【问题标题】:MSMQ, Message is put on queue and disapears but is never picked up by service contractMSMQ,消息被放入队列并消失,但从未被服务合同拾取
【发布时间】:2012-07-23 14:42:56
【问题描述】:

我有一个本地私人队列。我在 MVC 应用程序中还有一个 WCF 服务,它使用 msmqIntegrationBinding 侦听队列。问题是,当消息排队时,服务合同永远不会被调用,但消息在之后的那一刻就消失了。邮件不在有害队列中。这是我声明绑定到队列的配置部分:

<services>
  <service name="SkruvInfo.Web.Service.QueueMessageReceiver">
    <endpoint address="msmq.formatname:DIRECT=OS:LEIA\private$\screwinfo_autotests_messagequeue"
                      binding="msmqIntegrationBinding"
                      bindingConfiguration="MsmqBinding"
                      contract="SkruvInfo.Web.Service.IQueueMessageReceiver" />
  </service>
</services>

这是合同:

[ServiceContract(Namespace = "http://localhost/SkruvWeb/Service")]
public interface IQueueMessageReceiver
{
    [OperationContract(IsOneWay = true, Action = "*")]
    void PutScrewInfoMessage(MsmqMessage<string> msg);
}

这是服务中的方法:

    [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
    public void PutScrewInfoMessage(System.ServiceModel.MsmqIntegration.MsmqMessage<string> msg)
    {
        log4net.Config.XmlConfigurator.Configure();
        var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        try
        {
            log.Debug("Message from queue: " + msg.Body.ToString(CultureInfo.InvariantCulture));
            var xDoc = new XmlDocument();
            xDoc.LoadXml(msg.Body);
            CacheScrewInfoModelFromScrewInfoXmlDoc(xDoc);
        }
        catch (Exception e)
        {
            log.Error("Error parsing message from queue",e);
            EventLog.WriteEntry("Application","Message error for screws");
        }
    }

关于为什么消息消失但不调用服务的任何建议?

【问题讨论】:

  • 作为一个有趣的问题,你为什么使用 MsmqIntegrationBinding?您的队列客户端是否在旧平台上?

标签: c# asp.net-mvc wcf msmq msmqintegrationbinding


【解决方案1】:

尝试使用 ServiceKnownType 属性修改您的服务合同:

[ServiceContract(Namespace = "http://localhost/SkruvWeb/Service")]
[ServiceKnownType(typeof(String))]
public interface IQueueMessageReceiver
{
    [OperationContract(IsOneWay = true, Action = "*")]
    void PutScrewInfoMessage(MsmqMessage<string> msg);
}

更新

如果您使用的是 MsmqIntegrationBinding,我假设您的队列客户端是像 VB6 客户端这样的旧版应用程序?如果是这样,您将需要在服务绑定配置中指定序列化格式。例如:

  <msmqIntegrationBinding>
    <binding name="MsmqBinding" serializationFormat="ActiveX">
      <security mode="None" />
    </binding>
  </msmqIntegrationBinding>

允许的值记录在here

【讨论】:

  • 我尝试了你建议的两件事,但它不起作用。
  • 您是否出于某种原因使用集成绑定?
  • 是的,所以当消息到达后台队列时服务会自动接收。我这样说不对吗?
  • 你为什么不使用 netMsmqBinding?这是 MSMQ 的标准 WCF 绑定。然后您不再需要使用 MsmqMessage 类型作为您的数据协定。 MsmqIntergationBinding 适用于您有非 WCF 客户端时
  • 那么你们msmq队列客户端使用的是什么技术平台?
【解决方案2】:

根据我的经验,这种行为是由序列化失败或消息过大(64KB 是默认的最大消息大小)引起的。这会导致 WCF 崩溃静默(是的,我也不明白这种设计选择),但仍会从队列中删除消息。

只需启用跟踪,您将很快在 WCF 中看到导致此问题的异常。

将此添加到您的 web.config(我在 下方)以进行粗略的跟踪设置。确保 AppPool 用户对日志文件夹具有写入权限。

<system.diagnostics>
    <trace autoflush="true" indentsize="4" />
    <sources>
      <source name="System.ServiceModel" switchValue="Warning">
        <listeners>
          <add name="textLogger" />
        </listeners>
      </source>
    </sources>
    <sharedListeners>
      <add name="textLogger"
           type="System.Diagnostics.TextWriterTraceListener"
           initializeData="C:\logs\webbackend_wcf_log.txt" />
</system.diagnostics>

【讨论】:

    猜你喜欢
    • 2012-05-22
    • 1970-01-01
    • 2013-12-31
    • 1970-01-01
    • 2017-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多