WCF分布式开发步步为赢(13):WCF服务离线操作与消息队列MSMQ
之前曾经写过一个关于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的更多相关文章
- WCF分布式开发步步为赢(3)WCF服务元数据交换、配置及编程开发
今天我们继续WCF分布式开发步步为赢(3)WCF服务元数据交换.配置及编程开发的学习.经过前面两节的学习,我们了解WCF分布式开发的相关的基本的概念和自定义宿主托管服务的完整的开发和配置过程.今天我们 ...
- WCF分布式开发步步为赢(7):WCF数据契约与序列化
本节继续学习WCF分布式开发步步为赢(7):WCF数据契约与序列化.数据契约是WCF应用程序开发中一个重要的概念,毫无疑问实现客户端与服务端数据契约的传递中序列化是非常重要的步骤.那么序列化是什么?为 ...
- WCF分布式开发步步为赢(4):WCF服务可靠性传输配置与编程开发
今天继续WCF分布式开发步步为赢系列的第4节:WCF服务可靠性传输配置与编程开发.这个章节,我们要介绍什么是WCF服务的可靠性传输,随便介绍网络协议的概念,Web Service为什么不支持可靠性传出 ...
- WCF分布式开发步步为赢(11):WCF流处理(Streaming)机制
WSE3.0框架提供了数据优化传输机制,WSE3.0构建Web服务安全(4):MTOM消息传输优化和文件上传.下载 疑问里进行了介绍.WCF同样也提供了流操作来支持大数据对象的传输和处理优化机制,今天 ...
- WCF分布式开发步步为赢(12):WCF事务机制(Transaction)和分布式事务编程
今天我们继续学习WCF分布式开发步步为赢系列的12节:WCF事务机制(Transaction)和分布式事务编程.众所周知,应用系统开发过程中,事务是一个重要的概念.它是保证数据与服务可靠性的重要机制. ...
- WCF分布式开发步步为赢(9):WCF服务实例激活类型编程与开发
.Net Remoting的激活方式也有三种:SingleTon模式.SingleCall模式.客户端激活方式,WCF服务实例激活类型包括三种方式:单调服务(Call Service),会话服务(Se ...
- WCF分布式开发步步为赢(14):WCF安全编程--基本概念
WCF安全机制是个非常复杂的问题,因为涉及的知识点较多,所以今天这个文章,会分析进行WCF安全开发应该了解的哪些知识点.如何查看资料.为了更好地理解WCF安全相关知识,我把WCF安全机制主要知识点整理 ...
- WCF分布式开发步步为赢(5)服务契约与操作重载
继上一节WCF分布式开发步步为赢系列的(4):WCF服务可靠性传输配置与编程开发,本节我们继续学习WCF分布式开发步步为赢的第(5)节:服务契约与操作重载.这里我们首先讲解OOP面向对象的编程中方法重 ...
- WCF分布式开发步步为赢(6):WCF服务契约继承与分解设计
上一节我们学习了WCF分布式开发步步为赢(5)服务契约与操作重载部分.今天我们来继续学习WCF服务契约继承和服务分解设计相关的知识点.WCF服务契约继承有何优势和缺点?实际项目里契约设计有什么原则和依 ...
随机推荐
- 安装java 和 eclipse
昨天安装eclipse出现个问题, 安装完了创建第一个项目目录的时候弹窗报错an ......什么什么, 百度一堆没有用,后来发现是jdk12不支持,换了jdk8就可以了, 然后eclipse安装py ...
- ATM购物车程序项目规范(更新到高级版)
ATM购物车程序(高级版) 之前的低级版本已经删除,现在的内容太多,没时间把内容上传,有时间我会把项目源码奉上! 我已经把整个项目源码传到群文件里了,需要的可以加主页qq群号.同时群内也有免费的学习资 ...
- 一笔画问题 南阳acm42(貌似没用到什么算法)
一笔画问题 时间限制:3000 ms | 内存限制:65535 KB 难度:4 描述 zyc从小就比较喜欢玩一些小游戏,其中就包括画一笔画,他想请你帮他写一个程序,判断一个图是否能够用一笔画下 ...
- DDL失败案例
问题描述 今天对线上某个业务的大表120G进行重建表操作时遇到报错,该表有个比较显著的特征是*写入量比较大,每天写入加更新的频率在数千万级别.大致的环境 1 版本:Percona 5.6.24 2 操 ...
- MySQL分区的限制(最多有多少个分区)
MySQL分区的限制 • 只能对数据表的整型列进行分区,或者数据列可以通过分区函数转化成整型列 • 最大分区数目不能超过1024 • 如果含有唯一索引或者主键,则分区列必须包含在所有的唯一 ...
- 4.HBASE数据迁移方案(之snapshot):
4.HBASE数据迁移方案: 4.1 Import/Export 4.2 distcp 4.3 CopyTable 4.4 snapshot 快照方式迁移(以USER_info:user_lo ...
- NB-IOT的键值对
1. 关于NB-IOT的软件开发,有一个功能,NB收到数据的时候可以唤醒处于低功耗下的MCU. 2. 2个键值对可以配置这个功能.使用键值对的方式. 3. 遇到的第一个问题,<config> ...
- jdk带的一些工具,强悍
这些工具有的已经接触到了,功能很强悍,但是使用也有点复杂(参数) 在代码中使用System.setProperty()或者在启动程序时使用-D选项设置代理服务器地址和端口 看看别人的研究: JDK自带 ...
- Android Google Maps 监听地图缩放
接上篇.http://www.cnblogs.com/maomishen/p/3556297.html 由于公司项目要求,需要对google map监听地图的缩放(zoom)来进行一些操作. 但是在网 ...
- pep8介绍
pep8介绍: PEP8是针对python代码格式而编订的风格指南,采用一致的编码风格可以令代码更加易懂易读! (1)空白: python中空白会影响代码的含义及其代码的清晰程度 使用space(空格 ...