8

我在服务器 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 队列)。

4

5 回答 5

3

我相信,如果您在 MSMQ 服务器端使队列事务化,则需要在 WCF 绑定配置中指定更多设置 - 试试这个:

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

如果我没记错的话,您需要将durable="true"andexactlyOnce="true"属性添加到您的 netMsmq 绑定中才能正常工作。

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

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

exactOnce="true" 属性是 WCF 所说的,用于使用事务性消息队列。

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

更新:因为您要“跨越”机器边界,并且您正在使用事务队列 - 您是否检查了所有相关机器上的 DTC(分布式事务协调器)?查看 Tom 的博客第 3 部分:

检查 DTC 配置

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

于 2010-10-05T16:21:24.623 回答
1

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

MSMQ 消息属性

这样的消息在发送到 a 时会被接受,localhost但会被远程服务器拒绝。

为了使它工作,你有几个选择:

  1. 启用身份验证
  2. 授予匿名登录的发送权限

第一个选项当然更安全,但它需要与 Active Directory 集成一起安装 MSMQ。

于 2013-11-24T13:03:50.367 回答
0

在关闭通道之前尝试完成事务范围。

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

于 2010-10-05T16:00:01.523 回答
0

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

于 2010-10-11T16:20:32.913 回答
0

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

  1. 连接性:我想雷神 DNS 条目正在工作,不是吗?检查它是否使 ping...
  2. 跨不同域的权限:我在一些 sprint 前遇到了问题,原因是权限。我的测试本地机器与服务器位于不同的域中。检查 thor 和你的机器是否在同一个域中。可以跨域使用它,但我无法让它工作(所以我将测试移到同一域中的机器上)
  3. 队列工具:虽然您可以从管理工具中看到队列,但我发现队列浏览器工具 ( http://cogin.com/mq/index.php ) 非常有用。您可以检查消息卡在哪里。

注意:可能 1 是可以的,但以防万一我把它...

于 2010-10-06T12:22:08.053 回答