0

我们的团队正在构建一个服务,用于使用 WCF(通过msmqIntegrationBinding)处理来自多个远程 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具体的格式,ServiceKnownTypeAttribute不需要,因为类型信息包含在二进制有效负载中(仅用 测试过System.Guid)。如果您打算使用该Binary格式,重要的是您继续使用MsmqMessage<object>而不是MsmqMessage<XElement>因为实际的对象类型将通过而不是XElement.

于 2015-10-15T17:09:00.393 回答