基于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相关的文章,希望能给有需要的人带来一点帮助吧,水平有限再加上初次动手,写得不好还请多多包含!废话不多说了直接进入正题. ...
随机推荐
- 使用Xutils 3 中遇到的一些问题!!!!
1.当xml页面中有可见的,同时设置id的控件时,如果在Activity中没有使用注解进行反射该控件,app会crash,提示: Caused by: java.lang.NullPointerEx ...
- 什么是MSI文件?
当你双击`msi`文件时,就会调用`window.installer`程序,接下来就和安装其他程序一样了,但是你要确保你的`window.installer`服务是开启的,你可以在控制面板下的服务中找 ...
- php -- 特殊变量的三种输出
----- 020-3outputs.php ----- <!DOCTYPE html> <html> <head> <meta http-equiv=&qu ...
- JavaScript -- Screen
-----041-Screen.html----- <!DOCTYPE html> <html> <head> <meta http-equiv=" ...
- JAVA多线程Thread VS Runnable详解
要求 必备知识 本文要求基本了解JAVA编程知识. 开发环境 windows 7/EditPlus 演示地址 源文件 进程与线程 进程是程序在处理机中的一次运行.一个进程既包括其所要执行的指令,也 ...
- tensorflow 根据节点名称获取节点
ckpt_file = os.path.join(self.args.bert_dir, 'model.ckpt-6123') # 获取图的reader reader = self.tf_instan ...
- NHibernate 有好几种数据库查询方式
NHibernate 有好几种数据库查询方式 1.原生SQL var employeeQuery = Database.Session .CreateSQLQuery("select * f ...
- 第七章 过滤器 Filter(二)
一 过滤器API 由容器实现的接口 –javax.servlet.Filter –javax.servlet.FilterChain –javax.servlet.FilterConfig 四个包装 ...
- 【跟着开涛学Shiro】(一)Shiro简介
声明:本部分内容均转自于张老师的博客,因为本人很喜欢他的博客,所以一直在学习,转载仅是记录和分享,若也有喜欢的人的话,可以去他的博客首页看:http://jinnianshilongnian.itey ...
- 基于opencv将视频转化为字符串Java版
基于opencv将视频转化为字符串Java版 opencv java 先上一个效果图吧 首先,弄清一下原理 我们要将视频转化为字符画,那么就需要获取画面的每一帧,也就是每一张图片,然后将图片进行转化 ...