繁体   English   中英

是否可以使用通用WCF服务来处理多个MSMQ端点?

[英]Is it possible to have a generic WCF service for handling multiple MSMQ endpoints?

我们的团队正在构建一项服务,以使用WCF(通过msmqIntegrationBinding )处理来自多个远程MSMQ队列的消息。 我们希望有能力根据通常消耗的资源量来限制不同的队列组(通过serviceThrottling )。

我的想法是让一个服务类型处理来自多个队列的消息,并根据消息的类型确定如何处理它们。 不幸的是,我无法确定使用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 { }

该问题实际上不是由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通过。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM