MSMQ 為使用隊列創建分布式應用程序提供支持。WCF支持將MSMQ隊列作為netMsmqBinding綁定的底層傳輸協議的通信。 netMsmqBinding綁定允許客戶端直接把消息提交到一個隊列中同時服務端從隊列中讀取消息。客戶端和服務端之間沒有直接通信過程;因此,通信本 質是斷開的。也意外著所有的通信必須是單向的。因此,所有的操作必須要在操作契約上設置IsOneWay=true屬性。
提示 動態創建隊列
使用netMsmqBinding時動態創建MSMQ隊列是很普通的。當創建一個離線客戶端應用而且隊列在一個用戶的桌面時使用netMsmqBinding綁定更加平常。這可以通過創建System.MessageQueue類的靜態方法來實現。
下面的代碼顯示了netMsmqBinding綁定的地址格式:
??net.msmq:{hostname}/[private/|[public/]]{query name}
??MSMQ默認端口是1801而且沒有配置解決方案。注意地址格式中的public和private.你可以顯式的確定是否隊列名字指向一個私有的或者公有的隊列。默認情況下,隊列名字假設指向一個公共隊列。
表4.11 netMsmqBinding 綁定屬性

?
??我們在列表4.2到4.4使用的StockQuoteService樣例程序需要被修改以便于與netMsmqBinding綁定一起工作。 netMsmqBinding綁定僅支持單向操作(查看表4.2).我們之前的操作契約使用一個請求回復消息交換模式(查看列表4.4).我們將修改 StockQuoteService例子來顯示基于netMsmqBinding綁定的雙向通信而不是顯示一個不同的例子。
??我們需要使用兩個單向操作契約來維護服務端和客戶端的雙向通信。這意味著我們需要重新定義我們的契約以便于使用netMsmqBinding綁 定。列表4.24顯示了寫來與netMsmqBinding綁定一起使用的stock quote 契約。首先,注意我們把請求和回復契約轉換成兩個獨立的服務契約:IStockQuoteRequest和IStockQuoteResponse.每個 契約上的操作都是單向的。IStockQuoteRequest契約將被客戶端用來向服務端發送消息。IStockQuoteResponse契約將被服 務端用來發送一條消息給客戶端。這意味著客戶端和服務端都將寄宿服務來接收消息。
列表 4.24?IStockQuoteRequest,IStockQuoteResponse和StockQuoteRequestService
02 | using System.Collections.Generic; |
05 | using System.ServiceModel; |
06 | using System.Transactions; |
11 | ???? public interface IStockQuoteRequest |
13 | ???????? [OperationContract(IsOneWay= true )] |
14 | ???????? void SendQuoteRequest( string symbol); |
18 | ???? public interface IStockQuoteResponse |
20 | ???????? [OperationContract(IsOneWay = true )] |
21 | ???????? void SendQuoteResponse( string symbol, double price); |
24 | ???? public class StockQuoteRequestService : IStockQuoteRequest |
26 | ???????? public void SendQuoteRequest( string symbol) |
28 | ???????????? double value; |
29 | ???????????? if (symbol == "MSFT" ) |
30 | ???????????????? value = 31.15; |
31 | ???????????? else if (symbol == "YHOO" ) |
32 | ???????????????? value = 28.10; |
33 | ???????????? else if (symbol == "GOOG" ) |
34 | ???????????????? value = 450.75; |
36 | ???????????????? value = double .NaN; |
38 | ???????????? //Send response back to client over separate queue |
39 | ???????????? NetMsmqBinding msmqResponseBinding = new NetMsmqBinding(); |
40 | ???????????? using (ChannelFactory<IStockQuoteResponse> cf = new ChannelFactory<IStockQuoteResponse>( "NetMsmqResponseClient" )) |
42 | ???????????????? IStockQuoteResponse client = cf.CreateChannel(); |
43 | ???????????????? using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required)) |
45 | ???????????????????? client.SendQuoteResponse(symbol, value); |
46 | ???????????????????? scope.Complete(); |
48 | ???????????????? cf.Close(); |
?? netMsmqBinding下一個要考慮的就是使用ServiceHost類。先前的例子可以在不同的綁定上重用相同的ServiceHost代碼。這 因為服務契約可以保持一樣。而不是因為使用了netMsmqBinding。更新的用來寄宿StockServiceRequestService服務的 ServiceHost代碼在列表4.25中顯示。我們已經更新代碼來動態創建一個在基于配置文件中queueName的MSMQ隊列。這有助于通過簡單 配置允許程序部署而不需要額外的MSMQ配置。
列表 4.25 StockQuoteRequestService ServiceHost 服務
02 | using System.Collections.Generic; |
05 | using System.ServiceModel; |
06 | using System.Configuration; |
07 | using System.Messaging; |
13 | ???????? static void Main( string [] args) |
15 | ???????????? MyServiceHost.StartService(); |
16 | ???????????? Console.WriteLine( "Service is Started, press Enter to terminate." ); |
17 | ???????????? Console.ReadLine(); |
18 | ???????????? MyServiceHost.StopService(); |
22 | ???? internal class MyServiceHost |
24 | ???????? internal static string queryName = string .Empty; |
25 | ???????? internal static ServiceHost myServiceHost = null ; |
27 | ???????? internal static void StartService() |
29 | ???????????? queryName = ConfigurationManager.AppSettings[ "queueName" ]; |
30 | ???????????? if (!MessageQueue.Exists(queryName)) |
31 | ???????????????? MessageQueue.Create(queryName, true ); |
32 | ???????????? myServiceHost = new ServiceHost( typeof (EssentialWCF.StockQuoteRequestService)); |
33 | ???????????? myServiceHost.Open(); |
35 | ???????? internal static void StopService() |
37 | ???????????? if (myServiceHost.State != CommunicationState.Closed) |
38 | ???????????????? myServiceHost.Close(); |
?? 列表4.26的配置信息使用netMsmqBinding綁定暴露StockQuoteRequestService服務。它也為IStockQuoteResponse契約配置一個客戶端終結點以便于回復可以發送給客戶端。
列表 4.26 netMsmqBinding 宿主 配置
01 | <? xml version = "1.0" encoding = "utf-8" ?> |
03 | ???? < system.serviceModel > |
05 | ???????????? < endpoint address = "net.msmq://localhost/private/stockquoteresponse" |
06 | ???????????????? binding = "netMsmqBinding" bindingConfiguration = "NoMsmqSecurity" |
07 | ???????????????? contract = "EssentialWCF.IStockQuoteResponse" name = "NetMsmqResponseClient" /> |
10 | ???????????? < netMsmqBinding > |
11 | ???????????????? < binding name = "NoMsmqSecurity" > |
12 | ???????????????????? < security mode = "None" /> |
13 | ???????????????? </ binding > |
14 | ???????????? </ netMsmqBinding > |
17 | ???????????? < service name = "EssentialWCF.StockQuoteRequestService" > |
18 | ???????????????? < endpoint address = "net.msmq://localhost/private/stockquoterequest" |
19 | ???????????????????? binding = "netMsmqBinding" bindingConfiguration = "NoMsmqSecurity" |
20 | ???????????????????? name = "" contract = "EssentialWCF.IStockQuoteRequest" /> |
23 | ???? </ system.serviceModel > |
25 | ???? < add key = "queueName" value = ".\private$\stockquoterequest" /> |
??客戶端應用程序必須使用netMsmqBinding寄宿一個服務來接受回復且配置一個終結點來發送請求給服務端。列表4.27 顯示了客戶端用來寄宿一個實現了IStockQuoteResponse契約的ServiceHost類。我們添加代碼來動態創建一個客戶端監聽的隊列。 再次,這有助于通過簡單配置允許程序部署而不需要額外的MSMQ配置。
列表 4.27 StockQuoteResponseService ServiceHost 客戶端
02 | using System.Collections.Generic; |
05 | using System.ServiceModel; |
06 | using System.Configuration; |
07 | using System.Messaging; |
11 | ???? internal class MyServiceHost |
13 | ???????? internal static ServiceHost myServiceHost = null ; |
15 | ???????? internal static void StartService() |
17 | ???????????? string queryName = ConfigurationManager.AppSettings[ "queueName" ]; |
18 | ???????????? if (!MessageQueue.Exists(queryName)) |
19 | ???????????????? MessageQueue.Create(queryName, true ); |
20 | ???????????? myServiceHost = new ServiceHost( typeof (EssentialWCF.Program)); |
21 | ???????????? myServiceHost.Open(); |
23 | ???????? internal static void StopService() |
25 | ???????????? if (myServiceHost.State != CommunicationState.Closed) |
26 | ???????????????? myServiceHost.Close(); |
?? 列表4.28 顯示了IStockQuoteResponse接口的客戶端實現。客戶端實現了接口,接下來被服務端當作發送回復的回調端。這不是使用了WCF中的雙向能力。相反的,回調使用一個單獨的單向綁定實現。
02 | using System.Collections.Generic; |
05 | using System.Threading; |
06 | using System.ServiceModel; |
07 | using System.Transactions; |
11 | ???? public class Program : IStockQuoteResponse |
13 | ???????? private static AutoResetEvent waitForResponse; |
14 | ???????? static void Main( string [] args) |
16 | ???????????? //Start response service host |
17 | ???????????? MyServiceHost.StartService(); |
20 | ???????????????? waitForResponse = new AutoResetEvent( false ); |
21 | ???????????????? //Send request to the server |
22 | ???????????????? using (ChannelFactory<IStockQuoteRequest> cf = new ChannelFactory<IStockQuoteRequest>( "NetMsmqRequestClient" )) |
24 | ???????????????????? IStockQuoteRequest client = cf.CreateChannel(); |
25 | ???????????????????? using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required)) |
27 | ???????????????????????? client.SendQuoteRequest( "MSFT" ); |
28 | ???????????????????????? scope.Complete(); |
30 | ???????????????????? cf.Close(); |
32 | ???????????????? waitForResponse.WaitOne(); |
36 | ???????????????? MyServiceHost.StopService(); |
38 | ???????????? Console.ReadLine(); |
41 | ???????? public void SendQuoteResponse( string symbol, double price) |
43 | ???????????? Console.WriteLine( "{0}@${1}" , symbol, price); |
44 | ???????????? waitForResponse.Set(); |
?? 讓netMsmqBinding Stock Quote 樣例工作起來的最后一步是客戶端配置文件。列表4.29 顯示了客戶端配置,包含了寄宿IStockQuoteResponse服務實現的信息,調用IStockQuoteRequest服務的終結點配置。
列表 4.29 netMsmqBinding 客戶端配置
01 | <? xml version = "1.0" encoding = "utf-8" ?> |
03 | ???? < system.serviceModel > |
05 | ???????????? < netMsmqBinding > |
06 | ???????????????? < binding name = "NoMsmqSecurity" > |
07 | ???????????????????? < security mode = "None" /> |
08 | ???????????????? </ binding > |
09 | ???????????? </ netMsmqBinding > |
12 | ???????????? < endpoint address = "net.msmq://localhost/private/stockquoterequest" |
13 | ???????????????? binding = "netMsmqBinding" bindingConfiguration = "NoMsmqSecurity" |
14 | ???????????????? contract = "EssentialWCF.IStockQuoteRequest" name = "NetMsmqRequestClient" /> |
17 | ???????????? < service name = "EssentialWCF.StockQuoteRequestService" > |
18 | ???????????????? < endpoint address = "net.msmq://localhost/private/stockquoteresponse" |
19 | ???????????????????? binding = "netMsmqBinding" bindingConfiguration = "NoMsmqSecurity" |
20 | ???????????????????? contract = "EssentialWCF.IStockQuoteResponse" /> |
23 | ???? </ system.serviceModel > |
25 | ???? < add key = "queueName" value = ".\private$\stockquoteresponse" /> |
===========
轉載自
作者:DanielWise
出處:http://www.cnblogs.com/danielWise/
?