MSMQ全称MicroSoft Message Queue,微软消息队列,是在多个不同的应用之间实现相互通信的一种异步传输模式,相互通信的应用可以分布于同一台机器上,也可以分布于相连的网络空间中的任一位置。它的实现原理是:消息的发送者把自己想要发送的信息放入一个容器中(我们称之为Message),然后把它保存至一个系统公用空间的消息队列(Message Queue)中;本地或者是异地的消息接收程序再从该队列中取出发给它的消息进行处理。

消息Message是由通信的双方所需要传递的信息。

队列的类型主要包括一下几种:

“公共队列”在整个“消息队列”网络中复制,并且有可能由网络连接的所有站点访问。

“专用队列”不在整个网络中发布。相反,它们仅在所驻留的本地计算机上可用。专用队列只能由知道队列的完整路径名或标签的应用程序访问。

“管理队列”包含确认在给定“消息队列”网络中发送的消息回执的消息。指定希望 MessageQueue 组件使用的管理队列(如果有的话)。

“响应队列”包含目标应用程序接收到消息时返回给发送应用程序的响应消息。指定希望 MessageQueue 组件使用的响应队列(如果有的话)。

优点:稳定、消息优先级、脱机能力以及安全性,有保障的消息传递和执行许多业务处理的可靠的防故障机制。

缺点:MSMQ不适合于Client需要Server端实时交互情况.大量请求时候,响应延迟.

  1. .NET编程
  2.  
  3. 、命名空间 using System.Messaging;
  4.  
  5. 、默认存储路径 C:\WINDOWS\system32\msmq\storage
  6.  
  7. 、创建消息队列:MessageQueue mq = MessageQueue.Create(@".\Private$\LeeMSMQ");
  8.  
  9. 、删除队列:MessageQueue.Delete(@".\Private$\LeeMSMQ");
  10.  
  11. 、发送消息:MessageQueue mq = new MessageQueue(@".\Private$\LeeMSMQ");
  12.  
  13. mq.Send("sayhello1,hello msmq!", "sayhello1");
  14.  
  15. mq.Send("sayhello2,hello msmq!", "sayhello2");
  16.  
  17. 、接受并删除消息:MessageQueue mq = new MessageQueue(@".\Private$\LeeMSMQ")
  18.  
  19. Message msg = mq.Receive();//引用的队列中可用的第一条消息
  20.  
  21. 、接受但不删除消息:Message msg = mq.Peek();
  22.  
  23. 、删除所有消息: Message msg = mq.Purge();
  24.  
  25. 、返回本机所有私有队列的消息
  26.  
  27. //返回本机所有私有队列的消息
  28.  
  29. foreach (MessageQueue mq in MessageQueue.GetPrivateQueuesByMachine("liyanping"))
  30.  
  31. {
  32.  
  33. mq.Formatter = new XmlMessageFormatter(new string[] { "System.String" });
  34.  
  35. Message[] msg = mq.GetAllMessages();
  36.  
  37. foreach (Message m in msg)
  38.  
  39. {
  40.  
  41. Console.WriteLine("label:{0},body:{1}", m.Label, m.Body);
  42.  
  43. }
  44.  
  45. }
  46.  
  47. 、返回指定队列的消息
  48.  
  49. if (MessageQueue.Exists(@".\Private$\LeeMSMQ"))//判断私有消息是否存在
  50.  
  51. {
  52.  
  53. using (MessageQueue mq = new MessageQueue(@".\Private$\LeeMSMQ"))
  54.  
  55. {
  56.  
  57. mq.Formatter = new XmlMessageFormatter(new string[] { "System.String" });//设置消息队列格式化器
  58.  
  59. Message msg = mq.Receive();//接收消息
  60.  
  61. Console.WriteLine("label:{0},body: {1}", msg.Label, msg.Body);//输出消息
  62.  
  63. MessageQueue.Delete(@".\Private$\LeeMSMQ");
  64.  
  65. }
  66.  
  67. }

下面开始消息队列实战开发

msmq客户端:包含了消息基类和发送消息send方法以及抽象的序列化数据的方法

  1. public class BaseMsg
  2. {
  3. public BaseMsg()
  4. {
  5. Recoverable = true;
  6. PriorityLevel = MessagePriority.Normal;
  7. }
  8.  
  9. public bool Recoverable { get; set; }
  10.  
  11. public MessagePriority PriorityLevel { get; set; }
  12. }

