2015-10-15 89 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

相關問題