之前曾经写过一个关于MSMQ消息队列的文章:WCF分布式开发必备知识(1):MSMQ消息队列 ,当时的目的也是用它来作为学习WCF 消息队列MSMQ编程的基础文章。在那篇文章里,我们详细介绍了MSMQ消息队列的基本概念、安装、部署、开发、调试等相关问题。今天我们来学习WCF分布式开发步步为赢(13):WCF服务离线操作与消息队列MSMQ。在WCF框架下使用MSMQ消息队列服务编程。  这里我会给出一个使用WCF MSMQ实现离线请求的DEMO示例程序。

全文结构是:【1】MSMQ基本概念【2】WCF消息队列MSMQ的优势【3】WCF 消息队列MSMQ通信框架【4】安装配置注意事项【5】示例代码 【总结】

【1】MSMQ基本概念:

简要回顾一下MSMQ的基本概念,详细的你们可以参考WCF分布式开发必备知识(1):MSMQ消息队列

MSMQ全称MicroSoft Message Queue,微软消息队列,是在多个不同的应用之间实现相互通信的一种异步传输模式,相互通信的应用可以分布于同一台机器上,也可以分布于相连的网络空间中的任一位置。它的实现原理是:消息的发送者把自己想要发送的信息放入一个容器中(我们称之为Message),然后把它保存至一个系统公用空间的消息队列(Message Queue)中;本地或者是异地的消息接收程序再从该队列中取出发给它的消息进行处理。

【2】WCF消息队列MSMQ的优势:

消息队列MSMQ的优点:稳定、消息优先级、脱机能力以及安全性,有保障的消息传递和执行许多业务处理的可靠的防故障机制。 因此消息队列是实现SOA面向服务架构的重要组件之一。WCF框架提供了和MSMQ集成与扩展的能力。这一点也是WCF在特性中明确指出的。MSMQ支持离线消息模式,而且在WCF框架下,提供了基于http桥的internet网络队列服务的调用扩展。和MSMQ框架的结合和扩展,使得WCF服务具有的新的特点:

【2.1】Availabiliy:可用性。这个是MSMQ离线消息的一种体现。客户单和服务端不需要实时进行连接,然后进行消息的交互.WCF 客户端可以发送请求到离线服务端,服务上线以后在相应客户端请求。

【2.2】Disjoint:分解。可以讲工作分解为多个操作,一次放入队列。改善系统的可用性和吞吐量。

【2.3】Compensating:补偿。对于多业务事务,可以提供单独的事物提供其它事务失败的善后处理。

【2.4】Load Leveling:负载平衡。可以把过载的客户端请求放入队列,空闲的时候进行处理,平衡系统的吞吐量,改善性能。

【3】WCF 消息队列MSMQ通信框架:

WCF使用NetMsmqBinding来支持消息队列通信。当客户端调用服务时,客户端消息会被封装为MSMQ消息,发送懂到特定的消息队列。服务端宿主在运行转台下会,启动通道侦听器,来检测消息队列消息,如果发现对应的消息,会从队列里取出消息,使用分发器转发给对应的服务。具体的通信架构如图:

如果宿主离线,消息会被放入队列,等待下一次宿主联机时,在执行消息分发处理,给指定的WCF服务。

【4】安装配置注意事项:

MSMQ队列几种常见的类型就是:

1.公共队列:在整个消息队列网络中复制,并且有可能由网络连接的所有站点访问。 
2.专用队列:不在整个网络中发布。相反,它们仅在所驻留的本地计算机上可用。专用队列只能由知道队列的完整路径名或标签的应用程序访问。 
3.管理队列:包含确认在给定“消息队列”网络中发送的消息回执的消息。指定希望 MessageQueue 组件使用的管理队列(如果有的话)。 
4.响应队列:包含目标应用程序接收到消息时返回给发送应用程序的响应消息。指定希望 MessageQueue 组件使用的响应队列(如果有的话)。

这里有几个问题要注意,以前很多人也在配置MSMQ开发环境的时候遇到这个问题。Xp环境下作MSMQ配置开发有很多限制。这里算是做个总结供大家参考:

1.公共队列需要域控制器DC Domain Controller; 
2.私有队列与托管的机器同属本地,不需要DC,成为工作组安装; 
3.私有队列需要禁用安全模式:工作组安装与安全,安全设置需要客户端提供证书,MSMQ传输安全需要使用Windows安全,这里需要使用AD活动目录。

【5】示例代码 :

今天的示例DEMO程序代码,主要演示的是WCF如何配置和开发一个MSMQ服务程序,实现WCF离线操作,MSMQ事务的部分由于内容较多,这里暂时不涉及。我们只讨论WCF离线操作。

(1)WCF服务代码:

值得注意的WCF的操作要被定义为单向操作,因为本质上其符合单向操作的特征。异步,离线。无返回值。配置操作契约的时候要添加IsOneWay属性。代码如下:

 //1.服务契约
    [ServiceContract(Namespace = "http://www.cnblogs.com/frank_xl/")]
    public interface IWCFMSMQService
    {
        //操作契约,必须为单向操作
        [OperationContract(IsOneWay = true)]
        void SayHelloMSMQ(string name);     }
    //2.服务类,继承接口。实现服务契约定义的操作
    public class WCFMSMQService : IWCFMSMQService
    {
        public WCFMSMQService()
        {
            Console.WriteLine("WCF MSMQ Service instance was created at:{0}",  DateTime.Now);
        }
        //实现接口定义的方法
        public void SayHelloMSMQ(string name)
        {
            Console.WriteLine("Hello! {0},Calling WCF MSMQ Service Operation at:{1}", name,DateTime.Now);
            
        }
    }

(2)宿主:

我的开发环境为XP专业版,工作组模式。这里有个问题要注意,就是安全。MSMQ默认的安全模式是需要证书支持。我们必须在宿主配置文件里给配置为none,简化操作,因为证书需要MSMQ域管理器。MSMQ传输安全需要Windows安全,这个又需要AD活动目录支持,工作组模式下不支持,因此这里我们都设置为none。代码如下:

<services>
      <service behaviorConfiguration="WCFService.WCFServiceBehavior"
        name="WCFService.WCFMSMQService">
        <endpoint  
          address="net.msmq://localhost/Private/FrankWCFMSMQ" 
          binding="netMsmqBinding"         
          contract="WCFService.IWCFMSMQService" bindingConfiguration="msmq" >
        </endpoint>
       
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8001/"/>
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="WCFService.WCFServiceBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <netMsmqBinding>
        <binding name="msmq" durable="false" exactlyOnce="false">
          <security mode="None">
            <transport msmqProtectionLevel="None"/>
            <message clientCredentialType="None"/>
          </security>
        </binding>
      </netMsmqBinding>
    </bindings>

(3)客户端:

运行客户端,添加服务引用,这里客户端的配置文件要做修改,安全模式也修改和宿主对应,设置为none。客户端测试方案是每个2秒调用一次服务请求。我们这里在宿主端打印了时间。客户端发送消息完毕以后,宿主暂时不启动。等待一段时间。在启动宿主,观察宿主打印的消息。代码如下:

            //HTTP NetMsmqBinding_IWCFMSMQService
            WCFMSMQServiceClient wcfServiceProxy = new WCFMSMQServiceClient("NetMsmqBinding_IWCFMSMQService");
            //通过代理调用SayHello服务,这里及时服务调用服务失败,消息会发送到队列里进行缓存。
            Console.WriteLine("WCF First Call at:{0}",DateTime.Now);
            wcfServiceProxy.SayHelloMSMQ("Frank");
            Thread.Sleep(2000);//客户端休眠两秒,继续下一次调用
            Console.WriteLine("WCF Second Call at:{0}", DateTime.Now);
            wcfServiceProxy.SayHelloMSMQ("Frank Xu");
            Thread.Sleep(2000);//客户端休眠两秒,继续下一次调用
            Console.WriteLine("WCF Last Call at:{0}", DateTime.Now);
            wcfServiceProxy.SayHelloMSMQ("Frank Xu Lei");

(4)运行结果:

首先是客户端发送到的消息,我们可以再计算机-管理-服务-专用队列里查看到,如图:

以前的服务要求我们必须启动宿主,不然会出现连接错误。这里为了测试,停留约4分钟后,我们启动宿主。观察宿主打印的消息:

宿主在联机以后响应了客户端的调用操作。

【总结】

本节文章主要讲解的是WCF 如何使用MSMQ开发离线服务操作。这里除了回顾了MSMQ的基本概念,还介绍了WCF服务使用MSMQ的通信框架的优势和特点。最后给出了基于WCF 消息队列的离线服务调用实现的过程。

WCF 对MSMQ消息队列的支持和扩展,大大提高了WCF服务调用的伸缩性和灵活性。本文由于开发环境的关系,没有给出公共队列的开发实现过程。另外在WCF 消息队列开发过程中,大家要做注意。

(1)在服务宿主端启动宿主,要做队列存在的判断,以免出现读取错误。

(2)队列服务涉及到安全的问题,认证和消息加密,签名,需要证书的配置。条件限制这里就没有给出具体的实现过程。

(3)WCF队列服务的另外一个重要概念就是对离线事务的支持。这一特性会在后续文章里给出。

(4)运行环境:Xp pro,.net 3.0以上,vs2008,至少安装MSMQ队列的私有队列组件服务。

最后给出本文的参考代码:/Files/frank_xl/WCCFServiceMSMQFrankXuLei.rar

WCF分布式开发步步为赢(13):WCF服务离线操作与消息队列MSMQ的更多相关文章

  1. WCF分布式开发步步为赢(3)WCF服务元数据交换、配置及编程开发

    今天我们继续WCF分布式开发步步为赢(3)WCF服务元数据交换.配置及编程开发的学习.经过前面两节的学习,我们了解WCF分布式开发的相关的基本的概念和自定义宿主托管服务的完整的开发和配置过程.今天我们 ...

  2. WCF分布式开发步步为赢(7):WCF数据契约与序列化

    本节继续学习WCF分布式开发步步为赢(7):WCF数据契约与序列化.数据契约是WCF应用程序开发中一个重要的概念,毫无疑问实现客户端与服务端数据契约的传递中序列化是非常重要的步骤.那么序列化是什么?为 ...

  3. WCF分布式开发步步为赢(4):WCF服务可靠性传输配置与编程开发

    今天继续WCF分布式开发步步为赢系列的第4节:WCF服务可靠性传输配置与编程开发.这个章节,我们要介绍什么是WCF服务的可靠性传输,随便介绍网络协议的概念,Web Service为什么不支持可靠性传出 ...

  4. WCF分布式开发步步为赢(11):WCF流处理(Streaming)机制

    WSE3.0框架提供了数据优化传输机制,WSE3.0构建Web服务安全(4):MTOM消息传输优化和文件上传.下载 疑问里进行了介绍.WCF同样也提供了流操作来支持大数据对象的传输和处理优化机制,今天 ...

  5. WCF分布式开发步步为赢(12):WCF事务机制(Transaction)和分布式事务编程

    今天我们继续学习WCF分布式开发步步为赢系列的12节:WCF事务机制(Transaction)和分布式事务编程.众所周知,应用系统开发过程中,事务是一个重要的概念.它是保证数据与服务可靠性的重要机制. ...

  6. WCF分布式开发步步为赢(9):WCF服务实例激活类型编程与开发

    .Net Remoting的激活方式也有三种:SingleTon模式.SingleCall模式.客户端激活方式,WCF服务实例激活类型包括三种方式:单调服务(Call Service),会话服务(Se ...

  7. WCF分布式开发步步为赢(14):WCF安全编程--基本概念

    WCF安全机制是个非常复杂的问题,因为涉及的知识点较多,所以今天这个文章,会分析进行WCF安全开发应该了解的哪些知识点.如何查看资料.为了更好地理解WCF安全相关知识,我把WCF安全机制主要知识点整理 ...

  8. WCF分布式开发步步为赢(5)服务契约与操作重载

    继上一节WCF分布式开发步步为赢系列的(4):WCF服务可靠性传输配置与编程开发,本节我们继续学习WCF分布式开发步步为赢的第(5)节:服务契约与操作重载.这里我们首先讲解OOP面向对象的编程中方法重 ...

  9. WCF分布式开发步步为赢(6):WCF服务契约继承与分解设计

    上一节我们学习了WCF分布式开发步步为赢(5)服务契约与操作重载部分.今天我们来继续学习WCF服务契约继承和服务分解设计相关的知识点.WCF服务契约继承有何优势和缺点?实际项目里契约设计有什么原则和依 ...

随机推荐

  1. JDK8新垃圾回收机制--G1垃圾回收机制

    G1全称是Garbage First Garbage Collector,使用G1的目的是简化性能优化的复杂性.例如,G1的主要输入参数是初始化和最大Java堆大小.最大GC中断时间. G1 GC由Y ...

  2. STM32F4使用FPU+DSP库进行FFT运算的测试过程二

    原文地址:http://www.cnblogs.com/NickQ/p/8541156.html 测试环境:单片机:STM32F407ZGT6 IDE:Keil5.20.0.0 固件库版本:STM32 ...

  3. python循环,函数

    平常的网页会转换成ascll码,在转编译成十六进制a='http://www.mywebsit.com/?query=python&count=20'print(a)b=a.replace(' ...

  4. 001---Python简介

    编程语言: 机器语言 最底层,更容易被计算机识别,执行速度最快 复杂,开发效率低 汇编语言 比较底层,执行速度较快 同样复杂 高级语言 编译型语言:先编译,后执行.生成独立的可执行文件.是计算机可以理 ...

  5. 用ssh进行git clone出现 fatal: Could not read from remote repository.

    问题:在通过MobaXterm进行ssh连接的服务器上用ssh进行git clone出现 fatal: Could not read from remote repository. 解决方法:prox ...

  6. Android开发——告诉你Adapter应该写在Activity里面还是外面

    0. 前言 本文转载自AItsuki的博客. 首先说明一下为什么要写这么一篇博客:最近看了一些其他人的项目,发现很多项目的做法是建立一个专门存放Adapter类的Package包,也有的项目干脆直接都 ...

  7. PRO*C 函数事例 3 -- 游标使用

    1.Oracle中的游标    Oracle使用两种游标: 显式游标和隐式游标. 不管语句返回多少条记录, Oracle为每条使用的SQL语句隐式地定义一个游标. Oracle为每个DELETE , ...

  8. ThinkPHP5项目目录规划实践

    ThinkPHP5安装后(或者下载后的压缩文件解压后)可以看到下面的目录结构: tp5├─application     应用目录 ├─extend          扩展类库目录(可定义) ├─pu ...

  9. C++ 学习笔记之——输入和输出

    在 C++ 中,我们通过调用输入输出流库中的流对象 cin 和 cout 来实现输入和输出. #include <iostream> using namespace std; int ma ...

  10. python——pyinstaller生成exe基本使用和遇到的坑

    1.安装 pip install pyinstaller 2.常规操作 在cmd界面(之前安装python或者anaconda的时候正确添加环境变量的话,是可以在cmd界面直接执行pyinstalle ...