学习微软的技术有点让人恼火的一个原因是,技术文档跨度太大。
有一个简单的例子,但是涉及到很多具体使用的细节,隐藏在大量文字文档中。
作为技术文档,似乎并不是为了给想学习的人使用的,开发者将所有有关该技术的内容,一股脑的堆叠起来。
了解到MSMQ可以用作windows上的进程间通信,所以想了解应该如何使用。
使用上,关心的可能依次是如下几个问题
- 如何创建,创建时挂接/对应的系统资源是什么,如何指定
- 如何发送、接收
- 实践相关,如线程安全性,容量等
- 权限、控权
- 其他
最关心的,一般其实就是前两个了
初见微软的文档例子,看到创建指定的队列名称一头雾水,为什么名称要用".\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的,如果消息太多,还是需要考虑是否合适