WCF 结合MSMQ,使服务更稳定

来源:互联网 发布:淘宝违规处理怎么处理 编辑:程序博客网 时间:2024/05/16 07:59

转载自:http://blog.csdn.net/hoken2020856/article/details/5622860

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

 

[c-sharp] view plain copy
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5.     
  6. using System.ServiceModel;  
  7.     
  8. namespace WCF.ServiceLib.Message  
  9. {  
  10.   /**//// <summary>  
  11.   /// 演示MSMQ的接口  
  12.   /// </summary>  
  13.   /// <remarks>  
  14.   /// DeliveryRequirements - 指定绑定必须提供给服务或客户端实现的功能要求  
  15.   /// QueuedDeliveryRequirements - 指定服务的绑定是否必须支持排队协定  
  16.   /// QueuedDeliveryRequirementsMode.Allowed - 允许排队传送  
  17.   /// QueuedDeliveryRequirementsMode.Required - 要求排队传送  
  18.   /// QueuedDeliveryRequirementsMode.NotAllowed - 不允许排队传送  
  19.   /// </remarks>  
  20.   [ServiceContract]  
  21.   [DeliveryRequirements(QueuedDeliveryRequirements = QueuedDeliveryRequirementsMode.Required)]  
  22.   public interface IMSMQ  
  23.   {  
  24.     /**//// <summary>  
  25.     /// 将字符串写入文本文件  
  26.     /// </summary>  
  27.     /// <param name="str">需要写入文本文件的字符串</param>  
  28.     /// <remarks>  
  29.     /// 如果要使用 MSMQ 的话,则必须配置IsOneWay = true  
  30.     /// </remarks>  
  31.     [OperationContract(IsOneWay = true)]  
  32.     void Write(string str);  
  33.   }  
  34. }  

 

MSMQ.cs

[c-sharp] view plain copy
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5.     
  6. using System.ServiceModel;  
  7.     
  8. namespace WCF.ServiceLib.Message  
  9. {  
  10.   /**//// <summary>  
  11.   /// 演示MSMQ的类  
  12.   /// </summary>  
  13.   public class MSMQ : IMSMQ  
  14.   {  
  15.     /**//// <summary>  
  16.     /// 将字符串写入文本文件  
  17.     /// </summary>  
  18.     /// <param name="str">需要写入文本文件的字符串</param>  
  19.     public void Write(string str)  
  20.     {  
  21.       System.IO.StreamWriter sw = new System.IO.StreamWriter(@"C:WCF_Log_MSMQ.txt"true);  
  22.       sw.Write(str);  
  23.       sw.WriteLine();  
  24.       sw.Close();  
  25.     }  
  26.   }  
  27. }  

2、宿主

 

  MSMQ.cs

[c-sharp] view plain copy
  1. // 队列名  
  2. // 只能使用.private$YourPrivateMSMQName来访问本机的私有MSMQ队列  
  3. string queueName = @".private$SampleMSMQ";  
  4.     
  5. // 没有queueName队列,则创建queueName队列  
  6. if (!System.Messaging.MessageQueue.Exists(queueName))  
  7. {  
  8.   // 第二个参数为是否创建事务性队列  
  9.   System.Messaging.MessageQueue.Create(queueName, true);  
  10. }  
  11.     
  12. using (ServiceHost host = new ServiceHost(typeof(WCF.ServiceLib.Message.MSMQ)))  
  13. {  
  14.   host.Open();  
  15.     
  16.   Console.WriteLine("服务已启动(WCF.ServiceLib.Message.MSMQ)");  
  17.   Console.WriteLine("按<ENTER>停止服务");  
  18.   Console.ReadLine();  
  19.     
  20. }  

App.config

[xhtml] view plain copy
  1. <?xml version="1.0" encoding="utf-8" ?>  
  2. <configuration>  
  3.   <system.serviceModel>  
  4.     <services>  
  5.       <!--name - 提供服务的类名-->  
  6.       <!--behaviorConfiguration - 指定相关的行为配置-->  
  7.       <service name="WCF.ServiceLib.Message.MSMQ" behaviorConfiguration="MessageBehavior">  
  8.         <!--address - 服务地址-->  
  9.         <!--binding - 通信方式-->  
  10.         <!--contract - 服务契约-->  
  11.         <!--bindingConfiguration - 指定相关的绑定配置-->  
  12.         <endpoint address="" binding="netMsmqBinding" contract="WCF.ServiceLib.Message.IMSMQ" bindingConfiguration="MSMQBindingConfiguration" />  
  13.         <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />  
  14.         <host>  
  15.           <baseAddresses>  
  16.             <add baseAddress="http://localhost:12345/Message/MSMQ"/>  
  17.             <add baseAddress="net.msmq://localhost/private/SampleMSMQ"/>  
  18.           </baseAddresses>  
  19.         </host>  
  20.       </service>  
  21.     </services>  
  22.     <behaviors>  
  23.       <serviceBehaviors>  
  24.         <behavior name="MessageBehavior">  
  25.           <!--httpGetEnabled - 指示是否发布服务元数据以便使用 HTTP/GET 请求进行检索,如果发布 WSDL,则为 true,否则为 false,默认值为 false-->  
  26.           <serviceMetadata httpGetEnabled="true" />  
  27.           <serviceDebug includeExceptionDetailInFaults="true"/>  
  28.         </behavior>  
  29.       </serviceBehaviors>  
  30.     </behaviors>  
  31.     <bindings>  
  32.       <netMsmqBinding>  
  33.         <binding name="MSMQBindingConfiguration">  
  34.           <security>  
  35.             <!--msmqAuthenticationMode - 指示 MSMQ 传输必须采用什么方式对消息进行身份验证,默认值 WindowsDomain -->  
  36.             <!--MsmqAuthenticationMode.None - 不使用任何安全性-->  
  37.             <!--MsmqAuthenticationMode.WindowsDomain - 通过 Kerberos 进行身份验证,客户端和服务器必须连接到受信任域-->  
  38.             <!--MsmqAuthenticationMode.Certificate - 客户端通过 X.509 证书进行身份验证,客户端证书必须显示在服务器的证书存储区中-->  
  39.     
  40.             <!--msmqProtectionLevel - 保护级别,设置与 MsmqAuthenticationMode 相关联的 ProtectionLevel,默认值 Sign -->  
  41.             <!--ProtectionLevel.None - 只做身份验证-->  
  42.             <!--ProtectionLevel.Sign - 对数据做签名,以确保所传输数据的完整性-->  
  43.             <!--ProtectionLevel.EncryptAndSign - 对数据做加密和签名,以确保所传输数据的保密性和完整性-->  
  44.             <transport msmqAuthenticationMode="None" msmqProtectionLevel="None" />  
  45.     
  46.             <!--clientCredentialType - 客户端用以进行身份验证的凭据的类型,默认值 UserName -->  
  47.             <!--BasicHttpMessageCredentialType.UserName - 使用用户名凭据对客户端进行身份验证-->  
  48.             <!--BasicHttpMessageCredentialType.Certificate - 使用证书对客户端进行身份验证-->  
  49.             <message clientCredentialType="UserName" />  
  50.           </security>  
  51.         </binding>  
  52.       </netMsmqBinding>  
  53.     </bindings>  
  54.   </system.serviceModel>  
  55. </configuration>  

3、客户端

  MSMQ.cs

[c-sharp] view plain copy
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5.     
  6. using System.Windows.Forms;  
  7. using System.ServiceModel;  
  8.     
  9. namespace Client2.Message  
  10. {  
  11.   /**//// <summary>  
  12.   /// 演示Message.MSMQ的类  
  13.   /// </summary>  
  14.   public class MSMQ  
  15.   {  
  16.     /**//// <summary>  
  17.     /// 用于测试 MSMQ 的客户端  
  18.     /// </summary>  
  19.     /// <param name="str">需要写入文本文件的字符串</param>  
  20.     public void HelloMSMQ(string str)  
  21.     {  
  22.       using (var proxy = new MessageSvc.MSMQ.MSMQClient())  
  23.       {  
  24.         proxy.Write(str);  
  25.       }  
  26.     }     
  27.   }  
  28. }  

App.config