然后实现client发送msmq及序列化消息的基类

  1. public abstract class MSMQClient<T>
  2. where T : BaseMsg
  3. {
  4. private readonly string queueName;
  5. protected MSMQClient(string appSettingName)
  6. {
  7. ConfigurationManager.RefreshSection("appSettings");
  8. this.queueName = ConfigurationManager.AppSettings[appSettingName];
  9. }
  10.  
  11. /// <summary>
  12. /// 添加短信到消息队列
  13. /// </summary>
  14. /// <param name="entity"></param>
  15. public void Send(T entity)
  16. {
  17. if (entity == null)
  18. throw new ArgumentNullException("发送对象不能为空");
  19. if (string.IsNullOrEmpty(queueName))
  20. {
  21. throw new ArgumentNullException("队列名称不能为空");
  22. }
  23.  
  24. var msg = Serialize(entity);
  25. var queue = new MessageQueue(queueName);
  26. queue.Send(msg);
  27. }
  28.  
  29. protected abstract Message Serialize(T msg);
  30. }

msmq服务端:消息处理的公共接口、Msmq监听

  1. public interface IMessageProcessor
  2. {
  3. /// <summary>
  4. /// 处理方法
  5. /// </summary>
  6. /// <param name="o"></param>
  7. void Process(object o);
  8. }

Msmq的监听

  1. class MSMQListener
  2. {
  3. private readonly MessageQueue queue;
  4. private readonly WaitHandle[] waiteHandle = new WaitHandle[];
  5. public event MessageReceivedEventHandler MessageReceived;
  6.  
  7. /// <summary>
  8. /// 构造函数
  9. /// </summary>
  10. /// <param name="queuePath">要监控队列名称</param>
  11. public MSMQListener(string queuePath)
  12. {
  13. queue = new MessageQueue(queuePath);
  14. }
  15.  
  16. /// <summary>
  17. /// 开启监控
  18. /// </summary>
  19. public void Start()
  20. {
  21. queue.ReceiveCompleted += OnReceiveCompleted;
  22. StartListening();
  23. }
  24.  
  25. /// <summary>
  26. /// 关闭监控
  27. /// </summary>
  28. public void Stop()
  29. {
  30. queue.ReceiveCompleted -= OnReceiveCompleted;
  31. StopListening();
  32. }
  33.  
  34. private void StartListening()
  35. {
  36. waiteHandle[] = queue.BeginReceive().AsyncWaitHandle;
  37. }
  38.  
  39. private void StopListening()
  40. {
  41. try
  42. {
  43. waiteHandle[].Close();
  44. }
  45. catch (Exception ex)
  46. {
  47. Log.Error("停止监控信号量异常1", ex);
  48. }
  49. }
  50.  
  51. private void FireRecieveEvent(object body)
  52. {
  53. if (MessageReceived != null)
  54. {
  55. MessageReceived(this, new MessageEventArgs(body));
  56. }
  57. }
  58.  
  59. private void OnReceiveCompleted(object sender, ReceiveCompletedEventArgs e)
  60. {
  61. try
  62. {
  63. var msg = queue.EndReceive(e.AsyncResult);
  64. msg.Formatter = new ActiveXMessageFormatter();
  65.  
  66. StartListening();
  67.  
  68. FireRecieveEvent(msg.Body);
  69. }
  70. catch (Exception ex)
  71. {
  72. Log.Error("OnReceive Error", ex);
  73. }
  74. }
  75. }
  76.  
  77. /// <summary>
  78. /// 消息接收事件
  79. /// </summary>
  80. /// <param name="sender"></param>
  81. /// <param name="args"></param>
  82. public delegate void MessageReceivedEventHandler(object sender, MessageEventArgs args);
  83.  
  84. /// <summary>
  85. /// 消息参数
  86. /// </summary>
  87. public class MessageEventArgs : EventArgs
  88. {
  89. private readonly object messageBody;
  90.  
  91. /// <summary>
  92. /// 消息体
  93. /// </summary>
  94. public object MessageBody
  95. {
  96. get { return messageBody; }
  97. }
  98.  
  99. /// <summary>
  100. /// 构造函数
  101. /// </summary>
  102. /// <param name="body">消息体</param>
  103. public MessageEventArgs(object body)
  104. {
  105. messageBody = body;
  106. }
  107. }

