0

私たちのチームは、( msmqIntegrationBindingを介して) WCF を使用して、複数のリモート MSMQ キューからのメッセージを処理するためのサービスを構築しています。通常消費するリソースの量に基づいて、 ( serviceThrottlingを介して) キューのさまざまなグループを調整する機能が必要です。

私の考えは、単一のサービス タイプで複数のキューからのメッセージを処理し、メッセージのタイプに基づいてメッセージの処理方法を決定することです。残念ながら、MsmqMessage<T>メッセージの正確なタイプを期待しているため、一般的な使用方法を理解できません。MsmqMessage<object>type のシリアライザーを見つけようとしていると思われるため、機能しません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 { }
4

1 に答える 1

1

この問題は、実際には によって引き起こされたものではありませんMsmqMessage<object>

キューに入れられたメッセージが XML 形式の場合、サービスは を使用して、ServiceKnownTypeAttributeサービスがサポートする XML (逆) シリアル化の型を判別します。この場合、object実際には有効なシリアル化可能な型ではないため、おそらく無視されました。

XML メッセージの一般的な処理をサポートするために[ServiceKnownType(typeof(XElement))]、サービス コントラクトに追加してMsmqMessage<object>、サービス メソッドの引数として受け入れることができます。これにより、オブジェクトのプロパティをチェックして、オブジェクトのMsmqMessage<T>処理方法を決定できます。別の可能なオプションは、メソッド パラメーターを受け入れるのオーバーロードを使用して、サポートされている型のリストを動的に作成することです。ServiceKnownTypeAttribute

私がチェックした唯一の他のシリアライゼーション形式Binaryは. 特に形式については、型情報がバイナリ ペイロードに含まれているためBinary、noは必要ありません (これは でのみテストされています)。形式を使用する場合は、実際のオブジェクト タイプが.ServiceKnownTypeAttributeSystem.GuidBinaryMsmqMessage<object>MsmqMessage<XElement>XElement

于 2015-10-15T17:09:00.393 に答える