[C#.NET][WCF] 接收 MSMQ 4.0 Poison
當 Service 接收到 "有害" 訊息,什麼是有害,例如說不符合條件的資料
有害資料的處理流程如下:
這會牽涉到一些設定檔參數,參考:http://msdn.microsoft.com/zh-tw/library/ms789028.aspx
參數相依關係如下:參考:http://msdn.microsoft.com/zh-tw/library/aa395218.aspx
@Contract
public interface IService1 { [OperationContract(IsOneWay = true)] void SendUser(User request); }
@Model
public class User { [DataMember] public Guid ID { get; set; } [DataMember] public string Name { get; set; } [DataMember] public int Age { get; set; } public override string ToString() { return string.Format("ID : {0},Name : {1},Age : {2}", this.ID, this.Name, this.Age); } }
開始實作:
@Service
實作 Service1
{ [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)] public void SendUser(User request) { //TODO:判斷資料是否正確 if (request.Name != "余小章") { Console.WriteLine("Cannot process : " + request); throw new MsmqPoisonMessageException("Cannot process : " + request); } else { Console.WriteLine("Receive: {0} ", request); } } }
實作 Poison
要設定兩個 Attribute
- AddressFilterMode = AddressFilterMode.Any
- TransactionScopeRequired = true, TransactionAutoComplete = true
public class Poison : IService1 { [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)] public void SendUser(User request) { //TODO:做想做的事 Console.WriteLine("有害訊息接收: {0}", request); } }
開始監聽
{ private static void Main(string[] args) { string queueName = @".\private$\service"; if (!MessageQueue.Exists(queueName)) MessageQueue.Create(queueName, true); ServiceHost serviceHost = new ServiceHost(typeof(Service1)); ServiceHost poisoneHost = new ServiceHost(typeof(Poison)); try { serviceHost.Faulted += Host_Faulted; poisoneHost.Faulted += Host_Faulted; //start listening serviceHost.Open(); poisoneHost.Open(); Console.WriteLine("The service is ready."); Console.WriteLine("Press <ENTER> to terminate service."); Console.ReadLine(); } finally { serviceHost.Close(); poisoneHost.Close(); } } private static void Host_Faulted(object sender, EventArgs e) { ServiceHost host = (ServiceHost)sender; host.Abort(); } }
比較重要的是 poison queue 的設定,這要用分號 ";"
net.msmq://localhost/private/service;poison
<configuration> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> </startup> <system.serviceModel> <behaviors> <serviceBehaviors> <behavior name="serviceBehavior0"> <serviceMetadata httpGetEnabled="true" /> </behavior> </serviceBehaviors> </behaviors> <bindings> <netMsmqBinding> <binding name="server1.netMsmqBinding" maxRetryCycles="1" receiveErrorHandling="Move" receiveRetryCount="0" retryCycleDelay="00:00:05"> <security mode="None" /> </binding> <binding name="poison.netMsmqBinding"> <security mode="None" /> </binding> </netMsmqBinding> </bindings> <services> <service behaviorConfiguration="serviceBehavior0" name="Service.Service1"> <endpoint address="net.msmq://localhost/private/service" binding="netMsmqBinding" bindingConfiguration="server1.netMsmqBinding" contract="Contract.IService1" /> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> <host> <baseAddresses> <add baseAddress="http://YAO-WIN8:8888/service" /> </baseAddresses> </host> </service> <service name="Service.Poison"> <endpoint address="net.msmq://localhost/private/service;poison" binding="netMsmqBinding" bindingConfiguration="poison.netMsmqBinding" contract="Contract.IService1" /> </service> </services> </system.serviceModel> </configuration>
@Client
這裡就沒有什麼特別的地方了
文章出自:http://www.dotblogs.com.tw/yc421206/archive/2013/10/31/126335.aspx
範例下載:https://dotblogsfile.blob.core.windows.net/user/yc421206/1310/2013103116373566.zip
若有謬誤,煩請告知,新手發帖請多包涵
Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET