[C#.NET][WCF] 接收 MSMQ 4.0 Poison

[C#.NET][WCF] 接收 MSMQ 4.0 Poison

當 Service 接收到 "有害" 訊息,什麼是有害,例如說不符合條件的資料

有害資料的處理流程如下:

image

 

 

這會牽涉到一些設定檔參數,參考:http://msdn.microsoft.com/zh-tw/library/ms789028.aspx

image

 

參數相依關係如下:參考:http://msdn.microsoft.com/zh-tw/library/aa395218.aspx

image

 

@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

Image result for microsoft+mvp+logo