zoukankan      html  css  js  c++  java
  • .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的,如果消息太多,还是需要考虑是否合适
  • 相关阅读:
    【算法】273-每周一练 之 数据结构与算法(Tree)
    【算法】272-每周一练 之 数据结构与算法(Dictionary 和 HashTable)
    【CSS】271- RGB、HSL、Hex网页色彩,看完这篇全懂了
    【Redis】270- 你需要知道的那些 redis 数据结构
    Hybird App 应用开发中5个必备知识点复习
    【Vuejs】269- 提升90%加载速度——vuecli下的首屏性能优化
    【富文本】268- 富文本原理了解一下?
    HTML5 CSS3 经典案例:无插件拖拽上传图片 (支持预览与批量) (二)
    HTML5 CSS3 经典案例:无插件拖拽上传图片 (支持预览与批量) (一)
    HTML5 CSS3 专题 : 拖放 (Drag and Drop)
  • 原文地址:https://www.cnblogs.com/mosakashaka/p/12608031.html
Copyright © 2011-2022 走看看