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

WCF 從理論到實踐 (7):三大訊息交換模式完全解析

     編輯:關於.NET

文章導讀

本文系統闡述 WCF 三種訊息交換模式(One-Way、Request/Reply、Duplex)的特徵、定義方式、適用場景,並提供完整程式碼範例驗證各模式行為差異。適合具備 SOA 基礎概念與分散式開發經驗的讀者。

核心知識點

  • 三大模式定義、特徵、限制對比
  • OperationContract 屬性控制模式切換
  • Duplex 模式的繫結需求與回調合約設計
  • 完整範例:合約定義、服務實作、宿主配置、客戶端呼叫
  • 執行結果驗證與圖解

一、WCF 三大訊息交換模式概覽

模式特徵回傳值參數限制適用場景
One-Way 單向發送,有去無回(肉包子打狗) 只能 void 不可有 ref/out 參數 事件通知、日誌記錄、非關鍵狀態更新
Request/Reply 請求-回應,預設模式,類似 HTTP 任意型別(含 void 也會產生回應訊息) 支援 ref/out 大多數業務操作:查詢、CRUD、運算
Duplex 雙工,雙方可互為客戶端/服務端,支援回調 任意型別 支援 ref/out 即時通訊、進度通知、事件訂閱、長時間任務回報

二、模式定義方式與程式碼範例

1. One-Way 定義

[ServiceContract]
public interface IOneWayJob {
    [OperationContract(IsOneWay = true)]
    void Do(string jobName);
}

// 實作
public class OneWayJob : IOneWayJob {
    public void Do(string jobName) {
        Thread.Sleep(1000); // 模擬耗時
        Console.WriteLine($"服務執行任務: {jobName}");
    }
}

One-Way 合約介面定義

2. Request/Reply 定義(預設)

[ServiceContract]
public interface INormalJob {
    [OperationContract] // 預設 IsOneWay=false
    string Do(string jobName);
}

// 實作
public class NormalJob : INormalJob {
    public string Do(string jobName) {
        Thread.Sleep(1000);
        Console.WriteLine($"服務執行任務: {jobName}");
        return "成功";
    }
}

Request/Reply 合約介面定義

3. Duplex 定義(需回調合約)

// 1. 定義回調合約(客戶端需實作)
[ServiceContract]
public interface ICallback {
    [OperationContract(IsOneWay = true)]
    void Done(int elapsedMs);
}

// 2. 服務合約引用回調
[ServiceContract(CallbackContract = typeof(ICallback))]
public interface IJob {
    [OperationContract]
    string Do(string jobName);
}

// 3. 服務實作:透過 OperationContext 取得回調通道
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
public class Job : IJob {
    public string Do(string jobName) {
        var callback = OperationContext.Current.GetCallbackChannel<ICallback>();
        var sw = Stopwatch.StartNew();
        Thread.Sleep(1000);
        Console.WriteLine($"服務執行任務: {jobName}");
        sw.Stop();
        callback.Done((int)sw.ElapsedMilliseconds); // 發起回調
        return "成功";
    }
}

回調合約定義

Duplex 服務合約定義

三、Duplex 關鍵技術點

繫結需求

Duplex 需支援雙工訊息交換模式的繫結:

  • WSDualHttpBinding(HTTP 雙工,需客戶端開啟監聽埠)
  • NetTcpBinding(TCP 雙工,效能最佳,推薦內網)
  • NetNamedPipeBinding(同機器進程間雙工)

⚠️ BasicHttpBinding、WSHttpBinding 不支援 Duplex。

客戶端 BaseAddress 陷阱

使用 WSDualHttpBinding 時,客戶端必須指定 clientBaseAddress(預設嘗試佔用 80 埠常失敗):

<endpoint ... binding="wsDualHttpBinding">
  <identity><dns value="localhost" /></identity>
</endpoint>
<client>
  <endpoint ...>
    <callbackEndpoint address="https://localhost:8080/ClientCallback" /> <!-- 指定回調位址 -->
  </endpoint>
</client>

四、完整範例專案結構

專案類型核心檔案
Jillzhang.Messaging.ContractClass LibraryIOneWayJob.cs, INormalJob.cs, IJob.cs, ICallback.cs
Jillzhang.Messaging.ServiceClass LibraryOneWayJob.cs, NormalJob.cs, Job.cs
Jillzhang.Messaging.HostConsole AppProgram.cs, App.config
Jillzhang.Messaging.WebSiteWeb Site*.svc, web.config
Jillzhang.Messaging.ClientConsole AppOnewayProxy.cs, NormalJobProxy.cs, DuplexProxy.cs, MyCallback.cs, Program.cs, app.config

專案結構圖

五、宿主與客戶端配置關鍵片段

服務端 App.config

服務端配置

客戶端 app.config

<system.serviceModel>
  <bindings>
    <netTcpBinding>
      <binding name="netTcpBinding" />
    </netTcpBinding>
  </bindings>
  <client>
    <endpoint address="net.tcp://localhost:6987/Service/duplex"
              binding="netTcpBinding" bindingConfiguration="netTcpBinding"
              contract="Jillzhang.Messaging.Contract.IJob" name="NetTcpBinding">
      <identity><dns value="localhost" /></identity>
    </endpoint>
    <!-- one-way、normal 端點類似 -->
  </client>
</system.serviceModel>

客戶端回調實作與呼叫

// MyCallback.cs - 客戶端實作回調
public class MyCallback : ICallback {
    public void Done(int elapsedMs) {
        Console.WriteLine($"[回調] 任務完成,耗時 {elapsedMs} ms");
    }
}

// Program.cs - 呼叫三種模式
static void DuplexCall() {
    var callback = new MyCallback();
    var ctx = new InstanceContext(callback);
    var proxy = new JobClient(ctx);
    string result = proxy.Do("duplex job");
    Console.WriteLine($"收到回覆: {result}");
}

static void OneWayCall() {
    var proxy = new OneWayJobClient();
    proxy.Do("one-way job"); // 立即返回,不等待
    Console.WriteLine("請求已送出");
}

static void NormalCall() {
    var proxy = new NormalJobClient();
    string result = proxy.Do("request/reply job"); // 阻塞等待回應
    Console.WriteLine($"收到回覆: {result}");
}

六、執行結果驗證

服務端輸出

服務端運行輸出

可見三種模式依序執行,Duplex 模式額外觸發回調。

客戶端輸出

客戶端運行輸出

One-Way:立即印出「請求完成」
Request/Reply:阻塞 1 秒後印出回覆
Duplex:阻塞 1 秒收到回覆,隨後回調印出耗時資訊

總結對比

維度One-WayRequest/ReplyDuplex
方向單向雙向(請求-回應)雙向(對等)
阻塞性非阻塞阻塞阻塞(等待回覆)+ 非阻塞回調
錯誤傳遞無法傳遞SOAP Fault 返回SOAP Fault + 回調異常
繫結支援所有所有NetTcp, WSDualHttp, NetNamedPipe
會話需求無無需 Session
典型用途通知、日誌、火後不理標準 RPC即時推送、長任務進度、聊天
本文配套源碼下載
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved