首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

WCF 實戰教學 (3):Binding 繫結核心概念與 basicHttpBinding / netTcpBinding 實戰設定

     編輯:關於.NET

前言

Binding (繫結) 是 WCF 通訊堆疊的核心,決定了「如何傳輸」(Transport)、「如何編碼」(Encoding)、「何種協定」(Protocol)。選對 Binding 能大幅影響效能、相容性、安全性與部署架構。本篇聚焦兩個最常用的繫結:basicHttpBinding (Web 服務相容) 與 netTcpBinding (高效能內網),並示範程式碼與設定檔兩種端點建立方式。

Binding 組成三要素

  • Protocol (協定層):Security、ReliableMessaging、TransactionFlow 等 WS-* 協定
  • Encoding (編碼層):Text (XML)、Binary、MTOM、Json
  • Transport (傳輸層):HTTP、HTTPS、TCP、Named Pipe、MSMQ、UDP、Custom

basicHttpBinding vs netTcpBinding 快速比較

特性basicHttpBindingnetTcpBinding
傳輸協定HTTP/HTTPSTCP (Binary)
編碼方式Text (XML) / MTOMBinary (專屬高效二進位)
相容性✅ ASMX、Java、PHP、任何 WS-I Basic Profile 1.1 客戶端❌ 僅限 WCF 客戶端
效能較低 (XML 解析、Base64)✅ 高 (二進位、連線導向、連線共用)
防火牆穿透✅ 80/443 通常開放需開放特定 Port (預設 808/客製)
安全性預設None (可升級 Transport/Message)Transport (Windows 驗證)
適用場景跨平台、對外公開 API、Web 應用整合內網高效能、雙向通訊、大量資料傳輸

完整程式碼範例

1. 共用服務契約與實作

// IHello.cs
using System.ServiceModel;

namespace WCF.ServiceLib.Binding
{
    [ServiceContract]
    public interface IHello
    {
        [OperationContract]
        string SayHello(string name);
    }
}

// Hello.cs
namespace WCF.ServiceLib.Binding
{
    public class Hello : IHello
    {
        public string SayHello(string name) => $"Hello: {name}";
    }
}

2. 宿主 — 程式碼建立端點 (Program.cs)

using System;
using System.ServiceModel;
using WCF.ServiceLib.Binding;

namespace WCF.ServiceHost2.Binding
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var host = new ServiceHost(typeof(Hello)))
            {
                // 方式 1:程式碼動態新增端點 (netTcpBinding)
                host.AddServiceEndpoint(typeof(IHello), new NetTcpBinding(), "net.tcp://localhost:54321/Binding/Hello");
                
                // 方式 2:若想同時支援 basicHttpBinding,取消註解下行
                // host.AddServiceEndpoint(typeof(IHello), new BasicHttpBinding(), "https://localhost:12345/Binding/Hello");
                
                // 中繼資料端點 (供用戶端產生 Proxy)
                host.AddServiceEndpoint(typeof(IMetadataExchange), new MexHttpBinding(), "https://localhost:12345/Binding/mex");
                
                host.Open();
                Console.WriteLine("服務已啟動 (net.tcp://localhost:54321/Binding/Hello)");
                Console.WriteLine("按  停止...");
                Console.ReadLine();
            }
        }
    }
}

3. 宿主 — 設定檔建立端點 (App.config)

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.serviceModel>
    <services>
      <service name="WCF.ServiceLib.Binding.Hello" behaviorConfiguration="BindingBehavior">
        <!-- netTcpBinding 端點 -->
        <endpoint address="net.tcp://localhost:54321/Binding/Hello"
                  binding="netTcpBinding"
                  contract="WCF.ServiceLib.Binding.IHello" />
        
        <!-- basicHttpBinding 端點 (取消註解即可雙協定並存) -->
        <!--
        <endpoint address="https://localhost:12345/Binding/Hello"
                  binding="basicHttpBinding"
                  contract="WCF.ServiceLib.Binding.IHello" />
        -->
        
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="https://localhost:12345/Binding/" />
          </baseAddresses>
        </host>
      </service>
    </services>

    <behaviors>
      <serviceBehaviors>
        <behavior name="BindingBehavior">
          <serviceMetadata httpGetEnabled="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