[xhtml] view plain copy
  1. <?xml version="1.0" encoding="utf-8" ?>  
  2. <configuration>  
  3.   <system.serviceModel>  
  4.     <client>  
  5.       <!--address - 服务地址-->  
  6.       <!--binding - 通信方式-->  
  7.       <!--contract - 服务契约-->  
  8.       <!--bindingConfiguration - 指定相关的绑定配置-->  
  9.       <endpoint address="net.msmq://localhost/private/SampleMSMQ" binding="netMsmqBinding"  
  10.         contract="MessageSvc.MSMQ.IMSMQ" bindingConfiguration="MSMQBindingConfiguration" />  
  11.     </client>  
  12.     <bindings>  
  13.       <netMsmqBinding>  
  14.         <binding name="MSMQBindingConfiguration">  
  15.           <security>  
  16.             <!--msmqAuthenticationMode - 指示 MSMQ 传输必须采用什么方式对消息进行身份验证,默认值 WindowsDomain -->  
  17.             <!--MsmqAuthenticationMode.None - 不使用任何安全性-->  
  18.             <!--MsmqAuthenticationMode.WindowsDomain - 通过 Kerberos 进行身份验证,客户端和服务器必须连接到受信任域-->  
  19.             <!--MsmqAuthenticationMode.Certificate - 客户端通过 X.509 证书进行身份验证,客户端证书必须显示在服务器的证书存储区中-->  
  20.     
  21.             <!--msmqProtectionLevel - 保护级别,设置与 MsmqAuthenticationMode 相关联的 ProtectionLevel,默认值 Sign -->  
  22.             <!--ProtectionLevel.None - 只做身份验证-->  
  23.             <!--ProtectionLevel.Sign - 对数据做签名,以确保所传输数据的完整性-->  
  24.             <!--ProtectionLevel.EncryptAndSign - 对数据做加密和签名,以确保所传输数据的保密性和完整性-->  
  25.             <transport msmqAuthenticationMode="None" msmqProtectionLevel="None" />  
  26.     
  27.             <!--clientCredentialType - 客户端用以进行身份验证的凭据的类型,默认值 UserName -->  
  28.             <!--BasicHttpMessageCredentialType.UserName - 使用用户名凭据对客户端进行身份验证-->  
  29.             <!--BasicHttpMessageCredentialType.Certificate - 使用证书对客户端进行身份验证-->  
  30.             <message clientCredentialType="UserName" />  
  31.           </security>  
  32.         </binding>  
  33.       </netMsmqBinding>  
  34.     </bindings>  
  35.   </system.serviceModel>  
  36. </configuration>  

运行结果:

  客户端调用时,如果没有启动服务端,那么消息会进入到消息队列中。等到服务端启动后,会执行消息队列中的所有消息。



MSMQ 防火墙 端口 配置 



The table below describes the ports used by Message Queuing:

PortPurposeApplicable VersionTCP 135Dynamic RPC port typically assigned by RPC for handshaking with an independent client or with an RPC server for the Message Queuing server to determine the fixed ports.MSMQ 5.0
MSMQ 4.0
MSMQ 3.0
MSMQ 2.0
MSMQ 1.0TCP 389Reserved port used by independent clients and Message Queuing servers to make MQIS requests directly to Active Directory using LDAP.MSMQ 5.0
MSMQ 4.0
MSMQ 3.0TCP 1801Message Queuing (including HTTP messaging) message traffic and internal session management traffic between Queue Managers.MSMQ 5.0
MSMQ 4.0
MSMQ 3.0
MSMQ 2.0
MSMQ 1.0UDP 1801Reserved port used by the Message Queuing independent client to multicast a server discovery broadcast.MSMQ 5.0
MSMQ 4.0
MSMQ 3.0
MSMQ 2.0
MSMQ 1.0TCP 2101*Message Queuing listens on this port on the Domain Controller for RPC-based MQIS and Active Directory lookups.MSMQ 5.0
MSMQ 4.0
MSMQ 3.0
MSMQ 2.0
MSMQ 1.0TCP 2103*

TCP 2105*On these two ports, Message Queuing independent clients and servers listen for RPC-based remote reads of their public queues and private queues.

The dependent client also uses these two ports to communicate with its server for send and for receive. MSMQ 5.0
MSMQ 4.0
MSMQ 3.0
MSMQ 2.0
MSMQ 1.0UDP 3527Reserved port used for the internal "ping" mechanism for Message Queuing.

Note On Message Queuing 4.0 and later, UDP port 3527 is no longer used by default. For more information on this change, visit the following links: 

Security Enhancements that Affect the Default Behavior of Message Queuing

MSMQ’s internal ping mechanism over port 3527MSMQ 3.0
MSMQ 2.0
MSMQ 1.0

* These port numbers may be incremented by 11 if the initial choice of RPC port is being used when Message Queuing initializes. A connecting QM queries port 135 to discover the 2xxx ports. 


The table below lists the MSMQ version by operating system: 

Operating SystemMessage Queuing VersionWindows Server 2008 R2
Windows 7MSMQ 5.0Windows Server 2008
Windows VistaMSMQ 4.0Windows Server 2003 R2
Windows Server 2003
Windows XP ProfessionalMSMQ 3.0Windows Server 2000
Windows Professional 2000MSMQ 2.0Windows NT 4.0MSMQ 1.0