[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