使用msmqIntegrationBinding的MVC应用程序内的WCF服务不会从msmq接收消息

时间:2012-07-24 08:35:14

标签: wcf msmq

我有一个MVC应用程序,其控制器的动作应该是从队列中的最新消息(msmq)中公开数据。我在本地计算机上添加了一个专用队列。我希望应用程序在添加一个消息时自动从队列中接收消息。为此,我在已添加到应用程序的WCF服务上使用msmqIntegrationBinding。接收合同中消息的方法然后应该将消息保存在应用程序缓存中,以便在客户端请求最新数据时访问它。

我现在面临的挑战是,当我向队列添加消息时,它不被WCF服务接收。我需要指导我可能做错了什么或反馈我的方法。请帮忙。

以下是WCF服务的endpoint-config:

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

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

以下代码来自QueueMessageReceiver.cs WCF-service:

public class QueueMessageReceiver : IQueueMessageReceiver
{
    private static readonly XmlSerializer Serializer = new XmlSerializer(typeof(ScrewInfoModel));

    [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
    public void PutScrewInfoMessage(System.ServiceModel.MsmqIntegration.MsmqMessage<System.Xml.XmlDocument> msg)
    {
        CacheScrewInfoModelFromScrewInfoXmlDoc(msg.Body);
    }

    private static void CacheScrewInfoModelFromScrewInfoXmlDoc(XmlNode screwInfoXmlDoc)
    {
        var reader = new StringReader(screwInfoXmlDoc.InnerXml);
        var screwInfoModel = (ScrewInfoModel)Serializer.Deserialize(reader);
        Common.Utils.CacheScrewInfo(screwInfoModel);
    }
}

这是WCF的接口:

[ServiceContract]
public interface IQueueMessageReceiver
{
    [OperationContract(IsOneWay = true, Action = "*")]
    void PutScrewInfoMessage(MsmqMessage<XmlDocument> msg);
}

1 个答案:

答案 0 :(得分:0)

尝试将操作合同更改为

void PutScrewInfoMessage(MsmqMessage<string> msg);

WCF堆栈可能难以反序列化为XmlDocument

<强>更新

要尝试的事情:

  1. 让你的队列“testsmessagequeue”具有正确的权限集。在这种情况下,运行托管控制器的应用程序池的服务帐户需要设置“接收消息”权限。

  2. 启用MSMQ日志记录(如果您使用的是Windows 2008服务器或Windows 7及更高版本),可以在事件查看器中找到:应用程序和服务日志 - &gt;微软 - &gt; Windows - &gt; MSMQ - &gt;端到端。这将捕获MSMQ中发生的所有事情,包括任何错误。

  3. 尝试使队列具有事务性(如果尚未)。这将确保消息未送达时存在错误情况。

  4. 在服务端点上启用WCF跟踪,以查看消息出列时发生的任何特定WCF错误。

  5. 更新2

    我认为问题是队列权限。您的应用程序池在用户 ApplicationPoolIdentity 下运行(如果它在.net 4.0应用程序池下运行)。与此标识对应的用户称为 DefaultAppPool 。您需要为此用户提供队列上的消息权限。要选择此用户,请在“选择用户”对话框中搜索名为 IIS AppPool \ DefaultAppPool 的本地帐户。

    enter image description here

    更新3

    让我感到震惊的是,IIS不是队列侦听器的适当托管容器。原因是应用程序池在一段时间不活动后卸载。这由IIS控制,不可配置。 (见here

    我认为您应该在Windows服务中创建一个新的托管容器(您可以使用控制台主机来加密它)来托管队列端点。 Windows服务将在实际的服务帐户下运行,因此授予权限将不那么复杂。

    此服务可以直接写入缓存,或者如果不可能,则应写入网站控制器可以刷新缓存的数据库。

    这有意义吗?

    更新4

    毒药消息表示由于某些问题,该消息无法出列。检查名为Transactional Dead Letter Queue的系统队列,看看你的消息是否在那里。

相关问题