4. 用戶端 — 程式碼建立 Channel (WinForm)

using System;
using System.ServiceModel;
using System.Windows.Forms;

namespace Client2.Binding
{
    public partial class HelloForm : Form
    {
        public HelloForm() => InitializeComponent();

        private void btnSayHello_Click(object sender, EventArgs e)
        {
            // 方式 1:ChannelFactory 程式碼建立 (無需設定檔)
            var binding = new NetTcpBinding();
            var address = new EndpointAddress("net.tcp://localhost:54321/Binding/Hello");
            var factory = new ChannelFactory(binding, address);
            var proxy = factory.CreateChannel();
            
            try
            {
                MessageBox.Show(proxy.SayHello(txtName.Text));
                ((ICommunicationObject)proxy).Close();
            }
            catch (Exception ex)
            {
                ((ICommunicationObject)proxy).Abort();
                MessageBox.Show(ex.Message);
            }
        }
    }
}

5. 用戶端 — 設定檔建立 Proxy (App.config)

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.serviceModel>
    <client>
      <endpoint address="net.tcp://localhost:54321/Binding/Hello"
                binding="netTcpBinding"
                contract="Binding.IHello" />
      
      <!-- basicHttpBinding 端點範例 -->
      <!--
      <endpoint address="https://localhost:12345/Binding/Hello"
                binding="basicHttpBinding"
                contract="Binding.IHello" />
      -->
    </client>
  </system.serviceModel>
</configuration>

進階設定:效能與安全性調校

netTcpBinding 關鍵屬性

<netTcpBinding>
  <binding name="OptimizedTcpBinding"
           maxReceivedMessageSize="1073741824"      <!-- 1 GB -->
           maxBufferSize="2147483647"               <!-- 緩衝區上限 -->
           transferMode="Buffered"                  <!-- 或 Streamed -->
           connectionBufferSize="8192"
           listenBacklog="100"
           maxConnections="200"
           receiveTimeout="00:10:00"
           sendTimeout="00:10:00">
    <security mode="Transport">                     <!-- 預設 Windows 驗證 -->
      <transport clientCredentialType="Windows" />
    </security>
    <reliableSession enabled="false" />             <!-- 可啟用可靠會話 -->
  </binding>
</netTcpBinding>

basicHttpBinding 關鍵屬性

<basicHttpBinding>
  <binding name="SecureHttpBinding"
           maxReceivedMessageSize="1073741824"
           messageEncoding="Text"                   <!-- 或 Mtom -->
           transferMode="Buffered">
    <security mode="TransportCredentialOnly">       <!-- HTTPS + 客戶端憑證 -->
      <transport clientCredentialType="Basic" />    <!-- 或 Windows, Certificate -->
    </security>
    <readerQuotas maxArrayLength="1073741824" />
  </binding>
</basicHttpBinding>

常見部署問題與解決

  1. netTcpBinding 連線失敗「拒絕連線」:檢查防火牆開放 Port (預設 808 或自訂)、確認服務已啟動、BaseAddress ACL (`netsh http add urlacl url=net.tcp://+:54321/ user=Everyone`)。
  2. basicHttpBinding 傳輸大檔案失敗:調大 `maxReceivedMessageSize`、`readerQuotas.maxArrayLength`,或改用 `transferMode="Streamed"` + MTOM。
  3. 跨網域呼叫 (Silverlight/Flash/瀏覽器):需在網站根目錄放置 `clientaccesspolicy.xml` 或 `crossdomain.xml`。
  4. 雙協定並存端點衝突:每個 Endpoint 的 `address` 必須唯一,BaseAddress 僅作相對路徑基準。

選型建議決策樹

需要跨平台/對外公開 API ? ──是──→ basicHttpBinding (或 wsHttpBinding 需 WS-* 支援)
                                    │
                                    否
                                    │
內網高效能/大資料/雙向通訊 ? ──是──→ netTcpBinding
                                    │
                                    否
                                    │
同機器進程間通訊 ? ───────────是──→ netNamedPipeBinding (最快、最安全)
                                    │
                                    否
                                    │
需離線/佇列/保證送達 ? ────────是──→ netMsmqBinding
                                    │
                                    否
                                    │
預設選擇 ──────────────────────→ basicHttpBinding (相容性最廣)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved