C# 为什么我排队的WCF消息会悄悄消失?

C# 为什么我排队的WCF消息会悄悄消失?,c#,.net,wcf,msmq,netmsmqbinding,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连接时,我

我在服务器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();
}
使用(var tx=new TransactionScope())
{
var cf=新的ChannelFactory(“INewsFeedService”);
var service=cf.CreateChannel();
TestMessage(“test”);
((IChannel)服务).Close();
tx.Complete();
}
我没有任何例外,但在THOR的队列上没有张贴任何消息。有什么想法吗?我甚至不知道如何调试它,因为它只是默默地失败了

更新


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

在关闭通道之前,请尝试完成TransAction作用域


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

我认为,如果您在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部分中介绍了事务队列,并提到:

exactlyOnce=“true”属性为 WCF支持使用事务性 消息队列

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

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

检查DTC配置

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


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

  • 连接性:我想thor DNS条目正在工作,不是吗?检查它是否使ping
  • 跨不同域的权限:我在一些sprint中遇到了问题,原因是权限。我的测试本地计算机与服务器位于不同的域中。检查thor和您的机器是否在同一个域中。可以让它跨域访问,但我无法让它工作(因此我将测试移到同一域中的计算机上)
  • 队列工具:虽然您可以从管理工具中看到队列,但我发现队列资源管理器工具()非常有用。您可以检查消息在哪里被卡住
    注意:可能1是可以的,但就我所说的情况而言…

    您需要使用MsmqIntegrationBinding。由于WCF不知道这些消息是什么,因此无法识别这些消息并将其丢弃。

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

    此类消息发送到
    本地主机时将被接受,但远程服务器将拒绝该消息

    为了使其正常工作,您几乎没有选择:

  • 启用身份验证
  • 匿名登录授予发送权限

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

    这些消息是否显示在事务死信队列中?否,事务性DLQ更新我的答案中没有显示任何消息-您是否检查了所有相关机器上的DTC?这些机器不工作。你说的有道理,但似乎没有什么不同。试过了,不行。我在我的原始帖子中添加了一个更新,说如果我将MSMQ URI更新为指向localhost而不是THOR,我就可以运行WCF代码。我认为MsmqIntegrationBinding用于WCF应用程序和非WCF应用程序之间的交互。我手动向队列添加内容的示例代码只是为了说明这不是一个简单的“关闭防火墙”问题。在生产中,队列将仅由WCF服务访问。对不起,第二个客户端跳过了我的眼睛。客户端是XP机器吗?我们在XP中遇到了Kerberos问题。它有一个补丁。不确定WCF,但这解决了我在NServiceBus和MSMQ向另一台机器发送消息时遇到的类似问题,并让它们安静地删除。向队列添加“匿名登录”权限修复了它(即使我已经拥有“所有人”的完全控制权!)