十五天精通WCF——第一天 三種Binding讓你KO80%的業務

一線碼農發表於2015-06-07

  

  轉眼wcf技術已經出現很多年了,也在.net界混的風生水起,同時.net也是一個高度封裝的框架,作為在wcf食物鏈最頂端的我們所能做的任務已經簡單的不能再簡單了,

再簡單的話馬路上的大媽也能寫wcf了,好了,wcf最基本的概念我們放在後面慢慢分析,下面我們來看看神奇的3個binding如何KO我們實際場景中的80%的業務場景。

 

一:basicHttpBinding

  作為入門第一篇,也就不深入談談basic中的通道棧中那些啥東西了,你只需要知道有ABC三個要素,注意不是姨媽巾哦,如果需要詳細瞭解,可以觀賞我以前的系列。在

這裡我就不多說了,太簡單的東西沒意思,先看個例子簡單感受了,你只需知道的是basic走的是http協議就好了,傳輸訊息為soap。

1. 契約

 1 using System.Runtime.Serialization;
 2 using System.ServiceModel;
 3 
 4 namespace MyService
 5 {
 6     [ServiceContract]
 7     public interface IHomeService
 8     {
 9         [OperationContract]
10         int GetLength(string name);
11     }
12 }

2. 實現類

 1 using System;
 2 using System.Messaging;
 3 using System.Threading;
 4 
 5 namespace MyService
 6 {
 7     public class HomeService : IHomeService
 8     {
 9         public int GetLength(string name)
10         {
11             return name.Length;
12         }
13     }
14 }

3. 服務啟動

 1 using System;
 2 using System.ServiceModel;
 3 
 4 namespace MyService
 5 {
 6     class Program
 7     {
 8         static void Main(string[] args)
 9         {
10             using (ServiceHost host = new ServiceHost(typeof(HomeService)))
11             {
12                 try
13                 {
14                     host.Open();
15 
16                     Console.WriteLine("服務開啟!");
17 
18                     Console.Read();
19                 }
20                 catch (Exception e)
21                 {
22                     Console.WriteLine(e.Message);
23                 }
24             }
25         }
26     }
27 }

4. 配置config檔案

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <bindings>
      <netTcpBinding>
        <binding name="IHomeServiceBinding" />
      </netTcpBinding>
    </bindings>

    <behaviors>
      <serviceBehaviors>
        <behavior name="">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>

    <services>
      <service name="MyService.HomeService">
        <endpoint address="http://127.0.0.1:1920/HomeService" binding="basicHttpBinding" contract="MyService.IHomeService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>

        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://127.0.0.1:1920"/>
          </baseAddresses>
        </host>
      </service>
    </services>

  </system.serviceModel>
</configuration>

5. 然後通過 servicehost 啟動服務端

using System;
using System.ServiceModel;

namespace MyService
{
    class Program
    {
        static void Main(string[] args)
        {
            using (ServiceHost host = new ServiceHost(typeof(HomeService)))
            {
                try
                {
                    host.Open();

                    Console.WriteLine("服務開啟!");

                    Console.Read();
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
            }
        }
    }
}

 

好了,到現在為止,服務端全部開啟完畢,接下來我們通過“新增服務引用”,來新增對客戶端的引用

 1 using System;
 2 
 3 namespace ConsoleApplication1
 4 {
 5     class Program
 6     {
 7         static void Main(string[] args)
 8         {
 9             HomeServiceReference.HomeServiceClient client = new HomeServiceReference.HomeServiceClient();
10 
11             var s = client.GetLength("12345");
12 
13             Console.WriteLine("長度為:{0}", s);
14 
15             Console.Read();
16         }
17     }
18 }

 

麻蛋,就這麼簡單,是的,就這樣簡單的五步,基於http的通訊就這樣被不小心的完成了,真不好意思。

 

二:netTcpBinding

  有了basic的程式碼,現在我們要改成tcp通訊,這會通訊走的是位元組流,很簡單,改一下服務端的config檔案就好了,大家也知道這種效能要比basic好。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="mxbehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>

    <services>
      <service name="MyService.HomeService" behaviorConfiguration="mxbehavior">
        <endpoint address="net.tcp://localhost:19200/HomeService" binding="netTcpBinding" contract="MyService.IHomeService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>

        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:1920/HomeService"/>
          </baseAddresses>
        </host>
      </service>
    </services>

  </system.serviceModel>
</configuration>

 

三:netMsmqBinding

  msmq這個玩意,我想大家都清楚,一個物理上的檔案,好處呢,你也明白,就是client和service的所有通訊都要經過它的手,這樣任何一方出了問題,只要

它在就沒問題了。同樣我們把tcp改成msmq也是非常簡單的,不過要注意,msmqbinding中是不可以讓契約方法有返回值的。所以我們加上isoneway就好了。

using System.Runtime.Serialization;
using System.ServiceModel;

namespace MyService
{
    [ServiceContract]
    public interface IHomeService
    {
        [OperationContract(IsOneWay = true)]
        void GetLength(string name);
    }
}

然後我在mmc上新建一個訊息佇列,如下:

然後我們再改動以下配置檔案

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="mxbehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <netMsmqBinding>
        <binding name="msmqbinding">
          <security mode="None"/>
        </binding>
      </netMsmqBinding>
    </bindings>
    <services>
      <service name="MyService.HomeService" behaviorConfiguration="mxbehavior">
        <endpoint address="net.msmq://localhost/private/homequeue" binding="netMsmqBinding"
                  contract="MyService.IHomeService" bindingConfiguration="msmqbinding">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>

        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:19200/HomeService"/>
          </baseAddresses>
        </host>
      </service>
    </services>

  </system.serviceModel>
</configuration>

 

縱觀上面的三種binding,配置起來何其簡單,底層的各種通訊協議貌似對我來說都是透明的,其實呢???wcf在底層做了何其多的事情,而我卻沒有挖掘。。。

這對碼農裡說也是一種悲哀啊。。。出了問題就只能禱告上天。。。下一篇我會開始深入剖析。

 

相關文章