1

让我首先声明这个问题与以下帖子非常相似:MSMQ messages received but not Delivered Windows 2008 R2。尽管如此,该帖子仍不清楚是什么解决了这个问题。

我的场景:

我有两个实体 A 和 B 都充当彼此的服务和客户。我还有另一个实体 C,它充当 B 的客户。

  1. A 向 B 发送一条消息,注册它的 URI。
  2. 在某些情况下,C 向 B 发送消息。
  3. 收到 C 的消息后,B 向 A 发送消息。

所有消息都在事务处理队列上发送。当我仅在 localhost(Windows 7 专业版)上运行上述场景时,一切都很好:所有消息都正确发送和接收。

现在问题出现在我的 Windows 7 pro 上的 A 和 C 的以下设置中。机器和 B 在 Windows Server 2012 R2 上。

对于第 1 步和第 2 步,一切正常:发送和接收消息。现在在 3 中,当 B 向 A 发送消息时,A 永远不会收到消息。MSMQ 的事件日志告诉我 B 确实发送了消息,而 A 的最后一个事件是:“消息来自网络”。

当我检查 B 上的 Transacted Dead Letter 队列时,我现在可以看到我的所有消息都有“无效签名”错误。从我收集的信息来看,这个错误似乎与身份验证问题有关,所以这是我在 A 的配置中所做的:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
  <appSettings>
    <!-- use appSetting to configure MSMQ queue name -->
    <add key="queueName" value=".\private$\MainOrchestrator/MainOrchestratorService" />
    <add key="ClientSettingsProvider.ServiceUri" value="" />
  </appSettings>
  <system.serviceModel>
    <services>
      <service name="MachineCommunication.Orchestrators.MainOrchestrator.MainService" behaviorConfiguration="DefaultBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:13000/" />
          </baseAddresses>
        </host>
        <!-- Define NetMsmqEndpoint -->
        <endpoint address="net.msmq://localhost/private/MainOrchestrator/MainOrchestratorService" binding="netMsmqBinding" bindingConfiguration="TransactedBinding" contract="MachineCommunication.Contracts.OrchestratorContracts.IOrchestratorService" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <client>
      <endpoint address="net.msmq://windowsserver2012address/private/Zeiss/ZeissAdapterService" binding="netMsmqBinding" bindingConfiguration="TransactedBinding" contract="IAdapterService" name="ZeissAdapter" />
    </client>
    <behaviors>
      <serviceBehaviors>
        <behavior name="DefaultBehavior">
          <serviceDebug includeExceptionDetailInFaults="true" />
          <serviceMetadata httpGetEnabled="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <netMsmqBinding>
        <binding name="TransactedBinding" deadLetterQueue="System" useActiveDirectory ="False">
          <security mode="None">
            <message clientCredentialType="None"/>            
            <transport msmqAuthenticationMode="None" msmqProtectionLevel="None"  />
          </security>          
        </binding>
      </netMsmqBinding>
    </bindings>
  </system.serviceModel>
</configuration>

我还按如下方式创建队列:

    MessageQueue queue;

    if (!MessageQueue.Exists(queueName))
    {
        queue = MessageQueue.Create(queueName, true);
        queue.Authenticate = false;

        queue.SetPermissions("ANONYMOUS LOGON",
            MessageQueueAccessRights.FullControl,
            AccessControlEntryType.Allow);
    }

然而,仍然存在“无效签名”问题。如果有人可以对此有所了解,

很多,非常感谢提前!

4

2 回答 2

3

找到了解决方案。大多数讨论交易死信队列中的“无效签名”错误的帖子或多或少地详细解释了它通常如何涉及接收端的权限问题(在这种情况下,是A的队列的安全配置)。就我而言,问题也出在发送端。即:

如果您收到“签名无效”错误,这意味着您的频道正在尝试发送经过身份验证的消息。

(资源)

为了完整起见,这是我当前对 A 的安全配置:

      <netMsmqBinding>
        <binding name="TransactedBinding" deadLetterQueue="System" useActiveDirectory ="False">
          <security mode="None">
            <message clientCredentialType="None"/>            
            <transport msmqAuthenticationMode="None" msmqProtectionLevel="None"  />
          </security>          
        </binding>
      </netMsmqBinding>

A 的服务端点使用以下方法引用此绑定:

<endpoint address="net.msmq://localhost/private/MainOrchestrator/MainOrchestratorService" binding="netMsmqBinding" bindingConfiguration="TransactedBinding" contract="MachineCommunication.Contracts.OrchestratorContracts.IOrchestratorService" />

虽然这一切都很好而且很花哨,但这还不够。

在 B 方面,我将消息发送给 a:

            NetMsmqBinding msmqCallbackBinding = new NetMsmqBinding();
            EndpointAddress epAddr = new EndpointAddress(client.clientUri);
            OrchestratorServiceClient orchestratorServiceClient = new OrchestratorServiceClient(msmqCallbackBinding, epAddr);                    

            using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
            {
                sendAction(orchestratorServiceClient);
                scope.Complete();
            }
            orchestratorServiceClient.Close();

问题在于 NetMsmqBinding。默认情况下,此绑定似乎尝试使用身份验证,这就是它失败的原因。更换:

NetMsmqBinding msmqCallbackBinding = new NetMsmqBinding();

和:

NetMsmqBinding msmqCallbackBinding = new NetMsmqBinding(NetMsmqSecurityMode.None);

修复了问题。

于 2014-08-26T14:20:44.527 回答
1

我试图添加评论,但我没有足够的“代表”。这不完全是一个答案,但我相信您的问题在于 MSDTC。

于 2014-08-26T02:44:15.150 回答