介紹
WCF(Windows Communication Foundation) - 消息隊列(MSMQ - MicroSoft Message Queue):
netMsmqBinding的binding屬性配置如下:
·ExactlyOnce - 確保消息只被投遞一次。只能應用於事務型隊列,默認值 ture
·Durable - 消息是否需要持久化。默認值 enabled,如果設置為disable,當MSMQ服務重啟後,先前保存在MSMQ中的消息將會丟失
·TimeToLive - 消息過期並且從原有的隊列移動到死信隊列的時間。默認值 1.00:00:00 (1天)
·ReceiveRetryCount - 配置隊列管理器在一定重試間隔中,嘗試重新投遞消息的次數,也就是將消息傳輸到重試隊列前嘗試發送該消息的最大次數(每隔RetryCycleDelay的時間重試ReceiveRetryCount次)。缺省值 5
·MaxRetryCycles - 配置隊列管理器重新投遞消息的重試間隔數(執行RetryCycleDelay的次數),也就是重試最大周期數。缺省值 2
·RetryCycleDelay - 表示兩次重試之間的間隔時間,也就是重試周期之間的延遲。缺省值 00:30:00
·ReceiveErrorHandling - 指定如何處理錯誤的消息。Fault、Drop、Reject或Move(具體說明查MSDN)
·DeadLetterQueue - 指定所使用的死信隊列的類型。None、System、或Custom(具體說明查MSDN)
·CustomDeadLetterQueue - 本地自定義死信隊列的URI
示例
1、服務
IMSMQ.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; namespace WCF.ServiceLib.Message { /**//// <summary> /// 演示MSMQ的接口 /// </summary> /// <remarks> /// DeliveryRequirements - 指定綁定必須提供給服務或客戶端實現的功能要求 /// QueuedDeliveryRequirements - 指定服務的綁定是否必須支持排隊協定 /// QueuedDeliveryRequirementsMode.Allowed - 允許排隊傳送 /// QueuedDeliveryRequirementsMode.Required - 要求排隊傳送 /// QueuedDeliveryRequirementsMode.NotAllowed - 不允許排隊傳送 /// </remarks> [ServiceContract] [DeliveryRequirements(QueuedDeliveryRequirements = QueuedDeliveryRequirementsMode.Required)] public interface IMSMQ { /**//// <summary> /// 將字符串寫入文本文件 /// </summary> /// <param name="str">需要寫入文本文件的字符串</param> /// <remarks> /// 如果要使用 MSMQ 的話,則必須配置IsOneWay = true /// </remarks> [OperationContract(IsOneWay = true)] void Write(string str); } }
MSMQ.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; namespace WCF.ServiceLib.Message { /**//// <summary> /// 演示MSMQ的類 /// </summary> public class MSMQ : IMSMQ { /**//// <summary> /// 將字符串寫入文本文件 /// </summary> /// <param name="str">需要寫入文本文件的字符串</param> public void Write(string str) { System.IO.StreamWriter sw = new System.IO.StreamWriter(@"C:\WCF_Log_MSMQ.txt", true); sw.Write(str); sw.WriteLine(); sw.Close(); } } }
2、宿主
MSMQ.cs
// 隊列名 // 只能使用.\private$\YourPrivateMSMQName來訪問本機的私有MSMQ隊列 string queueName = @".\private$\SampleMSMQ"; // 沒有queueName隊列,則創建queueName隊列 if (!System.Messaging.MessageQueue.Exists(queueName)) { // 第二個參數為是否創建事務性隊列 System.Messaging.MessageQueue.Create(queueName, true); } using (ServiceHost host = new ServiceHost(typeof(WCF.ServiceLib.Message.MSMQ))) { host.Open(); Console.WriteLine("服務已啟動(WCF.ServiceLib.Message.MSMQ)"); Console.WriteLine("按<ENTER>停止服務"); Console.ReadLine(); }
App.config
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <services> <!--name - 提供服務的類名--> <!--behaviorConfiguration - 指定相關的行為配置--> <service name="WCF.ServiceLib.Message.MSMQ" behaviorConfiguration="MessageBehavior"> <!--address - 服務地址--> <!--binding - 通信方式--> <!--contract - 服務契約--> <!--bindingConfiguration - 指定相關的綁定配置--> <endpoint address="" binding="netMsmqBinding" contract="WCF.ServiceLib.Message.IMSMQ" bindingConfiguration="MSMQBindingConfiguration" /> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> <host> <baseAddresses> <add baseAddress="http://localhost:12345/Message/MSMQ"/> <add baseAddress="net.msmq://localhost/private/SampleMSMQ"/> </baseAddresses> </host> </service> </services> <behaviors> <serviceBehaviors> <behavior name="MessageBehavior"> <!--httpGetEnabled - 指示是否發布服務元數據以便使用 HTTP/GET 請求進行檢索,如果發布 WSDL,則為 true,否則為 false,默認值為 false--> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="true"/> </behavior> </serviceBehaviors> </behaviors> <bindings> <netMsmqBinding> <binding name="MSMQBindingConfiguration"> <security> <!--msmqAuthenticationMode - 指示 MSMQ 傳輸必須采用什麼方式對消息進行身份驗證,默認值 WindowsDomain --> <!--MsmqAuthenticationMode.None - 不使用任何安全性--> <!--MsmqAuthenticationMode.WindowsDomain - 通過 Kerberos 進行身份驗證,客戶端和服務器必須連接到受信任域--> <!--MsmqAuthenticationMode.Certificate - 客戶端通過 X.509 證書進行身份驗證,客戶端證書必須顯示在服務器的證書存儲區中--> <!--msmqProtectionLevel - 保護級別,設置與 MsmqAuthenticationMode 相關聯的 ProtectionLevel,默認值 Sign --> <!--ProtectionLevel.None - 只做身份驗證--> <!--ProtectionLevel.Sign - 對數據做簽名,以確保所傳輸數據的完整性--> <!--ProtectionLevel.EncryptAndSign - 對數據做加密和簽名,以確保所傳輸數據的保密性和完整性--> <transport msmqAuthenticationMode="None" msmqProtectionLevel="None" /> <!--clientCredentialType - 客戶端用以進行身份驗證的憑據的類型,默認值 UserName --> <!--BasicHttpMessageCredentialType.UserName - 使用用戶名憑據對客戶端進行身份驗證--> <!--BasicHttpMessageCredentialType.Certificate - 使用證書對客戶端進行身份驗證--> <message clientCredentialType="UserName" /> </security> </binding> </netMsmqBinding> </bindings> </system.serviceModel> </configuration>
3、客戶端
MSMQ.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Forms; using System.ServiceModel; namespace Client2.Message { /**//// <summary> /// 演示Message.MSMQ的類 /// </summary> public class MSMQ { /**//// <summary> /// 用於測試 MSMQ 的客戶端 /// </summary> /// <param name="str">需要寫入文本文件的字符串</param> public void HelloMSMQ(string str) { using (var proxy = new MessageSvc.MSMQ.MSMQClient()) { proxy.Write(str); } } } }
App.config
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <client> <!--address - 服務地址--> <!--binding - 通信方式--> <!--contract - 服務契約--> <!--bindingConfiguration - 指定相關的綁定配置--> <endpoint address="net.msmq://localhost/private/SampleMSMQ" binding="netMsmqBinding" contract="MessageSvc.MSMQ.IMSMQ" bindingConfiguration="MSMQBindingConfiguration" /> </client> <bindings> <netMsmqBinding> <binding name="MSMQBindingConfiguration"> <security> <!--msmqAuthenticationMode - 指示 MSMQ 傳輸必須采用什麼方式對消息進行身份驗證,默認值 WindowsDomain --> <!--MsmqAuthenticationMode.None - 不使用任何安全性--> <!--MsmqAuthenticationMode.WindowsDomain - 通過 Kerberos 進行身份驗證,客戶端和服務器必須連接到受信任域--> <!--MsmqAuthenticationMode.Certificate - 客戶端通過 X.509 證書進行身份驗證,客戶端證書必須顯示在服務器的證書存儲區中--> <!--msmqProtectionLevel - 保護級別,設置與 MsmqAuthenticationMode 相關聯的 ProtectionLevel,默認值 Sign --> <!--ProtectionLevel.None - 只做身份驗證--> <!--ProtectionLevel.Sign - 對數據做簽名,以確保所傳輸數據的完整性--> <!--ProtectionLevel.EncryptAndSign - 對數據做加密和簽名,以確保所傳輸數據的保密性和完整性--> <transport msmqAuthenticationMode="None" msmqProtectionLevel="None" /> <!--clientCredentialType - 客戶端用以進行身份驗證的憑據的類型,默認值 UserName --> <!--BasicHttpMessageCredentialType.UserName - 使用用戶名憑據對客戶端進行身份驗證--> <!--BasicHttpMessageCredentialType.Certificate - 使用證書對客戶端進行身份驗證--> <message clientCredentialType="UserName" /> </security> </binding> </netMsmqBinding> </bindings> </system.serviceModel> </configuration>
運行結果:
客戶端調用時,如果沒有啟動服務端,那麼消息會進入到消息隊列中。等到服務端啟動後,會執行消息隊列中的所有消息。
OK