1 //----------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation. All rights reserved.
3 //----------------------------------------------------------------
5 namespace System.ServiceModel.Discovery
8 using System.ServiceModel;
9 using System.ServiceModel.Discovery.Version11;
10 using System.ServiceModel.Discovery.VersionApril2005;
11 using System.ServiceModel.Discovery.VersionCD1;
13 using System.Globalization;
14 using System.Runtime.Diagnostics;
15 using System.ServiceModel.Diagnostics;
17 [Fx.Tag.XamlVisible(false)]
18 public abstract class DiscoveryService :
19 IDiscoveryContractAdhocApril2005,
20 IDiscoveryContractManagedApril2005,
21 IDiscoveryContractAdhoc11,
22 IDiscoveryContractManaged11,
23 IDiscoveryContractAdhocCD1,
24 IDiscoveryContractManagedCD1,
25 IDiscoveryServiceImplementation
27 DiscoveryMessageSequenceGenerator messageSequenceGenerator;
28 DuplicateDetector<UniqueId> duplicateDetector;
30 protected DiscoveryService()
31 : this(new DiscoveryMessageSequenceGenerator())
35 protected DiscoveryService(DiscoveryMessageSequenceGenerator discoveryMessageSequenceGenerator)
36 : this(discoveryMessageSequenceGenerator, DiscoveryDefaults.DuplicateMessageHistoryLength)
40 protected DiscoveryService(
41 DiscoveryMessageSequenceGenerator discoveryMessageSequenceGenerator,
42 int duplicateMessageHistoryLength)
44 if (discoveryMessageSequenceGenerator == null)
46 throw FxTrace.Exception.ArgumentNull("messageSequenceGenerator");
48 if (duplicateMessageHistoryLength < 0)
50 throw FxTrace.Exception.ArgumentOutOfRange(
51 "duplicateMessageHistoryLength",
52 duplicateMessageHistoryLength,
53 SR.DiscoveryNegativeDuplicateMessageHistoryLength);
55 if (duplicateMessageHistoryLength > 0)
57 this.duplicateDetector = new DuplicateDetector<UniqueId>(duplicateMessageHistoryLength);
59 this.messageSequenceGenerator = discoveryMessageSequenceGenerator;
62 internal DiscoveryMessageSequenceGenerator MessageSequenceGenerator
66 return this.messageSequenceGenerator;
70 void IDiscoveryContractApril2005.ProbeOperation(ProbeMessageApril2005 request)
72 Fx.Assert("The sync method IDiscoveryContractApril2005.ProbeOperation must not get invoked. It is marked with PreferAsyncInvocation flag.");
75 IAsyncResult IDiscoveryContractApril2005.BeginProbeOperation(ProbeMessageApril2005 request, AsyncCallback callback, object state)
77 return new ProbeDuplexApril2005AsyncResult(request, this, null, callback, state);
80 void IDiscoveryContractApril2005.EndProbeOperation(IAsyncResult result)
82 ProbeDuplexApril2005AsyncResult.End(result);
85 void IDiscoveryContractApril2005.ResolveOperation(ResolveMessageApril2005 request)
87 Fx.Assert("The sync method IDiscoveryContractApril2005.ResolveOperation must not get invoked. It is marked with PreferAsyncInvocation flag.");
90 IAsyncResult IDiscoveryContractApril2005.BeginResolveOperation(ResolveMessageApril2005 request, AsyncCallback callback, object state)
92 return new ResolveDuplexApril2005AsyncResult(request, this, null, callback, state);
95 void IDiscoveryContractApril2005.EndResolveOperation(IAsyncResult result)
97 ResolveDuplexApril2005AsyncResult.End(result);
100 void IDiscoveryContractAdhoc11.ProbeOperation(ProbeMessage11 request)
102 Fx.Assert("The sync method IDiscoveryContractAdhoc11.ProbeOperation must not get invoked. It is marked with PreferAsyncInvocation flag.");
105 IAsyncResult IDiscoveryContractAdhoc11.BeginProbeOperation(ProbeMessage11 request, AsyncCallback callback, object state)
107 return new ProbeDuplex11AsyncResult(request, this, null, callback, state);
110 void IDiscoveryContractAdhoc11.EndProbeOperation(IAsyncResult result)
112 ProbeDuplex11AsyncResult.End(result);
115 void IDiscoveryContractAdhoc11.ResolveOperation(ResolveMessage11 request)
117 Fx.Assert("The sync method IDiscoveryContractAdhoc11.ResolveOperation must not get invoked. It is marked with PreferAsyncInvocation flag.");
120 IAsyncResult IDiscoveryContractAdhoc11.BeginResolveOperation(ResolveMessage11 request, AsyncCallback callback, object state)
122 return new ResolveDuplex11AsyncResult(request, this, null, callback, state);
125 void IDiscoveryContractAdhoc11.EndResolveOperation(IAsyncResult result)
127 ResolveDuplex11AsyncResult.End(result);
130 ProbeMatchesMessage11 IDiscoveryContractManaged11.ProbeOperation(ProbeMessage11 request)
132 Fx.Assert("The sync method IDiscoveryContractManaged11.ProbeOperation must not get invoked. It is marked with PreferAsyncInvocation flag.");
136 IAsyncResult IDiscoveryContractManaged11.BeginProbeOperation(ProbeMessage11 request, AsyncCallback callback, object state)
138 return new ProbeRequestResponse11AsyncResult(request, this, callback, state);
141 ProbeMatchesMessage11 IDiscoveryContractManaged11.EndProbeOperation(IAsyncResult result)
143 return ProbeRequestResponse11AsyncResult.End(result);
146 ResolveMatchesMessage11 IDiscoveryContractManaged11.ResolveOperation(ResolveMessage11 request)
148 Fx.Assert("The sync method IDiscoveryContractManaged11.ResolveOperation must not get invoked. It is marked with PreferAsyncInvocation flag.");
153 IAsyncResult IDiscoveryContractManaged11.BeginResolveOperation(ResolveMessage11 request, AsyncCallback callback, object state)
155 return new ResolveRequestResponse11AsyncResult(request, this, callback, state);
158 ResolveMatchesMessage11 IDiscoveryContractManaged11.EndResolveOperation(IAsyncResult result)
160 return ResolveRequestResponse11AsyncResult.End(result);
163 void IDiscoveryContractAdhocCD1.ProbeOperation(ProbeMessageCD1 request)
165 Fx.Assert("The sync method IDiscoveryContractAdhocCD1.ProbeOperation must not get invoked. It is marked with PreferAsyncInvocation flag.");
168 IAsyncResult IDiscoveryContractAdhocCD1.BeginProbeOperation(ProbeMessageCD1 request, AsyncCallback callback, object state)
170 return new ProbeDuplexCD1AsyncResult(request, this, null, callback, state);
173 void IDiscoveryContractAdhocCD1.EndProbeOperation(IAsyncResult result)
175 ProbeDuplexCD1AsyncResult.End(result);
178 void IDiscoveryContractAdhocCD1.ResolveOperation(ResolveMessageCD1 request)
180 Fx.Assert("The sync method IDiscoveryContractAdhocCD1.ResolveOperation must not get invoked. It is marked with PreferAsyncInvocation flag.");
183 IAsyncResult IDiscoveryContractAdhocCD1.BeginResolveOperation(ResolveMessageCD1 request, AsyncCallback callback, object state)
185 return new ResolveDuplexCD1AsyncResult(request, this, null, callback, state);
188 void IDiscoveryContractAdhocCD1.EndResolveOperation(IAsyncResult result)
190 ResolveDuplexCD1AsyncResult.End(result);
193 ProbeMatchesMessageCD1 IDiscoveryContractManagedCD1.ProbeOperation(ProbeMessageCD1 request)
195 Fx.Assert("The sync method IDiscoveryContractManagedCD1.ProbeOperation must not get invoked. It is marked with PreferAsyncInvocation flag.");
199 IAsyncResult IDiscoveryContractManagedCD1.BeginProbeOperation(ProbeMessageCD1 request, AsyncCallback callback, object state)
201 return new ProbeRequestResponseCD1AsyncResult(request, this, callback, state);
204 ProbeMatchesMessageCD1 IDiscoveryContractManagedCD1.EndProbeOperation(IAsyncResult result)
206 return ProbeRequestResponseCD1AsyncResult.End(result);
209 ResolveMatchesMessageCD1 IDiscoveryContractManagedCD1.ResolveOperation(ResolveMessageCD1 request)
211 Fx.Assert("The sync method IDiscoveryContractManagedCD1.ResolveOperation must not get invoked. It is marked with PreferAsyncInvocation flag.");
215 IAsyncResult IDiscoveryContractManagedCD1.BeginResolveOperation(ResolveMessageCD1 request, AsyncCallback callback, object state)
217 return new ResolveRequestResponseCD1AsyncResult(request, this, callback, state);
220 ResolveMatchesMessageCD1 IDiscoveryContractManagedCD1.EndResolveOperation(IAsyncResult result)
222 return ResolveRequestResponseCD1AsyncResult.End(result);
225 bool IDiscoveryServiceImplementation.IsDuplicate(UniqueId messageId)
227 return (this.duplicateDetector != null) && (!this.duplicateDetector.AddIfNotDuplicate(messageId));
230 DiscoveryMessageSequence IDiscoveryServiceImplementation.GetNextMessageSequence()
232 return this.messageSequenceGenerator.Next();
235 IAsyncResult IDiscoveryServiceImplementation.BeginFind(FindRequestContext findRequestContext, AsyncCallback callback, object state)
237 return this.OnBeginFind(findRequestContext, callback, state);
240 void IDiscoveryServiceImplementation.EndFind(IAsyncResult result)
242 this.OnEndFind(result);
245 IAsyncResult IDiscoveryServiceImplementation.BeginResolve(ResolveCriteria resolveCriteria, AsyncCallback callback, object state)
247 return this.OnBeginResolve(resolveCriteria, callback, state);
250 EndpointDiscoveryMetadata IDiscoveryServiceImplementation.EndResolve(IAsyncResult result)
252 return this.OnEndResolve(result);
255 internal static bool EnsureMessageId()
257 if (OperationContext.Current.IncomingMessageHeaders.MessageId == null)
259 if (TD.DiscoveryMessageWithNullMessageIdIsEnabled())
261 TD.DiscoveryMessageWithNullMessageId(
264 CultureInfo.InvariantCulture,
266 ProtocolStrings.TracingStrings.Probe,
267 ProtocolStrings.TracingStrings.Resolve));
276 internal static bool EnsureReplyTo()
278 OperationContext context = OperationContext.Current;
279 if (context.IncomingMessageHeaders.ReplyTo == null)
281 if (TD.DiscoveryMessageWithNullReplyToIsEnabled())
283 EventTraceActivity eventTraceActivity = EventTraceActivityHelper.TryExtractActivity(context.IncomingMessage);
284 TD.DiscoveryMessageWithNullReplyTo(eventTraceActivity, context.IncomingMessageHeaders.MessageId.ToString());
293 protected abstract IAsyncResult OnBeginFind(FindRequestContext findRequestContext, AsyncCallback callback, object state);
294 protected abstract void OnEndFind(IAsyncResult result);
296 protected abstract IAsyncResult OnBeginResolve(ResolveCriteria resolveCriteria, AsyncCallback callback, object state);
297 protected abstract EndpointDiscoveryMetadata OnEndResolve(IAsyncResult result);