简体   繁体   English

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

[英]WCF service inside an MVC-app that uses msmqIntegrationBinding does not receive messages from msmq

I have a MVC-app that has a controller with an action that is supposed to expose data from the latest message in a queue (msmq). 我有一个带有控制器的MVC应用程序,该控制器的操作应公开队列(msmq)中最新消息的数据。 I have added a private queue on my local machine. 我在本地计算机上添加了一个专用队列。 I want the application to automatically receive a message from the queue when one is added. 我希望应用程序在添加消息时自动从队列中接收消息。 For this i am using msmqIntegrationBinding on a WCF-service that has been added to the application. 为此,我在已添加到应用程序的WCF服务上使用msmqIntegrationBinding。 The method that takes the message in the contract i then supposed to save the message in the application cache so that it can be accessed when a client asks for the latest data. 然后,我应该在合同中采用消息的方法将消息保存在应用程序缓存中,以便在客户端请求最新数据时可以对其进行访问。

The challenge I now face is that when I add a message to the queue, it's not being picked up by the WCF-service. 我现在面临的挑战是,当我将消息添加到队列时,WCF服务不会接收该消息。 I need guidance at what I might be doing wrong or feedback on my approach. 对于我可能做错的事情,我需要指导,或者对我的方法需要反馈。 Please help. 请帮忙。

The following is the endpoint-config for the WCF-service: 以下是WCF服务的终结点配置:

<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>

And the following code is from the QueueMessageReceiver.cs WCF-service: 以下代码来自QueueMessageReceiver.cs WCF服务:

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);
    }
}

And here is the Interface for the WCF: 这是WCF的接口:

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

Try changing your operation contract to 尝试将您的运营合同更改为

void PutScrewInfoMessage(MsmqMessage<string> msg);

It's possible that the WCF stack is having difficulty with the deserialization to XmlDocument . WCF堆栈可能难以反序列化为XmlDocument

UPDATE 更新

Things to try: 尝试的事情:

  1. Make suer your queue "testsmessagequeue" have the correct permissions set. 使suer队列“ testsmessagequeue”具有正确的权限集。 In this case the service account running the app pool hosting your controller needs to have the "Receive Message" permissions set. 在这种情况下,运行托管您的控制器的应用程序池的服务帐户需要设置“接收消息”权限。

  2. Enable MSMQ logging (if you're on windows 2008 server or windows 7 and above) which can be found in Event Viewer under: Applications and Services Logs -> Microsoft -> Windows -> MSMQ -> End2End. 启用MSMQ日志记录(如果您使用的是Windows 2008 Server或Windows 7及更高版本),可以在“事件查看器”中的以下位置找到:应用程序和服务日志-> Microsoft-> Windows-> MSMQ-> End2End。 This will capture everything that happens in MSMQ including any errors. 这将捕获MSMQ中发生的一切,包括任何错误。

  3. Try making the queue transactional (if it not already). 尝试使队列具有事务性(如果尚未)。 This will ensure that an error condition will exist on message non-delivery. 这将确保在未送达邮件时存在错误情况。

  4. Enable WCF tracing on your service endpoint to see any specific WCF errors happening with the dequeuing of the message. 在服务端点上启用WCF跟踪,以查看消息出队时发生的任何特定WCF错误。

UPDATE 2 更新2

I think the problem is queue permissions. 我认为问题是队列权限。 Your app pool is running under the user ApplicationPoolIdentity (if it's running under the .net 4.0 app pool). 您的应用程序池在用户ApplicationPoolIdentity下运行(如果它在.net 4.0应用程序池下运行)。 The user which corresponds to this identity is called DefaultAppPool . 与此身份对应的用户称为DefaultAppPool You need to give this user receive message permissions on the queue. 您需要授予该用户队列接收消息的权限。 To select this user search for a local account called IIS AppPool\\DefaultAppPool in the Select Users dialogue. 若要选择此用户,请在“选择用户”对话框中搜索名为IIS AppPool \\ DefaultAppPool的本地帐户。

在此处输入图片说明

UPDATE 3 更新3

It just struck me that IIS is not an appropriate hosting container for a queue listener. 令我惊讶的是,IIS不是队列侦听器的合适宿主容器。 The reason for this is that the app pool unloads after a period of inactivity. 原因是在一段时间不活动后,应用程序池将卸载。 This is controlled by IIS and is not configurable. 这是由IIS控制的,并且不可配置。 (see here ) (请参阅此处

I think you should create a new hosting container in a windows service (you can use a console host to spike this) to host the queue endpoint. 我认为您应该在Windows服务中创建一个新的托管容器(您可以使用控制台主机来添加它)来托管队列终结点。 The windows service will run under an actual service account so granting permissions will be less complicated. Windows服务将在实际的服务帐户下运行,因此授予权限将变得不那么复杂。

This service can write either write directly into the cache, or if this is not possible, should write to a DB where the website controller can refresh the cache from. 此服务可以直接将写入写入高速缓存,或者如果不可能,则应写入数据库,网站控制器可以从中刷新高速缓存。

Does this make sense? 这有意义吗?

UPDATE 4 更新4

Poison message means that the message cannot be dequeued because of some problem with it. 毒消息表示由于某些问题而无法使该消息出队。 Check the system queue called Transactional Dead Letter Queue and see if your message is in there. 检查称为事务性死信队列的系统队列,并查看您的消息是否在其中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM