.net中使用MSMQ

学习微软的技术有点让人恼火的一个原因是,技术文档跨度太大。

有一个简单的例子,但是涉及到很多具体使用的细节,隐藏在大量文字文档中。

作为技术文档,似乎并不是为了给想学习的人使用的,开发者将所有有关该技术的内容,一股脑的堆叠起来。

了解到MSMQ可以用作windows上的进程间通信,所以想了解应该如何使用。

使用上,关心的可能依次是如下几个问题

  1. 如何创建,创建时挂接/对应的系统资源是什么,如何指定
  2. 如何发送、接收
  3. 实践相关,如线程安全性,容量等
  4. 权限、控权
  5. 其他

最关心的,一般其实就是前两个了

初见微软的文档例子,看到创建指定的队列名称一头雾水,为什么名称要用".\xxx"开头(如".\myQueue\Journal$"什么意思)?发送字符串如何接收?

搜索了不少资料,根据自己的理解整理以下。

准备

MSMQ,对应c#的MessageQueue类,是在单独的System.Messaging.dll中的,一般在.net sdk相关目录中

该功能依赖windows的消息队列功能,需要在widows功能中先开启,因为默认是不开启的。

同时,该功能依赖的dll也不再默认dll中,添加引用时,可以从这里查找(注意版本可能不同):

C:Program Files (x86)Reference AssembliesMicrosoftFramework.NETFrameworkv3.5ProfileClientSystem.Messaging.dll

初始化

MSMQ不存在时,需要先创建,如果已经存在,则需要通过new来生成:

                if (!MessageQueue.Exists(path))
                {
                    msgq = MessageQueue.Create(path);
                }
                else
                {
                    msgq = new MessageQueue(path);
                }

这里关键点在于,path是什么?看下表:

Queue type

Syntax

Public queue

MachineNameQueueName

Private queue

MachineNamePrivate$QueueName

Journal queue

MachineNameQueueNameJournal$

Machine journal queue

MachineNameJournal$

Machine dead-letter queue

MachineNameDeadletter$

Machine transactional dead-letter queue

MachineNameXactDeadletter$

由于MSMQ是可以跨主机,远程调用,同时还有一些系统预定义的功能,这里直接使用的话深入了解很复杂。

但是最简单的,进程间通信功能,我了解到可以用Private queue,这种类型的消息队列,是在本机使用的,用于本机通信。

关于`MachineName`,对于本机,也可以直接用点`.`来代替,于是,一个最简单的队列名可以是:

@".Private$MyQueue"

读写

由于我使用上,是通过JSON做消息格式,序列化成字符串通信就可以了。

最简单的,看到了MSMQ的Send()和Receive()接口,于是很容易想到:

//发送端:
Message msg = new Message();
msg.Body = stringContent;
queue.Send(msg);

//接收端
var message = queue.Receive();
return (string)message.Body;

然而实际运行时,接收端总是报错不识别。

搜索了一些例子,才了解到,需要制定默认使用的格式化器,否则内容无法识别。

具体做法是:

//发送端:
Message msg = new Message();
msg.Body = stringContent;
msg.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });//注意这句!!
queue.Send(msg);

//接收端
var message = queue.Receive();
return (string)message.Body;

 发送端必须指定格式化Formatter,而接收端根据我的测试,并不需要,默认的就是Xml的formatter。

至此基本的收发到此为止。

其他

有几点需要注意

  • 收发操作,都是线程不安全的,为了线程安全,需要
    • 使用锁保护
    • 或者使用线程安全的接口(实际上目前似乎仅有一个接口是线程安全的)
  • 当基本功能实现以后,安全也是很重要的考量。消息队列有大量权限相关的配置操作
  • 消息队列在早期windows中似乎是有1000的容量,新版的没有关注容量限制,但是应该是不少于1000的,如果消息太多,还是需要考虑是否合适
原文地址:https://www.cnblogs.com/mosakashaka/p/12608031.html