是否可以使用通用WCF服务来处理多个MSMQ端点? [英] Is it possible to have a generic WCF service for handling multiple MSMQ endpoints?

查看:108
本文介绍了是否可以使用通用WCF服务来处理多个MSMQ端点?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们的团队正在构建服务,以使用WCF处理来自多个远程MSMQ队列的消息(通过

Our team is building a service for processing messages from multiple remote MSMQ queues using WCF (via msmqIntegrationBinding). We would like to have the ability to throttle different groups of queues (via serviceThrottling) based on the amount of resources they typically consume.

我的想法是让一个服务类型处理来自多个队列的消息,并根据消息的类型确定如何处理它们.不幸的是,我无法弄清楚使用 MsmqMessage<T> ,因为它期望消息的确切类型. MsmqMessage<object>不起作用,因为我认为它正在尝试查找类型为object的序列化器.

My idea is to have a single service type processing messages from multiple queues and determining what to do with them based on the type of message. Unfortunately, I can't figure out a generic way to use MsmqMessage<T> as it's expecting the exact type of the message. MsmqMessage<object> doesn't work because I think it's trying to find a serializer for type object.

关于如何开展这项工作或替代方法的任何想法?最好仍使用WCF,因为它已内置了死信处理功能.

Any ideas on how to get this work or alternative approaches? Preferably still using WCF since it has dead-letter handling already built-in.

示例配置:

<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>引起的.

The issue was not actually caused by MsmqMessage<object>.

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

When the queued messages are in XML format, the service uses the ServiceKnownTypeAttribute to determine what types are supported by the service for XML (de)serialization. In this case, object isn't really a valid serializable type so it was probably ignored.

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

In order to support generic processing of XML messages, you can add [ServiceKnownType(typeof(XElement))] to your service contract and accept MsmqMessage<object> as the argument to your service method. This will allow you to check properties of the MsmqMessage<T> object to determine how it should be processed. Another possible option would be to use the overload of the ServiceKnownTypeAttribute that accepts a method parameter to dynamically build a list of your supported types.

唯一的其他序列化格式选中的是Binary,因此请记住,它们的处理方式可能都不同.特别是对于Binary格式,不需要ServiceKnownTypeAttribute,因为类型信息包含在二进制有效负载中(仅使用System.Guid进行了测试).如果您打算使用Binary格式,那么继续使用MsmqMessage<object>而不是MsmqMessage<XElement>是很重要的,因为实际的对象类型将代​​替XElement出现.

The only other serialization format I checked is Binary, so keep in mind they are all likely processed differently. For the Binary format specifically, no ServiceKnownTypeAttribute is required as the type information is included in the binary payload (only tested this with System.Guid). If you intend to use the Binary format, it's important you continue to use MsmqMessage<object> rather than MsmqMessage<XElement> as the actual object type will come through instead of XElement.

这篇关于是否可以使用通用WCF服务来处理多个MSMQ端点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