我正在尝试使用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来过滤匹配条件匹配消息所针对的任何服务端点的地址。这是成功处理从有害消息队列中读取的消息所必需的。“
但是我的毒药服务没有处理中毒消息?
我无法弄清楚这个问题。
答案 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文件进行属性处理,它应该为您处理有害消息处理。