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.
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
.
Any ideas on how to get this work or alternative approaches? Preferably still using WCF since it has dead-letter handling already built-in.
Example Configuration:
<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>
Example Contract:
[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 { }