WCF WS-Discovery應(yīng)用技巧分享
WCF是一款使用托管代碼建立的應(yīng)用程序統(tǒng)一框架。它在實(shí)際應(yīng)用中可以幫助開(kāi)發(fā)人員輕松的實(shí)現(xiàn)一個(gè)安全性高,可依賴性的開(kāi)發(fā)解決方案,輕松幫助用戶解決各種問(wèn)題。在這里我們會(huì)為大家詳細(xì)介紹一下WCF WS-Discovery的相關(guān)應(yīng)用技巧。#t#
在WS-*標(biāo)準(zhǔn)和規(guī)范中,WCF WS-Discovery是在2008年才加入了OASIS標(biāo)準(zhǔn)。WS-Discovery在標(biāo)準(zhǔn)被定義為Web Service Dynamic Discovery,其目的是為定位服務(wù)定義Discovery協(xié)議,主要應(yīng)用在為客戶端動(dòng)態(tài)搜索一個(gè)或多個(gè)目標(biāo)服務(wù)。OASIS為WS- Discovery提供了兩種操作模式:ad hoc和managed模式。
ad hoc模式根據(jù)類型在托管目標(biāo)服務(wù)的范圍內(nèi)查找目標(biāo)服務(wù)??蛻舳藭?huì)以多播的形式發(fā)送一個(gè)Probe(探測(cè))消息,如果服務(wù)匹配該信息,則以單播方式直接將響應(yīng)發(fā)送到客戶端。為了能夠根據(jù)名稱定位目標(biāo)服務(wù),客戶端會(huì)以相同的多播組發(fā)送一個(gè)Resolve(解析)消息,同樣的,匹配該消息的服務(wù)會(huì)直接以單播方式響應(yīng)客戶端。
如果Endpoint的數(shù)量擴(kuò)大了,且超出了ad hoc網(wǎng)絡(luò)的范圍之外,而且在網(wǎng)絡(luò)中可以使用Discovery Proxy(發(fā)現(xiàn)代理),則應(yīng)該采用Managed操作模式,以禁止多播的行為。在Managed模式下,目標(biāo)服務(wù)只需要以單播的形式發(fā)布一個(gè) announcement(通告)消息到Discovery Proxy,同時(shí),客戶端也會(huì)以單播形式發(fā)送Probe和Resolve消息到Discovery Proxy。這種模式并非直接采用單播方式,而是會(huì)實(shí)時(shí)對(duì)Discovery Proxy進(jìn)行監(jiān)聽(tīng),然后根據(jù)情況切換操作模式,從而降低多播給網(wǎng)絡(luò)傳輸帶來(lái)的影響。當(dāng)Discovery Proxy檢測(cè)到在ad hoc網(wǎng)絡(luò)中有多播方式發(fā)送的Probe和Resolve消息時(shí),它就會(huì)發(fā)布announcement通知自身??蛻舳艘坏┍O(jiān)聽(tīng)到Discovery Proxy上的announcement消息,就切換為Managed模式,直接以單播方式將probe和resolve消息發(fā)送給Discovery Proxy。如果Discovery Proxy沒(méi)有響應(yīng),客戶端又會(huì)切換為ad hoc操作模式。Managed模式的消息交換流程如下所示:
WCF 4.0實(shí)現(xiàn)了OASIS的WCF WS-Discovery標(biāo)準(zhǔn),相關(guān)的類定義在System.ServiceModel.Discovery命名空間中。這是一個(gè)單獨(dú)的程序集,所以需要添加對(duì)它的引用。
WCF Discoverty支持ad hoc和Managed模式,其中實(shí)現(xiàn)Managed模式需要實(shí)現(xiàn)Discovery Proxy。
在WCF 4.0中,新增了ServiceDiscoveryBehavior行為類,可以控制服務(wù)終結(jié)點(diǎn)的可發(fā)現(xiàn)能力。它能夠讓服務(wù)的所有終結(jié)點(diǎn)都能被發(fā)現(xiàn),相反,如果使用EndpointDiscoveryBehavior則只能使特定的終結(jié)點(diǎn)能夠被發(fā)現(xiàn)。除了需要添加發(fā)現(xiàn)行為,我們還需要添加發(fā)現(xiàn)終結(jié)點(diǎn),用來(lái)指定監(jiān)聽(tīng)以及發(fā)送discovery消息。WCF中標(biāo)準(zhǔn)的發(fā)現(xiàn)終結(jié)點(diǎn)類是UdpDiscoveryEndpoint,它基于UDP的多播綁定,是WCF 預(yù)先配置好的發(fā)現(xiàn)終結(jié)點(diǎn)。該終結(jié)點(diǎn)繼承自DiscoveryEndpoint類。在托管服務(wù)的時(shí)候,我們可以向ServiceHost中添加 ServiceDiscoveryBehavior和EndpointDiscoveryBehavior,如下所示:
- class CalculatorServiceHost {
- public static void Main() {
- Uri baseAddress = new Uri("http://localhost:8000/" +
Guid.NewGuid().ToString());- using (ServiceHost serviceHost = new ServiceHost(typeof
(CalculatorService), baseAddress)) {- serviceHost.AddServiceEndpoint(typeof(ICalculatorService),
new WSHttpBinding(), String.Empty);- // Make the service discoverable over UDP multicast
- serviceHost.Description.Behaviors.Add(new ServiceDiscoveryBehavior());
- serviceHost.AddServiceEndpoint(new UdpDiscoveryEndpoint());
- serviceHost.Open();
- Console.WriteLine("Calculator Service started at {0}", baseAddress);
- Console.WriteLine();
- Console.WriteLine("Press <ENTER> to terminate the service.");
- Console.WriteLine();
- Console.ReadLine();
- }
- }
- }
在對(duì)服務(wù)宿主進(jìn)行如下設(shè)置之后,客戶端就可以通過(guò)發(fā)送Probe和Resolve消息來(lái)發(fā)現(xiàn)服務(wù)。WCF將這些邏輯封裝在了DiscoveryClient 類中。它接受一個(gè)發(fā)現(xiàn)終結(jié)點(diǎn)對(duì)象,然后通過(guò)調(diào)用它的Find()方法(該方法接受一個(gè)FindCriteria實(shí)例,用來(lái)指定搜索標(biāo)準(zhǔn),在下面的代碼片斷中指定搜索標(biāo)準(zhǔn)為按照目標(biāo)服務(wù)的類型),返回FindResponse對(duì)象。該對(duì)象會(huì)包含一個(gè) Collection<EndpointDiscoveryMetadata>類型的屬性Endpoints:
- // Create DiscoveryClient
- DiscoveryClient discoveryClient = new DiscoveryClient
(new UdpDiscoveryEndpoint());- Console.WriteLine("Finding ICalculatorService endpoints...");
- Console.WriteLine();
- // Find ICalculatorService endpoints
- FindResponse findResponse = discoveryClient.Find
(new FindCriteria(typeof(ICalculatorService)));- Console.WriteLine("Found {0} ICalculatorService endpoint(s).",
findResponse.Endpoints.Count);- Console.WriteLine();
- if (findResponse.Endpoints.Count > 0) {
- return findResponse.Endpoints[0].Address;
- } else {
- return null;
- }
通過(guò)WCF WS-Discovery,我們不需要知道WCF服務(wù)的終結(jié)點(diǎn),只要存在目標(biāo)服務(wù),我們就能夠動(dòng)態(tài)查找到該服務(wù)。即使服務(wù)的Url發(fā)生改變,我們也不需要修改任何代碼和配置文件,客戶端仍然能夠正常發(fā)現(xiàn)目標(biāo)服務(wù)。