MSMQ消息队列的更多相关文章

  1. 微软MSMQ消息队列的使用

    首先在windows系统中安装MSMQ 一.MSMQ交互 开发基于消息的应用程序从队列开始.MSMQ包含四种队列类型: 外发队列:消息发送到目的地之前,用它来临时存储消息. 公共队列:在主动目录中公布 ...

  2. 【转】MSMQ消息队列安装

    一.Windows 7安装.管理消息队列1.安装消息队列   执行用户必须要有本地 Administrators 组中的成员身份,或等效身份.   具体步骤:    开始—>控制面板—>程 ...

  3. MSMQ消息队列安装

    一.Windows 7安装.管理消息队列1.安装消息队列   执行用户必须要有本地 Administrators 组中的成员身份,或等效身份.   具体步骤:    开始—>控制面板—>程 ...

  4. 【6】.net msmq消息队列实例

    1.msmq消息队列windows环境安装 控制面板---->程序和功能---->启用或关闭Windows程序---->Microsoft Message Queue(MSMQ)服务 ...

  5. MSMQ消息队列 用法

    引言 接下来的三篇文章是讨论有关企业分布式开发的文章,这三篇文章筹划了很长时间,文章的技术并不算新,但是文章中使用到的技术都是经过笔者研究实践后总结的,正所谓站在巨人的肩膀上,笔者并不是巨人,但也希望 ...

  6. WCF分布式开发必备知识(1):MSMQ消息队列

    本章我们来了解下MSMQ的基本概念和开发过程.MSMQ全称MicroSoft Message Queue,微软消息队列,是在多个不同应用之间实现相互通信的一种异步传输模式,相互通信的应用可以分布于同一 ...

  7. 跟我一起学WCF(1)——MSMQ消息队列

    一.引言 Windows Communication Foundation(WCF)是Microsoft为构建面向服务的应用程序而提供的统一编程模型,该服务模型提供了支持松散耦合和版本管理的序列化功能 ...

  8. C#实战Microsoft Messaging Queue(MSMQ)消息队列(干货)

    前言 在使用MSMQ之前,我们需要自行安装消息队列组件!(具体安装方法大家自己搜一下吧) 采用MSMQ带来的好处是:由于是异步通信,无论是发送方还是接收方都不用等待对方返回成功消息,就可以执行余下的代 ...

  9. (转)MSMQ(消息队列)

    原文作者:虔诚者    点此传送至原文   前段时间研究WCF接触到了MSMQ,所以认真的学习了一下,下面是我的笔记. 我理解的MSMQ MSMQ可以被看成一个数据储存装置,就如同数据库,只不过数据存 ...

随机推荐

  1. python多线程下载

    # -*- coding=utf-8 -*- import sys import os import os.path import time import urllib.request, urllib ...

  2. STM32学习笔记(三) STM32的GPIO的深入学习

    STM32的开发学习主要涉及软硬件两个部分的实现,包含众多外设和总线的理解配置.STM32的整个学习曲线并不陡峭,但入门却相当困难,因此在学习之初,多动手实验和测试相当重要,GPIO作为整个STM32 ...

  3. 使用js加载器动态加载外部Javascript文件

    原文:http://www.cnblogs.com/xdp-gacl/p/3927417.html 今天在网上找到了一个可以动态加载js文件的js加载器,具体代码如下: JsLoader.js var ...

  4. Java Date与SimpleDateFormat

    最近在弄一些涉及到时间处理的项目.本来自己写了一个时间转换函数,虽然能用但是过于麻烦而且不够规范,于是学习了下java自带的时间处理的类. public class Timechg { public ...

  5. Android_开发工具的下载和开发环境的搭建

    一.Android开发工具的下载  Android开发者官网: http://developer.android.com/           Android开发工具:http://www.andro ...

  6. IE, FireFox, Opera 浏览器支持CSS实现Alpha半透明的方法

    这个世界变化很快,IE8也快出来了,它将不在支持以前{filter:alpha(opacity=50);}的私有属性,转而支持更规范的私有属性-ms-filter: “progid:DXImageTr ...

  7. javascript算术运算符详解

    算术运算符 +.-.*./.%.++.-- ++.--分为前缀形式和后缀形式 前缀形式先加减1在执行 后缀形式先执行再加减1 注意 +号用来连接两个字符串 只要+连接的操作数中有一个是字符串型,JS就 ...

  8. association ,collection

    mybatis 出现这个错误Error creating document instance.  Cause: org.xml.sax.SAXParseException; lineNumber: 2 ...

  9. JSP HTML error code

    <html> <head> <title>Setting HTTP Status Code</title> </head> <body ...

  10. Java GC系列(4):垃圾回收监视和分析

    本文由 ImportNew - lomoxy 翻译自 javapapers. 目录 垃圾回收介绍 垃圾回收是如何工作的? 垃圾回收的类别 垃圾回收监视和分析 在这个Java GC系列教程中,让我们学习 ...