2015-10-15 116 views
0

我们的团队正在构建一个服务,用于使用WCF处理来自多个远程MSMQ队列的消息(通过msmqIntegrationBinding)。我们希望能够根据它们通常消耗的资源数量来限制不同的队列组(通过serviceThrottling)。是否有可能拥有处理多个MSMQ端点的通用WCF服务?

我的想法是有一个服务类型处理来自多个队列的消息,并根据消息的类型确定如何处理它们。不幸的是,我不能找出使用MsmqMessage<T>的通用方法,因为它期望确切的消息类型。 MsmqMessage<object>不起作用,因为我认为它试图找到类型为object的串行器。

关于如何获得这项工作或其他方法的任何想法?由于已经内置了死信处理,所以最好还是使用WCF。

示例配置:

<services> 
    <service name="MessageProcessor.LowResourceMsmqReceiverService" behaviorConfiguration="LowResourceMsmqServiceBehavior"> 
     <endpoint address="msmq.formatname:DIRECT=OS:.\private$\EmailQueue" binding="msmqIntegrationBinding" bindingConfiguration="IncomingMessageBinding" contract="MessageProcessor.IMsmqReceiverService" /> 
     <endpoint address="msmq.formatname:DIRECT=OS:.\private$\LoggingQueue" binding="msmqIntegrationBinding" bindingConfiguration="IncomingMessageBinding" contract="MessageProcessor.IMsmqReceiverService" /> 
    </service> 
    <service name="MessageProcessor.HighResourceMsmqReceiverService" behaviorConfiguration="HighResourceMsmqServiceBehavior"> 
     <endpoint address="msmq.formatname:DIRECT=OS:.\private$\DataImportQueue" binding="msmqIntegrationBinding" bindingConfiguration="IncomingMessageBinding" contract="MessageProcessor.IMsmqReceiverService" /> 
     <endpoint address="msmq.formatname:DIRECT=OS:.\private$\DataExportQueue" binding="msmqIntegrationBinding" bindingConfiguration="IncomingMessageBinding" contract="MessageProcessor.IMsmqReceiverService" /> 
    </service> 
</services> 
<behaviors> 
    <serviceBehaviors> 
     <behavior name="LowResourceMsmqServiceBehavior"> 
      <serviceThrottling maxConcurrentCalls="50" /> 
     </behavior> 
     <behavior name="HighResourceMsmqServiceBehavior"> 
      <serviceThrottling maxConcurrentCalls="3" /> 
     </behavior> 
    </serviceBehaviors> 
</behaviors> 

例合同:

[ServiceContract] 
[ServiceKnownType(typeof(object))] 
public interface IMsmqReceiverService 
{ 
    [OperationContract(IsOneWay = true, Action = "*")] 
    void Receive(MsmqMessage<object> message); 
} 

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single, InstanceContextMode = InstanceContextMode.PerCall)] 
public abstract class TransactionalMsmqReceiverService : IMsmqReceiverService 
{ 
    [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)] 
    [TransactionFlow(TransactionFlowOption.Allowed)] 
    public void Receive(MsmqMessage<object> message) 
    { 
     // TODO: Handle multiple message types here 
    } 
} 

public sealed class LowResourceMsmqReceiverService : TransactionalMsmqReceiverService { } 

public sealed class HighResourceMsmqReceiverService : TransactionalMsmqReceiverService { } 

回答

1

这个问题是不是由MsmqMessage<object>引起的。

当排队的消息为XML格式时,服务使用ServiceKnownTypeAttribute来确定服务支持XML(反)序列化的类型。在这种情况下,object不是真正有效的可序列化类型,因此可能被忽略。

为了支持XML消息的一般处理,您可以将[ServiceKnownType(typeof(XElement))]添加到您的服务合同中,并接受MsmqMessage<object>作为您的服务方法的参数。这将允许您检查MsmqMessage<T>对象的属性以确定它应该如何处理。另一种可能的选择是使用接受方法参数的ServiceKnownTypeAttributeoverload来动态构建您支持的类型的列表。

唯一其他serialization format我检查了Binary,所以请记住,它们都可能处理不同。特别是对于Binary格式,由于类型信息包含在二进制有效负载中,因此不需要ServiceKnownTypeAttribute(仅在System.Guid中进行了测试)。如果您打算使用Binary格式,则必须继续使用MsmqMessage<object>而非MsmqMessage<XElement>,因为实际的对象类型将通过而不是XElement

相关问题