基于MSMQ绑定的WCF服务实现总结
六、在IIS中寄宿MSMQ绑定的WCF服务实现分布式部署 16
- 创建消息队列
- 创建一个非事物性的私有队列
右键选择计算机/这台电脑——管理——服务和应用程序——消息队列——专用队列——新建——专用队列,输入队列的名称,不要勾选事物性队列,即可完成创建非事物性私有队列。

创建非事物性私有队列


- 设置消息队列访问权限
完成创建队列以后,必须设置队列的访问权限,否则无法通过队列发送接收消息。右键选择队列属性——安全选项卡,将everyone和anonymous权限设置为完全控制。如下图所示:

Everyone完全控制

Anonymous完全控制

- 创建WCF服务并绑定消息队列
- 创建HelloService服务

在VS中创建一个解决方案,并且新建一个类库项目,两个控制台项目上图所示。
在WCFMSMQDemo.Service服务层中创建一个名为IHelloService的接口作为服务契约,创建一个名为HelloClient的实现IHelloService接口的类作为服务类。在服务契约中定义一个无返回值的单项访问的方法。消息队列支持无返回值的单向访问。具体代码如下:
[ServiceContract]
public interface IHelloService
{
/// <summary>
///发送消息的方法
/// </summary>
/// <param name="message"></param>
[OperationContract(IsOneWay = true)]
void SendMessage(string message);
}
设置方法的属性IsOneWay=true,返回值为void
服务端代码如下所示:
public class HelloClient:IHelloService
{
public void SendMessage(string message)
{
Console.WriteLine("接收到来自客户端的消息" + message);
}
}
- 设置WCF服务的配置文件
完成契约定义和服务实现以后就可以配置服务端,在Server中添加对Service项目的引用,并添加引用System.ServiceModel,编译生成一下整个解决方案,否则在配置服务端配置文件的时候无法出现智能提示。基于消息队列绑定的WCF服务需要使用net.msmq协议绑定,服务的地址设置为如下格式net.msmq://消息队列所在服务器ip/{private}/队列名称。如果是私有队列必须加上private,公共队列则无需加上。由于我们创建的是私有队列所以服务的地址为net.msmq://localhost/private/myqueue。由于是非事物性队列所以需要这是绑定属性exactlyOnce="false"。这里我们的WCF服务只是用来演示如何调用消息队列就不再设置安全验证模式,直接设置不采用任何安全验证方式<security mode="None" />
具体设置代码如下所示:
<system.serviceModel>
<services>
<service name="WCFMSMQDemo.Service.HelloClient">
<endpoint address="net.msmq://192.168.103.66/private/myqueue" bindingConfiguration="NoneSecurity" binding="netMsmqBinding" contract="WCFMSMQDemo.Service.IHelloService">
</endpoint>
</service>
</services>
<bindings>
<netMsmqBinding>
<binding name="NoneSecurity" exactlyOnce="false" queueTransferProtocol="Native">
<security mode="None" />
</binding>
</netMsmqBinding>
</bindings>
</system.serviceModel>
设置完服务端配置文件以后需要设置一下客户端的配置文件,客户端配置文件与普通的WCF服务端配置稍有不同,具体配置如下:
<system.serviceModel>
<client>
<endpoint address="net.msmq://localhost/private/myqueue" binding="netMsmqBinding" bindingConfiguration="NoneSecurity" contract="WCFMSMQDemo.Service.IHelloService" name="msmqService">
</endpoint>
</client>
<bindings>
<netMsmqBinding>
<binding name="NoneSecurity" exactlyOnce="false" queueTransferProtocol="Native">
<security mode="None" />
</binding>
</netMsmqBinding>
</bindings>
</system.serviceModel>
- WCF服务服务端和客户端代码实现
using (ServiceHost host = new ServiceHost(typeof(HelloClient)))
{
host.Open();
Console.WriteLine("WCF 服务已经启动@" + DateTime.Now);
Console.ReadKey();
}
服务端代码
using (ChannelFactory<IHelloService> channelFactory = new ChannelFactory<IHelloService>("msmqService"))
{
IHelloService proxyeService = channelFactory.CreateChannel();
proxyeService.SendMessage("Hello World");
Console.WriteLine("调用服务成功");
Console.ReadKey();
}
客户端实现代码
最后启动服务端和客户端后运行结果如下:


- 测试WCF服务
修改客户端代码实现,模拟并发1000次访问,客户端实现代码如下:
using (ChannelFactory<IHelloService> channelFactory = new ChannelFactory<IHelloService>("msmqService"))
{
IHelloService proxyeService = channelFactory.CreateChannel();
Parallel.For(0, 1000, i =>
{
proxyeService.SendMessage("Hello World" + i);
Console.WriteLine("调用服务端" + i);
});
Console.WriteLine("调用成功");
Console.ReadKey();
}
启动服务端,然后启动客户端,运行结果如下

客户端请求结果,模拟并发1000次访问只用了407毫秒

服务端请求结果
- 启用远程访问MSMQ
- 在远程服务器上创建消息队列,具体步骤参见前面
- 设置MSMQ身份验证
右键选择计算机——管理——服务和应用程序——消息队列——属性——服务器安全性——取消勾选"禁用未经身份验证的RPC调用",否则无法通过消息队列收发消息。
Windows 7 上消息队列属性设置

如果是在windows server2008 r2服务器系统上设置会有所不同

Windows server 2008 r2 上消息队列设置
- 修改服务端和客户端消息队列地址绑定。
将地址中的修改为消息队列上服务器上对应的消息队列地址。net.msmq://192.168.103.66/private/myqueue。远程服务器上必须存在消息队列,否则会提示无法打开指定的消息队列。修改后的绑定地址如下
<system.serviceModel><services>
<service
name="WCFMSMQIISDemo.Service.HelloClient"
behaviorConfiguration="HttpGetEnable"><endpoint
address="net.msmq://192.168.103.66/private/HelloService.svc"
binding="netMsmqBinding"
bindingConfiguration="NoneSecurity"
contract="WCFMSMQIISDemo.Service.IHelloService"></endpoint>
<endpoint
address="mex"
binding ="mexHttpBinding"
contract="IMetadataExchange"></endpoint>
</service>
</services>
<bindings>
<netMsmqBinding>
<binding
name="NoneSecurity"
exactlyOnce="false"
queueTransferProtocol="Native"><security
mode="None" /></binding>
</netMsmqBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior
name="HttpGetEnable"><serviceMetadata
httpGetEnabled="true"/><serviceDebug
includeExceptionDetailInFaults="true"/></behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment
aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true"></serviceHostingEnvironment>
</system.serviceModel>
运行服务端和客户端后结果如下

- 通过消息队列离线使用WCF服务
使用消息队列收发消息,如果客户端与服务端无法及时通信,那么客户端发送的请求消息会暂时保存在本机的消息队列中,前提是本机中安装了消息队列服务,否则无法实现离线调用功能。当客户端能够与服务端正常通信以后,客户端上的消息会被自动发送到服务端的消息队列中然后被服务端处理掉。下面演示一下离线使用WCF服务
首先将客户端和服务端绑定的消息队列地址改为远程服务器上的地址net.msmq://192.168.103.66/private/myqueue,禁用本地网卡,然后启动客户端

客户端功能仍然能使用,我们再看看本地消息队列中是否有数据

可以看到本地传出队列中有一条消息指向远程服务器上的消息队列。现在启用网卡再看看本地消息队列——传出队列和远程服务器消息队列专用队列各有什么变化。

刷新一下,本地消息队列中的传出队列中已经没有消息了,再看一下远程服务器上专用队列中是否有消息

远程服务器上队列中已经有消息了,并且消息ID和本地传出队列中保存过的消息的消息ID一致,证明是同一条消息经过本地传递到了远程服务器上。最后运行一下服务端看能否正确处理消息。

