在某些特定的情况下,我们不能使用Ad hoc模式去发现服务,比如网络禁止多播消息,或者我们需要跨越多个服务边界查找服务的时候,就需要使用Managed Service Discovery 托管服务发现模式。WCF4.0新特性体验(12):服务发现WS-Discovery之Managed Service Discovery ,会给出详细的介绍和代码实现过程。
// 重写抽象类的DiscoveryProxy的abstract方法。
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
public
class DiscoveryProxyService : DiscoveryProxy
{
// 存储服务地址和元数据信息
Dictionary<EndpointAddress, EndpointDiscoveryMetadata> onlineServices;
public DiscoveryProxyService()
{
this.onlineServices =
new Dictionary<EndpointAddress, EndpointDiscoveryMetadata>();
}
// 接收到服务通告消息调用OnBeginOnlineAnnouncement
protected
override IAsyncResult OnBeginOnlineAnnouncement(DiscoveryMessageSequence messageSequence, EndpointDiscoveryMetadata endpointDiscoveryMetadata, AsyncCallback callback,
object state)
{
this.AddOnlineService(endpointDiscoveryMetadata);
return
new OnOnlineAnnouncementAsyncResult(callback, state);
}
// 接收到离线消息时候调用OnBeginOfflineAnnouncement
protected
override IAsyncResult OnBeginOfflineAnnouncement(DiscoveryMessageSequence messageSequence, EndpointDiscoveryMetadata endpointDiscoveryMetadata, AsyncCallback callback,
object state)
{
this.RemoveOnlineService(endpointDiscoveryMetadata);
return
new OnOfflineAnnouncementAsyncResult(callback, state);
}
// 接受到查找消息调用OnBeginFind
protected
override IAsyncResult OnBeginFind(FindRequestContext findRequestContext, AsyncCallback callback,
object state)
{
this.MatchFromOnlineService(findRequestContext);
return
new OnFindAsyncResult(callback, state);
}
//新增服务
void AddOnlineService(EndpointDiscoveryMetadata endpointDiscoveryMetadata)
{
lock (
this.onlineServices)
{
this.onlineServices[endpointDiscoveryMetadata.Address] = endpointDiscoveryMetadata;
}
PrintDiscoveryMetadata(endpointDiscoveryMetadata,
"Adding");
}
//移除服务
void RemoveOnlineService(EndpointDiscoveryMetadata endpointDiscoveryMetadata)
{
if (endpointDiscoveryMetadata !=
null)
{
lock (
this.onlineServices)
{
this.onlineServices.Remove(endpointDiscoveryMetadata.Address);
}
PrintDiscoveryMetadata(endpointDiscoveryMetadata,
"Removing");
}
}
//打印服务
void PrintDiscoveryMetadata(EndpointDiscoveryMetadata endpointDiscoveryMetadata,
string verb)
{
Console.WriteLine(
"********<" + verb +
" service of the following type");
foreach (XmlQualifiedName contractName
in endpointDiscoveryMetadata.ContractTypeNames)
{
Console.WriteLine(
"********" + contractName.ToString());
break;
}
Console.WriteLine(
"********Done");
}
}
public
static
void Main()
{
//添加客户端探测消息地址
Uri probeEndpointAddress =
new Uri(
"http://localhost:9001/Probe");
//添加服务端通告地址
Uri announcementEndpointAddress = new Uri("http://localhost:9002/Announcement");
// 托管DiscoveryProxy 服务
ServiceHost proxyServiceHost = new ServiceHost(new DiscoveryProxyService());
try
{
// 添加接收Probe和Resolve 消息的DiscoveryEndpoint终结点
DiscoveryEndpoint discoveryEndpoint = new DiscoveryEndpoint(new WSHttpBinding(), new EndpointAddress(probeEndpointAddress));
discoveryEndpoint.IsSystemEndpoint = false;
// 添加接收Hello合Bye消息的AnnouncementEndpoint终结点
AnnouncementEndpoint announcementEndpoint = new AnnouncementEndpoint(new WSHttpBinding(), new EndpointAddress(announcementEndpointAddress));
proxyServiceHost.AddServiceEndpoint(discoveryEndpoint);
proxyServiceHost.AddServiceEndpoint(announcementEndpoint);
//打开服务代理
proxyServiceHost.Open();
Console.ForegroundColor = ConsoleColor.Magenta;
Console.WriteLine("DiscoveryProxy Service started.");
Console.WriteLine("Press any key to exit");
Console.WriteLine();
Console.ReadLine();
proxyServiceHost.Close();
}
}
托管Proxy服务其实没什么特别之处,它也是一个WCF服务,只是干的工作已经确定。唯一的区别在于我们需要增加了一个客户端Probe探测地址,和一个WCF服务通告地址。
【2.5】运行结果:
【1】基本概念:托管服务发现模式Managed Service Discovery
实现托管服务发现模式Managed Service比ad hoc 模式复杂一些,因为我们要实现代理服务DiscoveryProxy,这个服务就是负责登记所有的服务终结点信息。例如,我们使用通告功能去更新DiscoveryProxy里服务的状态信息。有多种实现服务发现代理的方式,例如,我们可以建立数据库,来保存终结点信息,然后从数据库获取终结点信息。
我们在
WCF4.0新特性体验(10):服务发现WS-Discovery之简单的Ad hoc Service Discovery 也有过简单的介绍,当时做了个类比,托管服务发现模式很像现在的婚姻介绍所,我们可以快速定位自己需要的对象。
【1.1】Ad hoc模式:
在此模式下,客户端会通过UDP以多播的形式发送一个
Probe(探测)消息,如果服务匹配该探测信息,则以单播方式直接响应客户端一个
ProbeMatch(应答)消息。
为了减少客户端多播带来的性能问题,WCF允许服务加入、离开网络的时候发送一个多播消息,任何关注此服务的客户端都可以侦听这个消息。由于Ad hoc 基于UDP协议,所以只能适用于本地子网。
【1.2】Managed模式:
当我们需要跨多个网络发现服务的时候,就必须使用Managed发现模式。这里要借助的一个机制就是服务发现代理(Discovery Proxy )。服务代理管理服务的信息,并且可以跨越服务边界。服务代理的工作就是保存服务的终结点信息、处理客户端的查找请求。Managed发现模式的坏处就是实现复杂,不够灵活。好处就是可以显著降低ad hoc模式多播查找带来的网络负载问题,而且大大提高查找的效率。
【2】实现过程详解:
托管服务发现模式的应用主要包含一下几个主要的过程,首先要开发一个服务注册管理中心,也就是代理DiscoveryProxy,其次也托管这个服务。在就是定义WCF服务,并向DiscoveryProxy代理服务通告自己的服务信息。最后客户端可以向DiscoveryProxy代理服务查找自己的需要的服务。下面我们来依次看一下各个部分的实现过程。
【2.1】DiscoveryProxy:
首先看一下DiscoveryProxy的实现过程,WCF4.0定义了一个抽象基类DiscoveryProxy 。它包含了服务查找和管理的一些必要的方法。我们需要继承这个类型来实现我们自己的发现代理类。我们看一下具体自己的代理类的代码:
onlineServices属于存储服务信心的哈希表。作为DiscoveryProxyService 的属性。这里有几个比较重要的异步方法,当接收到服务注册和离线以及查找的时候执行的异步方法。OnBeginOnlineAnnouncement,OnBeginOfflineAnnouncement,OnBeginFind,此外还有一个打印终结点信息的自定义方法PrintDiscoveryMetadata,每次服务操作我们都会打印出消息,方便调试。省略了一些方法,大家有兴趣的话可以看一下文章最后给出的源代码。
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
【2.2】DiscoveryProxy宿主:
这个例子里,我们简单里创建了一个服务发现代理类,然后托管在Console程序里。我们指定了两个终结点:discovery(发现) 和announcement(通告)终结点。下面代码是具体的托管代码的实现:
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/d608a01840fefd0e145dfeac03617766.png)
//添加客户端探测消息地址,客户端将来查找消息的时候使用
Uri probeEndpointAddress = new Uri(" http://localhost:9001/Probe");
//添加服务端通告地址,WCF注册的时候使用。
Uri announcementEndpointAddress = new Uri(" http://localhost:9002/Announcement");
Uri probeEndpointAddress = new Uri(" http://localhost:9001/Probe");
//添加服务端通告地址,WCF注册的时候使用。
Uri announcementEndpointAddress = new Uri(" http://localhost:9002/Announcement");
【2.3】WCF服务代码:
现在我们启动服务发现代理的宿主程序。其它服务可以直接通道服务代理。当然客户端也可以通过单播直接与服务代理通信。WCF服务可以在启动的时候直接向代理服务DiscoveryProxy通告自己的地址信息。在服务行为里添加通告地址,我们可以通过配置文件实现:
<serviceBehaviors>
<behavior name="behaviorAnnouncement">
<serviceDiscovery>
<announcementEndpoints>
<endpoint address="http://localhost:9002/Announcement" binding="wsHttpBinding" kind="announcementEndpoint">
</endpoint>
</announcementEndpoints>
</serviceDiscovery>
<!-- enable service discovery behavior -->
</behavior>
</serviceBehaviors>
<behavior name="behaviorAnnouncement">
<serviceDiscovery>
<announcementEndpoints>
<endpoint address="http://localhost:9002/Announcement" binding="wsHttpBinding" kind="announcementEndpoint">
</endpoint>
</announcementEndpoints>
</serviceDiscovery>
<!-- enable service discovery behavior -->
</behavior>
</serviceBehaviors>
启动WCF服务宿主,WCF服务会向DiscoveryProxy通告自己的地址信息。我们观察一下DiscoveryProxy和WCF服务宿主窗口的信息,可以看到注册了三个终结点信息:
![](https://i-blog.csdnimg.cn/blog_migrate/a8e5e536b2c5f74574e7547dca5a844f.png)
【2.4】客户端:
现在我们可以来配置自己的客户端直接与代理服务DiscoveryProxy通信。这时我们可以给客户端指定特定的探测消息地址。客户端会像特定的服务代理发送探测Probe消息。
static void Main(string[] args)
{
// 创建DiscoveryClient,使用服务代理 discoveryProxy地址
// Create a DiscoveryEndpoint that points to the DiscoveryProxy
Uri probeEndpointAddress = new Uri("http://localhost:9001/Probe");
DiscoveryEndpoint discoveryEndpoint = new DiscoveryEndpoint(new WSHttpBinding(), new EndpointAddress(probeEndpointAddress));
DiscoveryClient discoveryClient = new DiscoveryClient(discoveryEndpoint);
// Find ICalculatorService endpoints in the specified scope
// 特定范围内查找IWCFService终结点
FindCriteria findCriteria = new FindCriteria();
//findCriteria.Scopes.Add(scope);
FindResponse findResponse = discoveryClient.Find(findCriteria);
//打印所有终结点信息
Console.WriteLine("All Endpoints:");
Console.ForegroundColor = ConsoleColor.Yellow;
foreach (EndpointDiscoveryMetadata edm in findResponse.Endpoints)
{
Console.WriteLine("[Address]: {0},[Contract]: {1}",
edm.Address, edm.ContractTypeNames[0].Name);
}
//定义Scope,限制搜索范围
Uri scope = new Uri("http://localhost:8000/");
findCriteria.Scopes.Add(scope);
findResponse = discoveryClient.Find(findCriteria);
//打印所有终结点信息
Console.WriteLine("Special Endpoints:");
Console.ForegroundColor = ConsoleColor.Red;
foreach (EndpointDiscoveryMetadata edm in findResponse.Endpoints)
{
Console.WriteLine("[Address]: {0},[Contract]: {1}",
edm.Address, edm.ContractTypeNames[0].Name);
}
Console.ForegroundColor = ConsoleColor.Yellow;
if (findResponse.Endpoints.Count > 0)
{
//创建服务代理客户端实例
EndpointAddress address = findResponse.Endpoints[0].Address;
IWCFService client = ChannelFactory<IWCFService>.CreateChannel(new WSHttpBinding(), address);
Console.WriteLine("Invoking WCFService at {0}", address);
// 调用SayHello服务操作.
string result = client.SayHello("Frank Xu Lei");
}
{
// 创建DiscoveryClient,使用服务代理 discoveryProxy地址
// Create a DiscoveryEndpoint that points to the DiscoveryProxy
Uri probeEndpointAddress = new Uri("http://localhost:9001/Probe");
DiscoveryEndpoint discoveryEndpoint = new DiscoveryEndpoint(new WSHttpBinding(), new EndpointAddress(probeEndpointAddress));
DiscoveryClient discoveryClient = new DiscoveryClient(discoveryEndpoint);
// Find ICalculatorService endpoints in the specified scope
// 特定范围内查找IWCFService终结点
FindCriteria findCriteria = new FindCriteria();
//findCriteria.Scopes.Add(scope);
FindResponse findResponse = discoveryClient.Find(findCriteria);
//打印所有终结点信息
Console.WriteLine("All Endpoints:");
Console.ForegroundColor = ConsoleColor.Yellow;
foreach (EndpointDiscoveryMetadata edm in findResponse.Endpoints)
{
Console.WriteLine("[Address]: {0},[Contract]: {1}",
edm.Address, edm.ContractTypeNames[0].Name);
}
//定义Scope,限制搜索范围
Uri scope = new Uri("http://localhost:8000/");
findCriteria.Scopes.Add(scope);
findResponse = discoveryClient.Find(findCriteria);
//打印所有终结点信息
Console.WriteLine("Special Endpoints:");
Console.ForegroundColor = ConsoleColor.Red;
foreach (EndpointDiscoveryMetadata edm in findResponse.Endpoints)
{
Console.WriteLine("[Address]: {0},[Contract]: {1}",
edm.Address, edm.ContractTypeNames[0].Name);
}
Console.ForegroundColor = ConsoleColor.Yellow;
if (findResponse.Endpoints.Count > 0)
{
//创建服务代理客户端实例
EndpointAddress address = findResponse.Endpoints[0].Address;
IWCFService client = ChannelFactory<IWCFService>.CreateChannel(new WSHttpBinding(), address);
Console.WriteLine("Invoking WCFService at {0}", address);
// 调用SayHello服务操作.
string result = client.SayHello("Frank Xu Lei");
}
启动客户端,向服务发现代理DiscoveryProxy,服务探测地址:Uri probeEndpointAddress = new Uri("
http://localhost:9001/Probe"); 发送服务探测消息,第一次没加任何限制,返回所有的服务信息,第二次我们使用了URI作为Scope,Uri scope = new Uri("
http://localhost:8000/"),限制查找范围,只返回一个匹配的服务地址,然后调用WCF服务。运行结果如下图:
![](https://i-blog.csdnimg.cn/blog_migrate/fcee4622e3f6067cfcd7d0ce6476050f.png)
【3】总结:
托管服务Managed Service发现模式的好处就是它可以跨越网络边界,因为其是基于传统的服务调用来注册和查找服务。这可以大大降低Ad-Hoc模式多播带来的网络资源消耗问题。此外,客户端可以通过服务发现代理DiscoveryProxy来查找特定的服务,而不需要每次服务都来监听特定的客户端多播消息。
参考文章:
6.OASIS WS-Discovery 1.1:
http://docs.oasis-open.org/ws-dd/discovery/1.1/os/wsdd-discovery-1.1-spec-os.html
本文转自 frankxulei 51CTO博客,原文链接:http://blog.51cto.com/frankxulei/320259
,如需转载请自行联系原作者