.Net下RabbitMQ的使用(9) -- 在WCF下使用RabbitMQ


 

RabbitMQ .net客戶端通過自定義的Binding和Transport Binding Element擴展了WCF,使之能夠在AMQP協議上使用。在WCF中,Binding作為一系列Binding Elements的棧,控制了消息傳輸的大部分方面如安全,消息格式,事務等等。而Binding中的Transport Binding Element傳輸綁定元素,則指定了服務端和客戶端之間的通信協議。RabbitMQ .net客戶端提供的Binding使我們可以在AMQP協議上面使用WCF方便的實現One-Way, Two-Way(Request/Reply),Duplex(Asynchronous Callback)這樣的常見通信方式,並且提供可靠的,事務性的傳輸。我們可以通過代碼和傳統WCF配置文件的方式進行開發。

 

WCF的ABC

Address

使用RabbitMQ Binding 的地址一定要使用如下格式:serviceAddress = “soap.amqp:///” serviceName,例如:soap.amqp:///myService。它使用類型是direct的exchange。其他類型的exchange似乎不被支持。

需要注意的是,用IIS來作為Host是不被推薦的,應該使用System.ServiceModel.ServiceHost來Host,RabbitMQ的服務端。地址的配置可以通過代碼也同樣可以通過config文件來配置。

 

Binding

RabbitMQ使用的Binding不是在.net客戶端RabbitMQ.Client中提供,而是在RabbitMQ.ServiceModel.dll這個新的dll中提供。可以再官方網站或者Nuget中獲取到。所以在引用RabbitMQ.Client.dll的同時還要引用RabbitMQ.ServiceModel.dll。在配置文件中定義時,必須要配置Binding的extension。

我們在配置文件中如下配置:

<bindings>
      <rabbitMQBinding>
        <binding name="rabbitMQConfig"
         protocolversion="AMQP_0_9_1"
                 hostname="localhost"
                 port="5672" />
      </rabbitMQBinding>
    </bindings>
    <extensions>
      <bindingExtensions>
        <add
          name="rabbitMQBinding"
          type="RabbitMQ.ServiceModel.RabbitMQBindingSection, RabbitMQ.ServiceModel, Version=1.0.110.0, Culture=neutral, PublicKeyToken=null"/>
      </bindingExtensions>
    </extensions>

 

關於RabbitMQ.ServiceModel.dll中Binding的相關詳細信息,默認使用和可以使用的綁定元素可以參考官方提供的文檔。

 

Contract

Contract的定義是和原來的WCF定義是一樣的,沒有什么區別,加上ServiceContractAttribute和OperationContractAttribute屬性就可以:

[ServiceContract]
public interface ICalculator
{
    [OperationContract]
    int Add(int x, int y);
    [OperationContract]
    int Subtract(int x, int y);
}

如果要在具體服務的實現上使用Behavior也可原來一樣:

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall)]
public sealed class Calculator : ICalculator
{
    public int Add(int x, int y)
    {
        return x + y;
    }
    public int Subtract(int x, int y)
    {
        return x - y;
    }
}

 

服務

服務的定義也和常用的WCF定義一樣,配置文件定義和代碼定義。Host應該使用System.ServiceModel.ServiceHost。ServiceHost必須定義一個基地址或者是完整的Endpoint地址,該地址是用soap.amqp格式的。Endpoint必須添加使用RabbitMQBinding。

service = new ServiceHost(
    typeof(Calculator),
    new Uri("soap.amqp:///"));
service.AddServiceEndpoint(
typeof(ICalculator),
new RabbitMQBinding(
"localhost",
5672,
"guest",
"guest",
"/",
8192,
Protocols.AMQP_0_9_1),
"Calculator");

 

服務端完整的配置文件定義如下:

<system.serviceModel>
    <services>
      <service name="ESBTest.WcfRabbitMQ.ConsoleServerPerformance.RabbitMQServer">
        <host>
          <baseAddresses>
            <add baseAddress="soap.amqp:///"   />
          </baseAddresses>
        </host>
        <endpoint
          address="ESBTest.WcfRabbitMQ.ConsoleServerPerformance"
          binding="rabbitMQBinding"
          bindingConfiguration="rabbitMQConfig"
          contract="ESBTest.Contracts.IRequest"/>
      </service>
    </services>
 
    <bindings>
      <rabbitMQBinding>
        <binding name="rabbitMQConfig"
                 hostname="localhost"
                 port="5672"
                 protocolversion="AMQP_0_9_1"
                 oneWay="false"/>
      </rabbitMQBinding>
    </bindings>
 
    <extensions>
      <bindingExtensions>
        <add
          name="rabbitMQBinding"
          type="RabbitMQ.ServiceModel.RabbitMQBindingSection, RabbitMQ.ServiceModel, Version=1.0.110.0, Culture=neutral, PublicKeyToken=null"/>
      </bindingExtensions>
    </extensions>
  </system.serviceModel>

 

開多個服務端,同樣可以實現負載均衡。

 

客戶端

客戶端的定義也和常用的WCF定義一樣,官方推薦通過繼承自ClientBase<T>或DuplexClientBase<T>來實現。如果是Duplex的客戶端,InstanceContext必須要指定的。

完整的客戶端配置文件定義如下:

<system.serviceModel>
    <client>
      <endpoint address="soap.amqp:///ESBTest.WcfRabbitMQ.ConsoleServerPerformance"
                binding="rabbitMQBinding"
                bindingConfiguration="rabbitMQConfig"
                contract="ESBTest.Contracts.IRequest"
                name="client" />
    </client>
    <bindings>
      <rabbitMQBinding>
        <binding name="rabbitMQConfig"
         protocolversion="AMQP_0_9_1"
                 hostname="localhost"
                 port="5672" />
      </rabbitMQBinding>
    </bindings>
    <extensions>
      <bindingExtensions>
        <add
          name="rabbitMQBinding"
          type="RabbitMQ.ServiceModel.RabbitMQBindingSection, RabbitMQ.ServiceModel, Version=1.0.110.0, Culture=neutral, PublicKeyToken=null"/>
      </bindingExtensions>
    </extensions>
  </system.serviceModel>

 

我們可以看到,提供的WCF Binding只是一些簡單通用的功能,RabbitMQ的一些其他比較好的功能並沒有提供。所以使用WCF或者直接使用客戶端要視業務和系統環境而定,如果只是使用一些簡單的功能或整個系統都是基於WCF的,那么使用WCF來做RabbitMQ,會給你提供一個快速的,一致性的開發模型。但如果使用的場景比較復雜,性能要求比較高的話還是使用.net客戶端的API比較理想。直接使用客戶端API和WCF來比較,就速度而言,WCF花的是時間大概是直接使用API的7倍左右,慢得多。這點相信大家也是可以預見的。

 

簡單代碼示例在這里下載。是One-Way的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM