使用消息队列

消息队列是本书WCF异步技术中的最后一个出场的。消息队列可以为消息传输提供持久性、可靠性和事务性。甚至,发送消息的客户端程序与接受消息的服务可以不必同时运行。但使用该灵活性需要付出一定的代价,那就是消息队列只能支持单向传输。因此如果使用该技术实现客户端程序和服务并且服务需要向客户端发送响应消息时,需要仔细的设计。另外,消息队列比其他传输协议更慢,这是因为它所支持的可靠性和可持续性;Windows操作系统需要把消息存储到磁盘。这意味着消息队列中的消息可以不受关机或者电源失败的影响;但这种稳健性在创建和传输消息时需要付出额外的I/O代价。
尽管MSMQ的编程模型非常简单,可能你曾经使用MSMQ构建过消息队列程序,但你仍然需要重视它。这是因为在WCF中你所使用的MSMQ技术与传统的C/S程序有根本的不同。但是,WCF有一个目标是:在发送和接受消息时保持一致性,而不管WCF底层使用了哪一个传输协议,因此使用消息队列的WCF与使用其他传输协议的WCF非常相似。但是,WCF使用的消息队列又和你过去曾经用的的消息队列技术有一些差别。
在本章最后一系列的练习中,你将看到使用消息队列作为传输协议实现单向异步操作是非常容易的。
练习:使用消息队列实现WCF服务
1. 使用Visual Studio,打开*\WCF\Step.by.Step\Solutions\Chapter12文件夹下的MSMQ解决方案
2. 在解决方案浏览器窗口,打开AdventureWorksAdminHost项目下的IService.cs文件
该文件中定义了一个IAdventureWorksAdmin的接口。该接口包含单个操作GenerateDailySalesReport。请注意该操作还通过OperationContract特性类的IsOneyWay属性指明了该操作为单向操作。这个设置很重要,因为通过消息队列实现的服务,其所有操作都必须是单向的。
3. 打开AdventureWorksAdminHost项目下的Service.cs文件
该文件包含了实现IAdventureWorksAdmin接口的AdventureWorksAdmin类。请注意GenerateDailySalesReport方法现在仅仅是等待10秒(模拟报表生成的过程)然后显示一个消息对话框以表示方法完成。
4. 在设计窗口下打开HostController.xaml文件。检查该文件,你会发现该文件是用于寄宿AdventureWokrsAdmin服务
5.使用WCF服务配置编辑器打开app.config文件
6. 在WCF配置编辑器的配置面板中,右键点击服务,然后选择创建新的服务
7. 在右边面板中,在名字属性处,输入AdventureWorksAdmin
8. 在配置面板中,右键点击AdventureWorksAdmin服务下的端点文件夹,然后选择创建新的服务端点
9. 在右边面板中,按照下表的内容设置该端点的属性
属性
名字 AdventureWorksAdminMsmqEndpoint
地址 Net.msmq://localhost/private/AdventureWorksAdmin
绑定 netMsmqBinding
服务合约 IAdventureWorksAdmin
消息队列URI由net.msmq和队列的名字组成。MSMQ通过与HTTP URL相似的方式识别队列,尽管与HTTP从学术意义上讲有一定程度的区别。URL的"private"部分指明其是一个私有的消息队列,这意味着该队列仅仅能够运行在本地计算机上。如果你使用的计算机位于Windows域中,那么你可以创建一个public的消息队列,这样域中的计算机都可以访问该消息队列。我们创建的消息队列的真实名字叫做AdventureWorksAdmin。

10. 在配置面板中,在绑定文件夹上点击右键,然后选择新的绑定配置。在创建新绑定配置对话框中,点击netMsmqBinding绑定类型,然后点击确认按钮

