如何成功发布一个MSMQ的Windows服务

因为MSMQ的使用需要不断的查看队列是否有新消息,所以一般是结合Windows的服务,当然也可以用一个不关闭的Winform程序,不过前者更好一些,不怕被人误关。

完成MSMQ的WindowsService项目后,将服务项目添加到Windows 服务中。

①如果访问的是一个已经存在的队列,那么启动的时候会报错误【本地计算机上的XXXX服务启动后停止。某些服务在未由其他服务或程序使用时将自动停止】

这是因为没有分配权限。

 处理方法:右击要访问的队列 ->安全 

EveryoneANONYMOUS LOGON的完全控制分别勾选

 

②发送消息到远程队列

访问本地队列时,队列的路径格式及使用是这样子的

var mqPath = @".Private$MyMQ";
MessageQueue _MQ;
if (MessageQueue.Exists(mqPath))
{
    _MQ = new MessageQueue(mqPath);
}
else
{
    _MQ = MessageQueue.Create(mqPath);
}

  

访问远程队列时,代码略有不同:

1.远程队列的路径格式:string path = @"Formatname:DIRECT=tcp:192.168.1.11Private$myMQ";  关键字不区分大小写

2.MSMQ 判断队列是否存在的方法(MessageQueue.Exists(string path))和创建队列(MessageQueue.Create(string path)),都是不支持远程队列的。

  1.使用Exists方法会出现错误无法确定具有指定格式名的队列是否存在。

  2.使用Create方法会出现错误【无法创建路径为 FormatName:DIRECT=tcp:192.168.1.11Private$myMQ 的队列

  3.由于前两条的限制,如果要访问远程专用队列,则必须保证事先在远程机器上该队列是存在的。

var path = @"FormatName:DIRECT=tcp:192.168.1.11Private$myMQ"; 
MessageQueue mq = new MessageQueue(queuePath);

  4.当发送消息到远程队列时,系统会在本机的传出队列下创建一个临时队列,每发送一条消息,该消息都会先存在临时队列中,这样做的目的是防止因远程队列无法访问而丢失消息。

    不过要特别注意的是,如果远程机器不能成功连接,则消息就一直在临时队列中存放;如果能成功连接,即使要访问的队列并不存在,消息发送程序也不会报错,并且临时队列中的消息会删除。

    所以  一定要保证先在远程服务器上建好队列。传出队列具体信息如下图:

   5.如果事务型属性不匹配,消息将无法传递。系统不会返回任何错误,但该条消息却会丢掉。

 
原文地址:https://www.cnblogs.com/TiestoRay/p/5166525.html