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

WCF 雙工服務完整實作:從契約設計到聊天室範例

     編輯:關於.NET

什麼是 WCF 雙工服務?

傳統 WCF 服務採用請求-回覆模式,客戶端發起呼叫,服務被動回應。雙工服務打破這一限制,允許服務主動向客戶端發起通訊(回呼),實現真正的雙向即時通訊。典型應用包括:即時通訊、股票報價推送、協同編輯、遊戲狀態同步等。

核心架構三要素

  1. 回呼契約:定義服務可呼叫的客戶端方法
  2. 服務契約:標註 CallbackContract 指定回呼型別
  3. 雙工繫結:必須使用支援雙工的繫結(如 WSDualHttpBinding、NetTcpBinding)

完整程式碼實作

1. 定義回呼契約

[ServiceContract]
public interface ICallbackContract
{
    [OperationContract(IsOneWay = true)]
    void ServerReply(string originalMessage);
}

2. 定義服務契約並關聯回呼

[ServiceContract(CallbackContract = typeof(ICallbackContract))]
public interface IChatContract
{
    [OperationContract(IsOneWay = true)]
    void SendMessage(string message);
}

3. 服務端實作

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
public class ChatService : IChatContract
{
    public void SendMessage(string message)
    {
        Console.WriteLine($"{DateTime.Now} 收到訊息: {message}");
        
        // 取得回呼通道,主動呼叫客戶端
        var callback = OperationContext.Current.GetCallbackChannel<ICallbackContract>();
        callback.ServerReply($"伺服器已處理: {message}");
    }
}

關鍵點:ConcurrencyMode.Multiple 允許多線程並發處理請求,避免回呼時死鎖。

4. 客戶端回呼處理器

public class CallbackHandler : ICallbackContract
{
    public void ServerReply(string originalMessage)
    {
        Console.WriteLine($"{DateTime.Now} 收到伺服器回覆: {originalMessage}");
    }
}

5. 客戶端 Proxy 建立與通訊

class ChatServiceClient : ClientBase<IChatContract>, IChatContract
{
    public ChatServiceClient(InstanceContext callback, Binding binding, EndpointAddress address)
        : base(callback, binding, address) { }

    public void SendMessage(string message) => Channel.SendMessage(message);
}

// 主程式
static void Main()
{
    var binding = new WSDualHttpBinding(); // 必須使用雙工繫結
    var address = new EndpointAddress("https://localhost:9000/ChatService");
    var callback = new CallbackHandler();
    var proxy = new ChatServiceClient(new InstanceContext(callback), binding, address);

    Console.Write("請輸入訊息 (Exit 離開): ");
    while ((input = Console.ReadLine()) != "Exit")
    {
        proxy.SendMessage(input);
        Console.Write("請輸入訊息 (Exit 離開): ");
    }
}

關鍵技術細節

InstanceContext 的角色

InstanceContext 包裝回呼物件實例,管理其生命週期與併發行為。它是雙工通訊的基石,確保服務能正確路由回呼訊息至特定客戶端實例。

繫結選擇指南

繫結傳輸適用場景
WSDualHttpBindingHTTP跨防火牆、互聯網環境
NetTcpBindingTCP內部網路、高效能需求
NetNamedPipeBindingNamed Pipe同機器進程間通訊

防火牆與 NAT 穿透

WSDualHttpBinding 實際上建立兩個 HTTP 通道:客戶端→服務、服務→客戶端。客戶端必須可被外部存取(需開放連接埠),這在企業防火牆後可能需額外配置。內網環境建議優先使用 NetTcpBinding。

常見問題與解決方案

  • TimeoutException:增加 SendTimeout、ReceiveTimeout 設定
  • 回呼不觸發:檢查 IsOneWay=true、客戶端防火牆、InstanceContext 生命週期
  • 並發死鎖:服務端設定 ConcurrencyMode.Multiple 或 Reentrant

總結

WCF 雙工服務透過回呼契約與雙工繫結,優雅地實現了伺服器主動推送能力。掌握 InstanceContext、併發模式、繫結選擇等核心概念,即可建構穩健的即時通訊應用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved