Message Queue基本使用说明

一、安装Message Queue:

在Win7之前,控制面板,添加删除组件(Windows Message Queue)。

Win7~Win8:控制面板,程序和功能,启用或关闭Windows功能(找到Windows Message Queue服务器)选项,连同所有子类一并勾上即可,自动安装。

二、使用Message Queue:

1)用于各类服务器、计算机之间的通讯:

本地,自己给自己发(直接是.\\Private$\\Queue的私有名字)。

远程计算机:

FormatName:Direct=TCP:121.0.0.1\\private$\\Queue名字
FormatName:Direct=OS:machinename\\private$\\Queue名字 (仅用于远程加了域的计算机)。
FormatName:DIRECT=http://222.10.xx.xx/msmq/Private$/Queue名字

注意:FormatName必须大小写完全按照红色的写法!"Direct"可以随意。

2)默认情况下,Queue会收到该组全部信息。有时候我们需要跨域但是指定某台计算机收到特定信息(比如N台有1,2,3……N编号的计算机都连接到某个服务器Queue,但是不同计算机有唯一编号,我发送的信息只发送给特定的计算机编号)。那么可以使用System.Message(使用前必须引用该类库)的Label,代码如下(包含收到消息后删除该信息,防止Queue里东西越来越多):

此案例是在我本人计算机上运行,界面上一个“发送”按钮和2个文本框(分别接受Label为1和2的消息),防止时间演示过长,使用了异步机制。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Messaging;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Msg = System.Messaging.Message;

namespace MessageQueueDemo
{
    public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();
        }

        private async Task<string> GetMessage(string labelId)
        {
            List<Msg> msgs = new List<Msg>();
            //监听当前自己计算机上的私有队列
            MessageQueue msgQueue = new MessageQueue(@".\private$\myQueue");
            string result = null;
            Random r = new Random();

            await Task.Run(() =>
            {
                //使用该方法允许您动态删除Queue
                var me = msgQueue.GetMessageEnumerator2();
                Msg tmpMsg = null;

                for (IEnumerator pointer = me; pointer.MoveNext();)
                {
                    //先返回当前的Queue
                    tmpMsg = (Msg)pointer.Current;
                    //如果该Label是符合当前文本框可以接受的Id,删除该Msg
                    if (tmpMsg.Label == labelId)
                    {
                        tmpMsg = me.RemoveCurrent();
                        //模拟接收的时间不同
                        Thread.Sleep(r.Next(100, 500));
                        //必须指定每一个Msg的存储信息格式
                        tmpMsg.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });
                        msgs.Add(tmpMsg);
                        //必须加上去,因为删除当前的Msg之后不使用“重置”,导致MoveNext为false。
                        me.Reset();
                    }
                }
                if (msgs.Count > 0)
                {
                    result = string.Join(",", (from m in msgs
                                                   select m.Body.ToString()));
                }
            });
            return result;
        }

        private async void button1_Click(object sender, EventArgs e)
        {
            //初始化已经创建的Queue
            MessageQueue msgQueue = new MessageQueue(@".\private$\myQueue");
            //模拟发送Msg(1和2交替发送)
            for (int i = 1; i < 11; i++)
            {
                Msg message = new Msg(i % 2 == 0 ? "1" : "2", new XmlMessageFormatter(new Type[] { typeof(string) }));

//Send第一个参数:发送的消息对象;第二个参数:Label
                 msgQueue.Send(message, i % 2 == 0 ? "1" : "2");
            }

            //异步接收
            var content1 = await GetMessage("1");
            var content2 = await GetMessage("2");
            textBox2.Text = content1;
            textBox3.Text = content2;
        }
    }
}

 

posted @ 2015-07-22 20:37  Serviceboy  阅读(2506)  评论(0编辑  收藏  举报