服务端成功处理了客户端离线发送的消息。
- 在IIS中寄宿MSMQ绑定的WCF服务实现分布式部署
通过sefhost虽然也能实现WCF服务的托管但是部署上还是有很多的局限性,那么基于MSMQ消息队列的WCF服务是否能在IIS中托管呢,答案是肯定的。通过微软的进程激活服务(WAS)即可实现非Http绑定的WCF在IIS中托管。要实现非Http绑定的WCF服务在IIS中托管需要做以下步骤的修改。
- 启用WCF的非htttp激活
右键选择开始菜单——控制面板——程序和功能——打开或关闭windows功能,找到.net framwork3.5.1 启用以下功能

Windows 7下实现

Windows server 2008 r2 服务器上

Windows 8/8.1需要安装.net3.5 并勾选windows communication foundation 非http激活和.net4.5中的wcf服务下的消息队列(MSMQ)激活。
- 创建IIS中托管的WCF服务
首先创建一个名为HelloService.svc的私有非事物性队列,并设置队列可以远程访问。然后创建WCF服务。创建WCF服务具体服务定义如下
public
class
HelloClient : IHelloService{
public
void SendMessage(string message){
File.WriteAllText(@"D:\test.txt", message, Encoding.Default);
}
}
设置为msmq绑定,同时开启元素数据获取。具体服务端配置文件如下
<system.serviceModel>
<services>
<service
name="WCFMSMQIISDemo.Service.HelloClient"
behaviorConfiguration="HttpGetEnable"><endpoint
address="net.msmq://192.168.103.66/private/HelloService.svc"
binding="netMsmqBinding"
bindingConfiguration="NoneSecurity"
contract="WCFMSMQIISDemo.Service.IHelloService"></endpoint>
<endpoint
address="mex"
binding ="mexHttpBinding"
contract="IMetadataExchange"></endpoint>
</service>
</services>
<bindings>
<netMsmqBinding>
<binding
name="NoneSecurity"
exactlyOnce="false"
queueTransferProtocol="Native"><security
mode="None" /></binding>
</netMsmqBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior
name="HttpGetEnable"><serviceMetadata
httpGetEnabled="true"/><serviceDebug
includeExceptionDetailInFaults="true"/></behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
- 创建网站并添加msmq绑定
完成服务端代码实现以后,即可在IIS中创建网站并添加msmq绑定来实现服务的寄宿。在IIS中新建一个网站,并将网站目录指向创建的WCF所在目录。添加网站的msmq绑定,右键网站——编辑绑定——添加,类型选择net.msmq,绑定信息填写消息队列服务器所在地址,如192.168.103.66。
点击添加按钮添加msmq绑定

默认是http绑定

将添加类型改为net.msmq,绑定信息填写消息队列所在服务器ip


添加net.msmq绑定以后还要增加网站的net.msmq支持,右键网站——管理网站——高级设置——已启用的协议中添加net.msmq

设置完成以后即可启动网站,访问网站下的HelloService.svc文件,如http://localhost:8080/HelloService.svc

启动wcftestclient,添加服务引用


查看D盘根目录下文件

