zoukankan      html  css  js  c++  java
  • 化零为整WCF(16) 消息队列(MSMQ MicroSoft Message Queue)

    [索引页]
    [源码下载]


    化零为整WCF(16) - 消息队列(MSMQ - MicroSoft Message Queue)


    作者:webabcd


    介绍
    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
    [源码下载]
  • 相关阅读:
    [POI2014]FarmCraft
    [POI2014]Solar Panels
    Luogu P2824 [HEOI2016/TJOI2016]排序
    CF903G Yet Another Maxflow Problem
    CF901C Bipartite Segments
    CF749E Inversions After Shuffle
    ARC068C Snuke Line
    BZOJ3747 [POI2015]Kinoman
    SA-IS
    简单字符串
  • 原文地址:https://www.cnblogs.com/webabcd/p/1240768.html
Copyright © 2011-2022 走看看