WCF MSMQ 4.0中的毒性消息处理

时间:2009-12-15 17:22:22

标签: wcf msmq

我正在尝试使用MSMQ传输处理WCF中的有害消息。

我按照以下链接创建原始和毒药服务。

http://msdn.microsoft.com/en-us/library/aa395218.aspx

唯一的区别是代替自托管,我在IIS中托管了2个服务,并且只有一个主机项目。

这两项服务的配置如下。

<services>
  <service behaviorConfiguration="MainMSMQWCFService.Service1Behavior"
    name="MainMSMQWCFService.OrderProcessorService">
    <endpoint address="net.msmq://localhost/private/servicemodelsamplespoison"
      binding="netMsmqBinding" bindingConfiguration="PoisonBinding"
      contract="MainMSMQWCFService.IOrderProcessor" />
  </service>
  <service behaviorConfiguration="MainMSMQWCFService.PoisonHandlingServiceBehavior"
    name="MainMSMQWCFService.PoisonHandlingService">
    <endpoint address="net.msmq://localhost/private/servicemodelsamplespoison;poison" 
              binding="netMsmqBinding"
              bindingConfiguration="PoisonBinding2"
              contract="MainMSMQWCFService.IOrderProcessor">
    </endpoint>
  </service>
</services>

两项服务都正常运行。

问题是当邮件被放入毒药队列时,毒药服务不处理该邮件。 我观察了Poison队列中的消息,它们仅针对原始服务。然后毒药服务如何处理它们?通过MSDN后,我知道通过设置服务行为属性,WCF通道会解决这个问题。以下几段解释相同。

“有害消息队列中的消息是发往处理消息的服务的消息,可能与有害消息服务端点不同。因此,当有害消息服务从队列中读取消息时,WCF通道层在端点中发现不匹配并且不调度消息。在这种情况下,消息被发送到订单处理服务但是被有害消息服务接收。即使消息被发送到,也要继续接收消息。在不同的端点,我们必须添加一个ServiceBehavior来过滤匹配条件匹配消息所针对的任何服务端点的地址。这是成功处理从有害消息队列中读取的消息所必需的。“

但是我的毒药服务没有处理中毒消息?

我无法弄清楚这个问题。

2 个答案:

答案 0 :(得分:4)

我有同样的问题。

我想知道是否因为在IIS中托管netMsmq服务时,队列名称必须与服务名称匹配。在初始消息队列的情况下,这是正常的(例如,队列将类似于private / SimpleService / Service1.svc),但是毒性队列被称为private / SimpleService / Service1.svc; poison,这显然不是匹配毒药服务名称。

我自己托管的样本工作正常。这个问题似乎只与IIS托管有关。

如果这是问题所在,我恐怕没有解决方案......

更新

来自

的评论

http://msdn.microsoft.com/en-us/library/ms789042(v=VS.90).aspx

表明问题与我想的一样:

“无法基于系统队列中的消息(例如系统范围的死信队列)或子队列(例如有毒子队列)激活WAS托管的应用程序。这是此版本的限制产品“

我认为不可能指定备用自定义毒药消息队列,因此备选方案是:

1)在服务实现中编写代码,以便在失败时将消息移动到备用队列 2)使用触发器将消息从病毒邮件队列传输到另一个队列,并让IIS托管服务监听该消息 3)在自定义EXE而不是IIS

中托管您的有害消息服务

答案 1 :(得分:2)

我最近遇到了IIS7。是的,默认情况下,WAS托管的应用程序不能处理毒性队列但是,我相信有一种方法可以在IIS中托管可以检测有害消息的WCF服务。我想到的方式是,有毒消息服务实际上是主要WCF服务的子服务,它依赖于主服务。为了在WCF中托管子服务,我实现了自定义ServiceHostFactory。在ServiceHostFactory中,我覆盖主服务主机的OnOpening和OnClosing事件,以打开和关闭有害消息服务。以下是示例代码:

public class HostFactory : ServiceHostFactory
{ 
    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
        SomeServiceHost host = new SomeServiceHost(serviceType, baseAddresses);
        host.PoisonMsmqServiceType = typeof(PoisonHandler);
        return host;
    }
}

public class SomeServiceHost : ServiceHost
{
    private ServiceHost poisonMsmqServiceHost;


    public Type PoisonMsmqServiceType { get; set; }

     public SomeServiceHost(Type serviceType, params Uri[] baseAddresses)
    : base(serviceType, baseAddresses) { }

    protected override void OnOpening()
    {
        base.OnOpening();

        if (this.PoisonMsmqServiceType != null)
        {
            this.poisonMsmqServiceHost = new ServiceHost(this.PoisonMsmqServiceType);
            this.poisonMsmqServiceHost.Open();
        }
    }

    protected override void OnClosing()
    {
        base.OnClosing();

        if (this.poisonMsmqServiceHost != null)
        {
            this.poisonMsmqServiceHost.Close();
            this.poisonMsmqServiceHost = null;
        }
    }
}

之后,只需设置工厂&#39;使用自定义主机工厂类对.svc文件进行属性处理,它应该为您处理有害消息处理。