有内容写入,证明服务运行成功。
- 写在最后
如果你对本文有什么不明白的地方可以与我联系,或者有更好的建议与意见欢迎与我交流。QQ:489505067
基于MSMQ绑定的WCF服务实现总结的更多相关文章
- IIS 中托管基于TCP绑定的WCF服务
IIS 中托管基于TCP绑定的WCF服务 一.创建一个基于TCP绑定的WCF服务 1.创建一个的简单的服务具体代码如下 服务契约定义 namespace SimpleService { // 注意: ...
- 将使用netTcp绑定的WCF服务寄宿到IIS7上全记录 (这文章也不错)
原文地址:http://www.cnblogs.com/wengyuli/archive/2010/11/22/wcf-tcp-host-to-iis.html 摘要 在项目开发中,我们可能会适时的选 ...
- 搭建基于asp.net的wcf服务,ios客户端调用的实现记录
一.写wcf 问题: 1.特定的格式 2.数据绑定 3.加密解密 二.发布到iis 问题: 1.访问权限问题,添加everyone权限 访问网站时:http://localhost/WebbUploa ...
- WCF 服务编程 - 常用绑定
WCF 定义了5中常用的绑定. 一. 绑定 1.基本绑定: 对应于BasicHttpBinding类.基本绑定能够将WCF服务公开为传统的ASMX Web服务,使得原客户端能够与新的服务协作.如果客 ...
- WCF 服务的ABC之绑定(六)
绑定 Binding 绑定是开发人员控制WCF程序与其他消息交互的主要手段.从功能上看,绑定创建了通道工厂惑通道侦听器的堆栈对象.绑定直接惑间接创建的对象是WCF实现各种消息功能(例如,传输.安全性. ...
- WCF技术剖析之三:如何进行基于非HTTP的IIS服务寄宿
原文:[原创]WCF技术剖析之三:如何进行基于非HTTP的IIS服务寄宿 在上面一篇文章中,我们对不同版本的IIS,以及ASP.NET得的实现机制进行了详细而深入的分析.在介绍IIS7.0的时候,我们 ...
- WCF入门(八)---WCF服务绑定
WCF服务绑定是一个集合,每个元素定义了服务与客户端进行通信方式的几个元素.传输元素和一个消息编码元素各自结合两个最重要的组成部分.这里是WCF服务绑定常用的列表. 基础绑定 基础约束是由basicH ...
- WCF分布式开发步步为赢(13):WCF服务离线操作与消息队列MSMQ
之前曾经写过一个关于MSMQ消息队列的文章:WCF分布式开发必备知识(1):MSMQ消息队列 ,当时的目的也是用它来作为学习WCF 消息队列MSMQ编程的基础文章.在那篇文章里,我们详细介绍了MSMQ ...
- 实战WCF中net.tcp和net.msmq绑定协议
平时很少写博文的,以前都是转载其他园友的文章,这几天有时间就自己尝试写一些wcf相关的文章,希望能给有需要的人带来一点帮助吧,水平有限再加上初次动手,写得不好还请多多包含!废话不多说了直接进入正题. ...
随机推荐
- wordpress谷歌字体
wordpress插件:disable google fonts wordpress插件:Remove Open Sans font from WP core 在主题的functions.php添加 ...
- 接口测试学习笔记(Jmeter)
常见接口协议: 1.http 超文本传输协议 2.https 安全超文本传输协议 3.ftp 文件传输协议 4.tcp 网络控制协议 5.IP 互联网协议 6.udp 用户数据协议 -- HTTP协议 ...
- 配置Codis-FE(管理界面)
codis所有的配置项可以有两种方式进行管理:通过图形界面进行配置,另外一种通过命令配置. 1.通过配置文件生成codis-fe的启动文件a.通过codis的管理工具完成:/usr/local/cod ...
- Ajax初始接触
演示JS对象的属性,方法和事件的使用 (1)window.location.href (2)form.submit() <form action="" method=&quo ...
- Maven <Profiles>定义不同环境的参数变量
记录一下 https://blog.csdn.net/qq245282209/article/details/52192115
- WPF 数据绑定 使用Code First with Database
一.准备工作 1.开发工具 Visual Studio 2013 2.安装 Entity Framework 6 Tools for Visual Studio 2012 & 2013 来实现 ...
- 【杂谈】Java I/O的底层实现
前言 Java I/O功能封装的很好,使用起来很方便,就是刚开始学的时候,如果不了解装饰器模式,会被他繁多的类给吓到.用多了也就习惯了,而且现在有很多实用的封装良好的实用类,可直接读写整个文件.开发者 ...
- 并发编程之 Java 三把锁
前言 今天我们继续学习并发.在之前我们学习了 JMM 的知识,知道了在并发编程中,为了保证线程的安全性,需要保证线程的原子性,可见性,有序性.其中,synchronized 高频出现,因为他既保证了原 ...
- 【WePY小程序框架实战三】-组件传值
[WePY小程序框架实战一]-创建项目 [WePY小程序框架实战二]-页面结构 父子组件传值 静态传值 静态传值为父组件向子组件传递常量数据,因此只能传递String字符串类型. 父组件 (paren ...
- .19-浅析webpack源码之compile流程-rules参数处理(2)
第一步处理rule为字符串,直接返回一个包装类,很简单看注释就好了. test/include/exclude 然后处理test.include.exclude,如下: if (rule.test | ...