1

我在远程机器上有一个名为 log 的队列。当我在本地调用该队列时,我通过修改我的 NetMsmqBinding 来指定一个自定义死信队列:

_binding.DeadLetterQueue = DeadLetterQueue.Custom;
_binding.CustomDeadLetterQueue = new Uri(
    "net.msmq://localhost/private/Services/Logging/LogDeadLetterService.svc");

这很好用;当我强制我的消息无法到达其目的地时,它会出现在此队列中。

现在,我有一个托管在 IIS/WAS 中的服务来读取死信队列。它托管在一个名为 Services 的站点中,位于 Services/Logging/LogDeadLetterService.svc。这是我的配置中的服务:

  <service name="Me.Logging.Service.LoggingDeadLetterService">
    <endpoint binding="netMsmqBinding"
              bindingNamespace="http://me.logging/services/2012/11"
              contract="Me.Logging.Service.Shared.Service.Contracts.ILog" />
  </service>

这是我的激活:

    <add relativeAddress="LogDeadLetterService.svc"
         service="Me.Logging.Service.LoggingDeadLetterService" />

我的实际服务基本上是这样的:

[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any, // Pick up any messages, regardless of To address.
                 InstanceContextMode = InstanceContextMode.Single, // Singleton instance of this class.
                 ConcurrencyMode = ConcurrencyMode.Multiple, // Multiple callers at a time.
                 Namespace = "http://me.logging/services/2012/11")]
public class LoggingDeadLetterService : ILog
{
    public void LogApplication(ApplicationLog entry)
    {
        LogToEventLog(entry);
    }
}

我的队列是事务性的和经过身份验证的。我在服务站点和日志记录应用程序上都将 net.msmq 作为启用的协议包含在内,并且我将 net.msmq 绑定添加到服务站点。如果绑定信息为,则在浏览http://appdev.me.com/Logging/LogDeadLetterService.svcappdev.me.com时出现以下错误(appdev.me.com 在我的 HOSTS 文件中设置):

An error occurred while opening the queue:Access is denied. (-1072824283, 0xc00e0025).

如果我的绑定信息为localhost,则会收到以下错误:

An error occurred while opening the queue:The queue does not exist or you do not have sufficient permissions to perform the operation. (-1072824317, 0xc00e0003).

无论我设置哪种方式,服务都不会收到死信,因为它仍在队列中,而不是在我的事件日志中。

现在,我意识到这两个都引用了权限问题。但是,为了在确定身份验证部分之前测试此代码部分,我已将完全控制权授予我能想到的每个人 - 包括所有人、经过身份验证的用户、网络服务、IIS_USERS、匿名登录和我自己。(应用程序池以我的身份运行。)

关于如何让我的服务能够从这个队列中拉出的任何帮助都将是惊人的。谢谢!

编辑: 根据这个 MSDN 博客条目,0xC00E0003 对应于 MQ_ERROR_QUEUE_NOT_FOUND,而 0xc00e0025 对应于 MQ_ERROR_ACCESS_DENIED,所以看起来我希望绑定信息为appdev.me.com. 但是,这仍然不能解决发生的明显权限问题。

EDIT2: 如果我在控制台应用程序中托管服务并提供以下端点,它就可以工作:

    <endpoint address="net.msmq://localhost/private/Services/Logging/LogDeadLetterService.svc"
              binding="netMsmqBinding"
              bindingNamespace="http://me.logging/services/2012/11"
              contract="Me.Logging.Service.Shared.Service.Contracts.ILog" />

那么控制台应用程序中的情况与 IIS 中的情况有何不同?由于上面的编辑,我非常有信心我正在排队。那我为什么进不去呢?

EDIT3:根据此处给出的建议将 Services/Logging/LogDeadLetterService.svc 更改为 Logging/LogDeadLetterService.svc ,但没有变化。

//

[额外问题:我需要处理死信队列中的有害消息吗?]

4

1 回答 1

1

因此,需要改变三件事:

  1. 绑定确实必须是localhost.
  2. 必须命名队列Logging/LogDeadLetterService.svc才能找到 - 它是应用程序和服务,而不是站点、应用程序和服务。
  3. 我的应用程序池出了点问题——我不知道它是什么,但是使用不同的应用程序池可以工作,所以我取消了所有与服务相关的更改,然后重新创建了所有内容,并且它可以工作。

好吧,为了“不要弄乱你的应用程序池”这样简单的事情,我的头撞到了我的办公桌上。

于 2012-12-04T21:42:21.603 回答