11. 在右边面板中,设置该绑定配置的名字为AdventureWorksAdminMsmqBindingConfig
你可以通过设置绑定属性以控制消息队列工作的诸多方面。比如,Durable属性决定消息是否可以不受处理过程失败、关机或者重启的影响而依旧存在;设置该属性为false那么将使消息容易受到破坏。ExactlyOnce属性涉及MSMQ的消息可靠性传输;设置该属性为true可以确保消息将被接收到一次并且仅仅一次,而且消息不会丢失或偶然地被并发实例接受两次。设置该属性为true要求消息队列必须是事务性的(使用计算机管理控制台创建消息队列时,可以指定一个队列是否为事务性队列)。
12. 点击安全标签,修改该绑定的安全模式属性为None
消息队列支持消息级别安全和传输级别安全,尽管实现传输级别安全是MSMQ特有的,并且不要求你配置SSL。如果你实现消息级别安全,你可以指定客户端证书的类型。你应该注意到MSMQ消息级别安全实现的验证机制要求配置消息队列服务器,该服务器必须为绑定所使用的消息队列提供一个证书。
13. 在配置面板,点击AdventureWorksAdminMsmqEndpoint端点定义,然后在右边的面板中,设置其绑定配置属性的值为AdventureWorksAdminMsmqBindingConfig
14. 保存配置文件然后退出WCF服务配置编辑器
15. 在Visual Studio中,生成AdventureWorksAdminHost项目。
实验:从WCF客户端向消息队列发送消息
1. 打开Visual Studio命令行工具窗口,然后转到*\WCF\Step.by.Step\Solutions\Chapter12\MSMQ\AdventureWorksAdminHost\bin\Debug文件夹下,然后输入下面的命令以生成客户端代理:
svcutil AdventureWorksAdminHost.exe
svcutil /namespace:*,AdventureWorksAdminTestClient.AdventureWorksAdmin adventure-works.com.2010.07.01.wsdl *.xsd /out:AdventureWorksAdminProxy.cs
为代理类生成的代码包含在AdventureWorksAdminProxy.cs文件中。请注意,当WCF服务使用MSMQ传输协议时,你不能使用Visual Studio自带的添加服务引用向导添加该WCF服务。
2. 返回到Visual Studio中,然后添加AdventureWorksAdminProxy.cs文件至AdventureWorksAdminTestClient项目。
3. 打开AdventureWorksAdminTestClient项目下的Programm.cs文件,该文件的main方法两次调用服务的GenerateDailySalesReport方法
4. 使用WCF服务配置编辑器编辑AdventureWorksAdminTestClient项目的app.config文件
5. 在配置面板,展开客户端文件夹,然后在端点上点击右键,然后选择创建新的客户端端点。
6. 在客户端端点面板中,使用下表的内容设置端点的属性:
属性
名字 MsmqBinding_AdventureWorksAdmin
地址 Net.msmq://localhost/private/AdventureWorksAdmin
绑定 netMsmqBinding
服务合约 AdventureWorksAdminTestClient.AdventureWorksAdmin.AdministrativeService
7. 基于netMsmqBinding类型添加一个绑定配置。设置该绑定名为为AdventureWorksAdminMsmqBindingConfig。并修改该绑定的安全模式为none
8. 返回到MsmqBinding_AdventureWorksAdmin端点定义,然后设置该端点的BindingConfiguration属性的值为AdventureWorksAdminMsmqBindingConfig
9. 保存配置文件并退出WCF服务配置编辑器
10. 在Programm.cs文件中,修改创建代理对象的声明:
到目前为止,你已经完成了服务和客户端程序的所有代码。接下来,你需要创建消息队列然后测试上述服务。
实验:创建AdventureWorksAdmin队列并测试该服务
1. 点击Windows的开始菜单,然后在我的电脑上点击右键,然后点击管理以启动计算机管理控制台。
2. 在计算机管理控制台中,在左边面板中展开服务和程序节点,然后展开消息队列节点,然后在private队列上点击右键,然后选择创建新的队列,最后选择创建私有队列。
3. 在创建私有队列对话框中,在名字处输入AdventureWorksAdmin,并选中事务性支持,然后点击确认按钮。
4. 不要关闭计算机管理控制台,然后回到Visual Studio。
5. 在非调适模式下运行解决方案。
在客户端控制台窗口中,按ENTER键以向服务发送两条GenerateDailySalesReport消息。请注意此时服务尚未启动,但客户端却成功地发送了这两条消息。按ENTER键关闭客户端控制台窗口。
6. 返回到计算机管理控制台,展开私有队列下的AdventurWorksAdmin队列,你将发现有两条消息显示在右边面板中。如下图所示:
7. 在AdventureWorks Admin Host窗口中,点击开始按钮
服务将启动,然后依次从消息队列中获取消息,并处理消息。当消息处理完成后,服务的操作将显示一个消息框。当第二个消息对话框出现后,点击停止按钮停止服务并关闭AdventureWorks Admin Host窗口。
8. 返回到计算机管理控制台。你会发现第六步中显示的两条消息都已经消失。
9. 关机计算机管理控制台。
MSMQ提供了一个易于使用的机制以实现异步操作。但是,netMsmqBinding绑定限制你只能使用单向操作。如果一个服务需要发送响应,那么服务异步地发送一条消息至一个客户端程序可以连接的队列。这就涉及到为每一个客户端实现不同的消息,并且需要关联消息至每一个客户端;只有这样,客户端程序才知道哪一个响应消息对应哪一个请求消息。

