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。在这种情况下,只能在本地计算机上创建和管理专用队列。 
不能使用内部证书发送经过验证的消息;必须使用外部证书。
无法对消息进行加密。
不支持从属客户端。

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

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

.Net下的进程间的通讯 -- Windows消息队列的更多相关文章

  1. [转]WINDOW进程间数据通讯以及共享内存

    1.引言 在Windows程序中,各个进程之间常常需要交换数据,进行数据通讯.WIN32 API提供了许多函数使我们能够方便高效地进行进程间的通讯,通过这些函数我们可以控制不同进程间的数据交换,就如同 ...

  2. 【转】C++ 进程间的通讯(一):简单的有名管道实现

    原文: C++ 进程间的通讯(一):简单的有名管道实现 -------------------------------------------------- 进程间的通讯(一):简单的有名管道实现   ...

  3. 8.7 进程间的通讯:管道、消息队列、共享内存、信号量、信号、Socket

    进程间的通讯 进程间为什么需要通讯? 共享数据.数据传输.消息通知.进程控制 进程间的通讯有哪些类型? 首先,联系前面讲过的知识,进程之间的用户地址空间是相互独立的,不能进行互相访问,但是,内核空间却 ...

  4. 进程间的通讯(IPC)方式

    内存映射 为什么要进行进程间的通讯(IPC (Inter-process communication)) 数据传输:一个进程需要将它的数据发送给另一个进程,发送的数据量在一个字节到几M字节之间共享数据 ...

  5. Linux下多任务间通信和同步-消息队列

    Linux下多任务间通信和同步-消息队列 嵌入式开发交流群280352802,欢迎加入! 简介 消息队列简称为队列.消息队列就是一些消息的列表.用户可以在消息队列中添加消息和读取消息等.从这点上看,消 ...

  6. 柯南君:看大数据时代下的IT架构(5)消息队列之RabbitMQ--案例(Work Queues起航)

    二.Work Queues(using the Java Client) 走起   在第上一个教程中我们写程序从一个命名队列发送和接收消息.在这一次我们将创建一个工作队列,将用于分发耗时的任务在多个工 ...

  7. Windows消息队列(优先队列,结构体中放比较函数)

    Windows消息队列 消息队列是Windows系统的基础.对于每个进程,系统维护一个消息队列.如果在进程中有特定事件发生,如点击鼠标.文字改变等,系统将把这个消息加到队列当中.同时,如果队列不是空的 ...

  8. 5-2 Windows消息队列 (25分)

    5-2 Windows消息队列   (25分) 消息队列是Windows系统的基础.对于每个进程,系统维护一个消息队列.如果在进程中有特定事件发生,如点击鼠标.文字改变等,系统将把这个消息加到队列当中 ...

  9. 7-26 Windows消息队列(25 分)(堆排序)

    7-26 Windows消息队列(25 分) 消息队列是Windows系统的基础.对于每个进程,系统维护一个消息队列.如果在进程中有特定事件发生,如点击鼠标.文字改变等,系统将把这个消息加到队列当中. ...

随机推荐

  1. 【转】Android 4.2蓝牙介绍

    原文网址:http://blog.csdn.net/innost/article/details/9187199 Tieto公司某蓝牙大牛写得<程序员>投稿文章 Android 4.2蓝牙 ...

  2. Flume FileChannel优化(扩展)实践指南

    本文系微博运维数据平台(DIP)在Flume方面的优化扩展经验总结,在使用Flume FileChannel的场景下将吞吐率由10M/s~20M/s提升至80M/s~90M/s,分为四个部分进行介绍: ...

  3. Android 网络通信框架Volley简介(Google IO 2013)

    1. 什么是Volley 在这之前,我们在程序中需要和网络通信的时候,大体使用的东西莫过于AsyncTaskLoader,HttpURLConnection,AsyncTask,HTTPClient( ...

  4. ArcGIS_系列视频教程::精品大放送

    转自:http://www.cnblogs.com/gispeng/archive/2008/11/28/1342758.html     ArcGIS_系列视频教程::精品大放送 文件名: ArcG ...

  5. 生成AWK快照的方法

    1.首先在用oracle用户登陆执行sqlplus命令用dba用户执行: exec DBMS_WORKLOAD_REPOSITORY.CREATE_SNAPSHOT (flush_level=> ...

  6. ASP.NET生命周期详解 [转]

    最近一直在学习ASP.NET MVC的生命周期,发现ASP.NET MVC是建立在ASP.NET Framework基础之上的,所以原来对于ASP.NET WebForm中的很多处理流程,如管道事件等 ...

  7. 《C语言程序设计现代方法》第2章 C语言基本概念

    C语言的基本概念 第一个C程序例子. /* pun.c */ #include <stdio.h> int main(void) { printf("To C, or not t ...

  8. 【iOS 7】使用UIScreenEdgePanGestureRecognizer实现swipe to pop效果

    在iOS 7还没有发布的时候,各种App实现各种的swipe to pop效果,比如这里有一份简单的demo. 在iOS 7上,只要是符合系统的导航结构: - (BOOL)application:(U ...

  9. LabVIEW系列——拍振现象重现

  10. expect批量分发公钥

    sshkey.exp #!/usr/bin/expect# 由于是多台服务器,需要在shell脚本中循环调用该脚本 if { $argc != 2 } { send_user "usage: ...