1、 建立消息队列 1 windows
1) 在远程服务器上建立消息队列,具体步骤参见前面 10.net
6、在IIS中寄宿MSMQ绑定的WCF服务实现分布式部署 16
右键选择计算机/这台电脑——管理——服务和应用程序——消息队列——专用队列——新建——专用队列,输入队列的名称,不要勾选事物性队列,便可完成建立非事物性私有队列。
建立非事物性私有队列
完成建立队列之后,必须设置队列的访问权限,不然没法经过队列发送接收消息。右键选择队列属性——安全选项卡,将everyone和anonymous权限设置为彻底控制。以下图所示:
Everyone彻底控制
Anonymous彻底控制
在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);
}
}
完成契约定义和服务实现之后就能够配置服务端,在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>
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();
}
客户端实现代码
最后启动服务端和客户端后运行结果以下:
修改客户端代码实现,模拟并发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毫秒
服务端请求结果
右键选择计算机——管理——服务和应用程序——消息队列——属性——服务器安全性——取消勾选"禁用未经身份验证的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服务
首先将客户端和服务端绑定的消息队列地址改成远程服务器上的地址net.msmq://192.168.103.66/private/myqueue,禁用本地网卡,而后启动客户端
客户端功能仍然能使用,咱们再看看本地消息队列中是否有数据
能够看到本地传出队列中有一条消息指向远程服务器上的消息队列。如今启用网卡再看看本地消息队列——传出队列和远程服务器消息队列专用队列各有什么变化。
刷新一下,本地消息队列中的传出队列中已经没有消息了,再看一下远程服务器上专用队列中是否有消息
远程服务器上队列中已经有消息了,而且消息ID和本地传出队列中保存过的消息的消息ID一致,证实是同一条消息通过本地传递到了远程服务器上。最后运行一下服务端看可否正确处理消息。
服务端成功处理了客户端离线发送的消息。
经过sefhost虽然也能实现WCF服务的托管可是部署上仍是有不少的局限性,那么基于MSMQ消息队列的WCF服务是否能在IIS中托管呢,答案是确定的。经过微软的进程激活服务(WAS)便可实现非Http绑定的WCF在IIS中托管。要实现非Http绑定的WCF服务在IIS中托管须要作如下步骤的修改。
右键选择开始菜单——控制面板——程序和功能——打开或关闭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)激活。
首先建立一个名为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>
完成服务端代码实现之后,便可在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