博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
.Net下的进程间的通讯 -- Windows消息队列
阅读量:5084 次
发布时间:2019-06-13

本文共 2183 字,大约阅读时间需要 7 分钟。

Windows 消息队列(MSMQ),是微软Windows2000以上的操作系统的一个服务,可以提供在计算机间消息的可靠传输,用来在两个进程间进行异步通讯最合适不过了。

在.Net中有一个MessageQueue组件,在System.Messaging命名空间中,使用这个组件接收与发送消息非常简单。只要在一台服务器上创建一个队列,我们就可以在这个队列上发送与接收消息了。

我们在消息中发送一个XmlDocument对象的简单代码如下:

//队列名称
string queuePath = "machineName\Private$\MyQueue"
//MessageQueue组件初始化
MessageQueue queue = new MessageQueue(queuePath);
//创建一个XMLDocument对象,用来在消息中传输
XmlDocument xmldoc = new XmlDocument();
XmlNode xmlNode = xmldoc.CreateNode(XmlNodeType.Element,"Root","");
xmldoc.AppendChild(xmlNode);
queue.Send(xmldoc);

如果对消息还有其他要求,可以创建一个Message对象,设置这个Message对象,再发送这个Message对象

System.Messaging.Message msg = new System.Messaging.Message(xmldoc);
queue.Send(msg);

接收这个消息

//队列名称
string queuePath = "machineName\Private$\MyQueue"
//MessageQueue组件初始化
MessageQueue queue = new MessageQueue(queuePath);
//消息反序列化的对象,一定要有这个对象,以便将消息反序列化为原来的对象
//构造函数的参数是传过来的消息中的对象可能的类型。
queue.Formatter = new XmlMessageFormatter(new Type[] {typeof(XmlDocument)});
System.Messaging.Message msg = queue.Receive();
XmlDocument xmlDoc = ((XmlDocument)msg.Body;

上面的程序在一台机器上没有问题,当在另一台机器上运行时,出现了问题,无法发送,查找原因后发现是在工作组模式下工作时,向远程机器上发现消息只能使用格式名,格式名的格式也有几种:

< XMLNAMESPACE PREFIX ="[default]" httpmsdnmicrosoftcommtps NS ="http://msdn2.microsoft.com/mtps" />FormatName:Public= 5A5F7535-AE9A-41d4-935C-845C2AFF7112

FormatName:DIRECT=SPX:NetworkNumber; HostNumber\ QueueName

FormatName:DIRECT=TCP:IPAddress\ QueueName

FormatName:DIRECT=OS:MachineName\ QueueName

我使用了直接格式名:FormatName:DIRECT=OS:machineName\private$\myqueue,之后就可以将消息发送到选程机器上了。

要想在远程机器上接收消息,还要为专用队列的“安全”选项中的"ANONYMOUS LOGON"用户分配接收消息的权限。

但这样问题就来了,在队列上的消息可能被在局域网中运行的其他程序接收走。在看了MSMQ的诸多安全功能后,在MSDN中看到MSMQ支持身份验证,加密什么的,就彻底的研究了一下,结果发现什么都不行,就是因为我没有在域环境中,后来终于搜索到了一篇文章:
,里面明确的写到:
在工作组模式中使用消息队列时,存在下列限制:
工作组模式下的计算机需要与目标计算机建立直接连接,并且只支持直接消息传输。无法路由通过这些计算机发送的消息。 
不能访问 Active Directory。在这种情况下,只能在本地计算机上创建和管理专用队列。 
不能使用内部证书发送经过验证的消息;必须使用外部证书。
无法对消息进行加密。
不支持从属客户端。

所以为了避免上面的问题,我采用的设计策略是:在接收的服务器上建立消息队列,只有本机程序可以接收并删除,其他服务器只可以远程将消息发送到这个队列。

 

最后补充一下事务性消息队列:当使用事务接收消息时,队列必须是本地事务性队列。不能在事务内检索来自远程事务性队列或本地非事务性队列的消息。消息队列不支持事务性远程读取操作,但是,可以通过使用事务读取响应应用程序来获得这样的功能,我的理解其实是做了一个事务的消息中转,需要使用事务将远程机器上的消息发送到本地的队列中来,当然中转程序需要驻留在远程队列所在的机器上。

转载于:https://www.cnblogs.com/gjhjoy/p/3531048.html

你可能感兴趣的文章
spring boot配置跨域
查看>>
BZOJ 1996 合唱队(DP)
查看>>
进击吧!阶乘——大数乘法
查看>>
安卓学习资料推荐-25
查看>>
Mysql数据库备份和还原常用的命令
查看>>
关于退出当前页面在火狐的一些问题
查看>>
【项目实施】项目考核标准
查看>>
spring-aop AnnotationAwareAspectJAutoProxyCreator类
查看>>
经典入门_排序
查看>>
Redis Cluster高可用集群在线迁移操作记录【转】
查看>>
二、spring中装配bean
查看>>
VIM工具
查看>>
javascript闭包
查看>>
@Column标记持久化详细说明
查看>>
创建本地yum软件源,为本地Package安装Cloudera Manager、Cloudera Hadoop及Impala做准备...
查看>>
mysql8.0.13下载与安装图文教程
查看>>
站立会议08(冲刺2)
查看>>
url查询参数解析
查看>>
http://coolshell.cn/articles/10910.html
查看>>
[转]jsbsim基础概念
查看>>