WCF 4.0 进阶系列 – 第十二章 实现单向操作和异步操作(下)相关推荐

  1. WCF 4.0 进阶系列 – 第十二章 实现单向操作和异步操作(中)

    单向操作特别适用于"触发然后忘记"场景,在该场景中,客户端程序并不期望服务回传任何信息.但是,许多操作并不适用于这种情况,其向客户端程序返回数据.为了处理这些情况,WCF支持异步操 ...

  2. WCF 4.0 进阶系列 – 第十二章 实现单向操作和异步操作(上)

    当客户端程序调用一个单向操作后,客户端可以继续运行而不用等待服务完成该操作.你可以通过操作合约指定单向操作行为.达到该目的的最简单方式是在当以操作时设置Operation-Contract特性类的Is ...

  3. WCF 4.0 进阶系列 – 第十六章 使用回调合约发布和订阅事件(第二部分)

    使用回调合约通知客户端单向操作的结果 使用回调合约的原则是,提供一个服务,该服务采用单向操作-不返回任何信息-的方式通知客户端程序.本小节的例子基于之前描述过的更改产品价格场景.当客户端程序调用Pro ...

  4. WCF 4.0 进阶系列 – 第十四章 检测服务和路由消息(第四部分)

    使用路由服务类 实现手动路由无疑是非常强大的技术,但是常见的场景下你所希望的仅仅是,基于请求的某些特性而不是编写一些动态的算法以实现路由消息.为了处理这样的场景,WCF提供了RoutingServic ...

  5. 第十二章 实现单向操作和异步操作(上)

    当客户端程序调用一个单向操作后,客户端可以继续运行而不用等待服务完成该操作.你可以通过操作合约指定单向操作行为.达到该目的的最简单方式是在当以操作时设置Operation-Contract特性类的Is ...

  6. 第十二章 Python文件操作【转】

    12.1 open() open()函数作用是打开文件,返回一个文件对象. 用法格式:open(name[, mode[, buffering[,encoding]]]) -> file obj ...

  7. 【TensorFlow】TensorFlow从浅入深系列之十二 -- 教你深入理解卷积神经网络中的池化层

    本文是<TensorFlow从浅入深>系列之第12篇 TensorFlow从浅入深系列之一 -- 教你如何设置学习率(指数衰减法) TensorFlow从浅入深系列之二 -- 教你通过思维 ...

  8. 《Python进阶系列》十二:最全魔术方法整理

    Python中的魔术方法 所谓魔法函数(Magic Methods),是Python的一种高级语法,允许你在类中自定义函数,并绑定到类的特殊方法中.比如在类A中自定义__str__()函数,则在调用s ...

  9. WP8.1学习系列(第二十二章)——在页面之间导航

    在本文中 先决条件 创建导航应用 Frame 和 Page 类 页面模板中的导航支持 在页面之间传递信息 缓存页面 摘要 后续步骤 相关主题 重要的 API Page Frame Navigation ...

最新文章

  1. 框架依赖注入和普通依赖注入_依赖注入快速入门:它是什么,以及何时使用它...
  2. python 随机生成密码
  3. 20130410 现阶段的学习状况
  4. 【Linux 内核 内存管理】优化内存屏障 ③ ( 编译器屏障 | 禁止 / 开启内核抢占 与 方法保护临界区 | preempt_disable 禁止内核抢占源码 | 开启内核抢占源码 )
  5. POJ 3525/UVA 1396 Most Distant Point from the Sea(二分+半平面交)
  6. Creating Your First Mac App--创建你的第一个Mac应用
  7. 2017 全球超大规模数据中心已超过 390 个,中国仅占 8%
  8. shell date
  9. Sencha-概念-Events(事件)(官网文档翻译10)
  10. linux物理内存虚拟内存一致,Liunx内存管理的调用和实现
  11. CodeForces - 1341E Nastya and Unexpected Guest(01bfs)
  12. vue项目代码改进(一)login组件
  13. java resource放入的文件没有生成在classes中_快速部署版@开源在线考试系统一键生成各种题型试卷且实时判卷...
  14. Nandflash希尔特编程器烧录带来的一些点知识信息
  15. php ci_controller,php – CodeIgniter 2:如何多次扩展CI_Controller?
  16. C++访问控制符内容相关介绍
  17. Tomcat日志设置
  18. linux下ASM配置
  19. “中国如果有五个丘成桐,数学肯定世界一流”
  20. 狂神Mybatis入门

热门文章

  1. 检查oracle安装,oracle安装前环境检查
  2. C 线程中容易忽视的 restrict 修饰符修饰
  3. Linux系统备份树莓派,全平台备份树莓派的方法
  4. java response返回xml_Spring 返回Xml格式
  5. 用python写数字_用python 写游戏之数字华容道
  6. suse linux用户界面,suse linux开户图形化界面
  7. golang连接postgresql too many client_MySQL和PostgreSQL压测性能对比
  8. python中“SimpleITK”模块完美快速安装
  9. 简易数字频率计(verilog HDL设计)(2020维护版本)
  10. 互联网寒冬前端社招面试