为什么排队的WCF消息会以静默方式消失?

时间:2010-10-05 15:55:53

标签: c# .net wcf msmq netmsmqbinding

我在服务器THOR上设置了事务性MSMQ队列。我可以使用以下代码从工作站发送消息到该队列:

var queue = new MessageQueue("FormatName:Direct=OS:thor\\private\\myqueue");
using (var tx = new MessageQueueTransaction())
{
   tx.Begin();
   queue.Send("test", tx);
   tx.Commit();
}

但是,当我尝试使用WCF进行连接时,我的消息永远不会出现在队列中。这是我正在使用的配置:

<system.serviceModel>
  <bindings>
    <netMsmqBinding>
      <binding name="ClientNewsFeedServiceBinding" durable="true" exactlyOnce="true">
        <security mode="None" />
      </binding>
    </netMsmqBinding>
  </bindings>

  <client>
    <!-- NewsFeed Service -->
    <endpoint name="INewsFeedService"
              address="net.msmq://thor/private/myqueue"
              binding="netMsmqBinding"
              bindingConfiguration="ClientNewsFeedServiceBinding"
              contract="Service.Contract.INewsFeedService" />
  </client>
</system.serviceModel>

代码:

using (var tx = new TransactionScope())
{
   var cf = new ChannelFactory<INewsFeedService>("INewsFeedService");
   var service = cf.CreateChannel();
   service.TestMessage("test");
   ((IChannel)service).Close();
   tx.Complete();
}

我没有任何例外,但是在THOR队列上没有发布消息。有任何想法吗?我甚至不知道如何调试它,因为它只是默默地失败。

更新

如果我将我的MSMQ URI更改为'net.msmq:// localhost / private / myqueue',那么它将发布到我已设置的本地事务队列。队列本身的设置是相同的(例如,我执行相同的步骤来创建localhost和THOR队列)。

5 个答案:

答案 0 :(得分:3)

我相信如果你在MSMQ服务器端进行队列事务处理,你需要在WCF绑定配置中指定更多设置 - 试试这个:

<bindings>
    <netMsmqBinding>
      <binding name="ClientNewsFeedServiceBinding" 
               durable="true" exactlyOnce="true">
        <security mode="None" />
      </binding>
    </netMsmqBinding>
  </bindings>

如果我没有弄错的话,您需要将durable="true"exactlyOnce="true"属性添加到netMsmq绑定中才能使其生效。

有一个关于如何让MSMQ和WCF很好地协同工作的非常好的教程:

Tom在第3部分中介绍了事务队列,并提到:

  

exactOnce =“true”属性是   WCF代表使用交易   消息队列。

durable=true仅表示将消息立即刷新到磁盘,而不是将它们保存在服务器内存中。它速度较慢,但​​在服务器崩溃或电源中断的情况下,消息不会丢失。经典的速度与可靠性权衡......

更新,因为您正在“越过”机器边界,并且您正在使用事务性队列 - 您是否检查过所有涉及的计算机上的DTC(分布式事务处理协调器)?查看Tom的博客第3部分:

  

检查DTC配置

     

我们的史诗般的旅程即将结束。   事实上,如果你还在玩   在家里,你可以尝试运行   应用程序与事务   排队看看它是否正常工作。 如果是的话   失败,一个可能的原因是   您的分布式问题   事务协调器配置。   以下是一些尝试:

答案 1 :(得分:1)

我遇到了同样的问题。在尝试了这里列出的所有想法后,我开始寻找其他的东西。事实证明,当您选择安全模式时,我的发件人属性消息为空(请参见下图)。

MSMQ Message properties

当此消息发送到localhost时将被接受,但远程服务器将拒绝该消息。

为了让它运作起来,你几乎没有选择:

  1. 启用身份验证
  2. 发送权限授予 ANONYMOUS LOGON
  3. 第一个选项当然更安全,但它需要使用Active Directory集成安装MSMQ。

答案 2 :(得分:0)

在关闭频道之前尝试完成交易范围。

当您关闭频道时,您失去了与它的联系,因此它有一个未提交的事务,最终会被丢弃。

答案 3 :(得分:0)

我有类似的问题,所以我希望这份清单有帮助:

  1. 连接性:我认为托管DNS入口正常,不是吗?检查它是否能ping ...
  2. 跨不同域的权限:我之前遇到过一些sprint问题,原因是权限。我的测试本地计算机与服务器位于不同的域中。检查Thor和您的机器是否在同一个域中。可以在域中使用它,但我无法使其工作(所以我将测试移到同一域中的计算机上)
  3. 队列工具:虽然您可以从管理工具中看到队列,但我发现队列资源管理器工具(http://cogin.com/mq/index.php)非常有用。您可以查看消息卡在哪里。
  4. 注意:可能1是可以的,但就我说的那样......

答案 4 :(得分:0)

您需要使用MsmqIntegrationBinding。由于WCF不知道它们是什么,因此消息未被识别并被丢弃。