[英]Does MsmqIntegrationBinding support multiple service operations
我正在學習MsmqIntegrationBinding。 到目前為止,我看到的所有樣本和指南都涵蓋了這樣的情況:只有一個操作只有一個數據合同。 我嘗試添加另一個合同,服務已成功啟動。 但是我無法弄清楚如何進行第二次操作。 這種綁定是否可以實現這一點?
[ServiceContract]
[ServiceKnownType(typeof(Data1))]
[ServiceKnownType(typeof(Data2))]
public interface ISampleService
{
[OperationContract(IsOneWay = true, Action = "*")]
void Operation1(MsmqMessage<Data1> msg);
[OperationContract(IsOneWay = true)]
void Operation2(MsmqMessage<Data2> msg);
}
public class SampleService : ISampleService
{
[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
public void Operation1(MsmqMessage<Data1> msg)
{
var data = msg.Body;
}
[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
public void Operation2(MsmqMessage<Data2> msg)
{
var data = msg.Body;
}
}
調用代碼
var queue = new MessageQueue(@".\private$\samplequeue");
var body = new Data1() { Data = "some data" };
var message = new Message(body);
message.Label = "some label";
queue.Send(body, MessageQueueTransactionType.Single);
這將觸發Action1設置為“*”的Operation1。
不確定這是一個答案,我沒有評論所需的50個聲譽。
從這個答案中獲取靈感: https : //stackoverflow.com/a/33154517/1095296我們正在做以下事情。
[ServiceContract]
public interface IMSMQueueHandler
{
[OperationContract(IsOneWay = true, Action = "*")]
void Handle(MsmqMessage<object> message);
}
然后我們在包裝服務主機的類上有一個構造函數
public MSMQueueServiceHost(IMSMQConfig msmqConfig, IMSMQueueHandler handler)
{
_hostService = new ServiceHost(handler);
AddHostServiceEndPoint(msmqConfig);
_hostService.Open();
}
private void AddHostServiceEndPoint(IMSMQConfig msmqConfig)
{
ServiceMetadataBehavior smb = new ServiceMetadataBehavior { HttpGetEnabled = false };
_hostService.Description.Behaviors.Add(smb);
MsmqIntegrationBinding binding = new MsmqIntegrationBinding(MsmqIntegrationSecurityMode.None);
binding.SerializationFormat = MsmqMessageSerializationFormat.Stream;
binding.ReceiveErrorHandling = ReceiveErrorHandling.Move;
ServiceEndpoint endpoint = _hostService.AddServiceEndpoint(
typeof(IMSMQueueHandler),
binding,
string.Format("msmq.formatname:DIRECT=OS:{0}", msmqConfig.MsmqPath));
// enforce ServiceBehaviours and OperationBehaviours so we dont have to decorate all the handlers
_hostService.Description.Behaviors.Find<ServiceBehaviorAttribute>().InstanceContextMode = InstanceContextMode.Single;
_hostService.Description.Behaviors.Find<ServiceBehaviorAttribute>().ConcurrencyMode = ConcurrencyMode.Single;
AddKnownTypes(endpoint);
}
private static void AddKnownTypes(ServiceEndpoint endpoint)
{
foreach(OperationDescription operation in endpoint.Contract.Operations)
{
operation.KnownTypes.Add(typeof(XElement));
operation.Behaviors.Find<OperationBehaviorAttribute>().TransactionScopeRequired = true;
operation.Behaviors.Find<OperationBehaviorAttribute>().TransactionAutoComplete = true;
}
}
這里使代碼的關鍵代碼是:
[OperationContract(IsOneWay = true, Action = "*")]
void Handle(MsmqMessage<object> message);
binding.SerializationFormat = MsmqMessageSerializationFormat.Stream;
operation.KnownTypes.Add(typeof(XElement));
Stream格式的原因是我們看到消息體中的XML包裹在大括號中(聞起來像JSON,但我們沒有看到原因)。
最后,我不確定這是一個答案,因為它沒有使用WCF DataContract和內置的WCF序列化,我們將包含以下方法的處理程序傳遞給構造函數:
public void Handle(MsmqMessage<object> message)
{
object msmqType = Serializer.Deserialize(message.Body);
_bus.Publish(msmqType);
}
如果不是很明顯,我們就會對消息使用XML序列化。
這是一個非常有趣的問題。
Action OperationContractAttribute通常由WCF堆棧用於填充WS-Addressing soap標頭。 它的使用顯然被排隊的綁定以某種方式覆蓋。
WCF可能存在未記錄的功能,它允許將msmq消息頭部分映射到基於Action屬性的操作,就像過濾器一樣,但如果有,我不知道它將采用什么形式。
我認為最簡單的解釋是:不,這是不可能的,其原因是msmqIntegrationBinding正如它在錫上所說的那樣:它是關於互操作功能的。
因為您被迫使用MsmqMessage包裝器調用該操作,所以它使得這種綁定在語義上是一維的,這使我的理論認為它旨在包裝單個端點操作以支持與傳統COM和ActiveX客戶端的互操作。
無論如何,沒有法律規定綁定必須支持多個操作,就像某些綁定不支持回調一樣,而某些綁定只支持單向操作。
感謝這不直接回答你的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.