具有 MSMQIntegrationBinding 的 WCF 不会从队列中获取消息
-
21-09-2019 - |
题
我有一个 BizTalk 2006 应用程序,它有一个使用 MSMQ 的发送端口。
我还有一个带有多个 WCF 服务的 WCF winforms 托管应用程序(在开发环境中,在生产中我使用 Windows 服务作为托管)。
我创建的 WCF 服务之一具有 MSMQIntegrationBinding(由于 BizTalk 不是 WCF 服务,因此不可能使用 NetMSMQBinding)。
我看到该消息已正确放置在远程队列上,因为我激活了日志选项,并且在日志队列中看到该消息,但该队列为空,并且 WCF 服务未拾取该消息。
有人可以告诉我在哪里可以解决这个问题吗?
(编辑1):我对这个主题做了一些更多的研究:
- 当使用 MSMQ 与 BizTalk 2006 R2 进行通信时,您必须使用 MSMQIntegrationBinding,因为 NetMSMQBinding 仅适用于 WCF 到 WCF
- 所以我坚持使用 MSMQIntegrationBinding
- MSMQIntegration 绑定不使用 DataContract 序列化程序。相反,它根据 MsmqMessageSerializationFormat 属性序列化数据。它的默认值是 MsmqMessageSerializationFormat.Xml,这意味着将使用 XmlSerializer。其背后的基本原理是 msmq 集成传输是专门为与本机 MSMQ / System.Messaging 应用程序进行互操作而设计的
- 由于 MSMQIntegration 绑定使用普通的旧式 XmlSerializer,因此我无法轻松使用 svcutil.exe 生成数据类。所以我必须手动创建我的数据合约类....pffffffffffff
(参考: http://social.msdn.microsoft.com/Forums/en/wcf/thread/2d48fe90-5c2a-4156-8a3f-2e21d5638fa1 和 http://www.danrigsby.com/blog/index.php/2008/03/07/xmlserializer-vs-datacontractserializer-serialization-in-wcf/)
(编辑2):
我检查了来自 WCF 服务的诊断跟踪数据,并且由于反序列化异常,消息被丢弃。现在唯一的解决方案是手动创建数据契约类......
(编辑3):通过使用 xsd.exe 工具而不是 svcutil.exe 我创建了数据契约类,因此这里没有手工工作;-) 因此结论是使用 xsd.exe 来作为 WCF 服务方法中的参数使用的数据契约类。这是因为 MSMQIntegrationBinding 强制您使用 XMLSerializer 而不是默认的 DataContractSerializer 将所有数据协定类型设为可序列化。
解决方案
您可能想尝试启用 WCF 跟踪。
它可以帮助您了解正在发生的事情以及未发生的事情。
下面是一个 .config
启用跟踪的示例。确保 .config
文件位于 WCF 服务主机的同一文件夹中。
<configuration>
<system.diagnostics>
<sources>
<source name="System.ServiceModel" switchValue="Warning"
propagateActivity="true" >
<listeners>
<add name="xml"/>
</listeners>
</source>
<source name="myUserTraceSource" switchValue="Warning, ActivityTracing">
<listeners>
<add name="xml"/>
</listeners>
</source>
</sources>
<sharedListeners>
<add name="xml"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="C:\trace_logs\TraceLog.svclog" />
</sharedListeners>
</system.diagnostics>
</configuration>
微软提供了一个 服务跟踪查看器工具 读取 .svclog 文件。
确保路径在 initializeData
您的服务可写。
其他提示
这里首先要检查的是WCF服务的权限。与消息队列的连接是否由允许连接到消息队列的帐户完成。
也可能是配置错误,您的连接配置是否正确?
检查事件日志,那里可能有错误,这将为您指明正确的方向。
您是否已验证该消息是否确实由 WCF 服务留在队列中,或者是否已被拾取并删除但未被 WCF 处理?
我想尝试的是将处理程序附加到 收到未知消息 ServiceHost 实例中的事件并查看在拾取消息时是否触发该事件...这肯定表明您的服务合同定义不正确(可能您需要使用 catch all:
[OperationContract(Action="*")]
确保它正确路由到您的方法。