日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

WCF入门(六)——回调

發布時間:2025/7/14 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 WCF入门(六)——回调 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在上篇文章中介紹了一下WCF中的客戶端到服務器端的單向通知,在實際應用中,還經常使用服務器端到客戶端的單向通知。例如,在聊天室里,我們需要把某人的發言廣播給每一個人。對于這種單向通知,我們一般稱為回調。本文就以一個簡單的聊天室為例,介紹一下如何實現回調。

1. 定義一個回調接口

????interface IMessageCallback
????{
????????[
OperationContract(IsOneWay = true)]
????????void OnMessageAdded(string message, DateTime timestamp);
????}

這個接口并不是服務,因此沒有ServiceContract標志,但其回調函數形式需要被公布,因此接口函數有OperationContract標志,另外,這個也是一個單向通知,因此有IsOneWay = true設置(注:這里的IsOneWay不是必須的,可以獲取回調函數的返回值的)

2. 在服務契約上加上回調通知接口聲明

????[ServiceContract(CallbackContract = typeof(IMessageCallback))]
????public interface IService1
????{
????????[OperationContract]
????????void AddMessage(string message);

????????[OperationContract]
????????void Subscribe();

????????[OperationContract]
????????void Unsubscribe();
????}

除了客戶端上報消息的接口外,這里也加了兩個接口函數Subscribe和Unsubscribe,用來注冊回調和刪除回調,實現了一個典型的觀察者模式。(PS:這兩個接口并不是必須的,主要是為了方便演示回調的實現過程)

3. 實現回調

接口聲明完成后,給了一個簡單的實現(這個只是示例代碼,線程安全,最佳實踐神馬的都沒有考慮,不要用于實際項目中)。

????public class Service1 : IService1
????{
????????static List<IMessageCallback> subscribers = new List<IMessageCallback>();

????????public void AddMessage(string message)
????????{
????????????subscribers.ForEach(callback =>
????????????{
????????????????if (((ICommunicationObject)callback).State == CommunicationState.Opened)
????????????????????callback.OnMessageAdded(message, DateTime.Now);
????????????????else
????????????????????subscribers.Remove(callback);
????????????});
????????}

????????public void Subscribe()
????????{
????????????var callback = OperationContext.Current.GetCallbackChannel<IMessageCallback>();
????????????subscribers.Add(callback);
????????}

????????public void Unsubscribe()
????????{
????????????var callback = OperationContext.Current.GetCallbackChannel<IMessageCallback>();
????????????subscribers.Remove(callback);
????????}
????}

從上述代碼中可以發現,回調的基本使用方式如下:

  • OperationContext.GetCallbackChannel中獲取回調通道對象,該對象實現了回調接口和ICommunicationObject接口。
  • 根據IcommunicationObject.State屬性查看其是否可用,也可以注冊IcommunicationObject. Closed事件主動響應客戶端退出。
  • 調用回調對象的回調函數接口即可實現回調通知
4. 服務器端配置

編譯并運行上述服務后,會發現一個服務無法啟動的錯誤。

原因說得很清楚,要使用CallbackContract,則需要底層協議支持雙工(因為需要從服務器端主動通知客戶端)。但目前使用的BasicHttpBinding由于是基于Http協議,不支持雙工(另外一個基于Http協議的WSHttpBinding也不支持雙工),要改成支持雙工的協議。目前WCF中支持雙工的協議有如下幾種:

  • 基于TCP協議的NetTcpBinding
  • 基于管道的NetNamedPipeBinding
  • 基于Http協議的wsDualHttpBinding,雖然Http協議本身不支持雙工,但是wsDualHttpBinding通過創建兩個不同方向的Http連接來實現了雙向傳輸。

為了簡單,我這里就改成了wsDualHttpBinding。

5. 實現客戶端代碼

由于WCF測試客戶端不支持回調的測試,因此這里我們就需要手動實現客戶端代碼:

????????static void Main(string[] args)
????????{
????????????var context = new System.ServiceModel.InstanceContext(new Callback());
????????????var client = new WcfClient.Service.Service1Client(context);

????????????client.Subscribe();
????????????while (true)
????????????{
????????????????var input = Console.ReadLine();
????????????????if (string.IsNullOrWhiteSpace(input))
????????????????????break;

????????????????client.AddMessage(input);
????????????}

????????????client.Unsubscribe();
????????????client.Close();
????????}

????????class Callback:IService1Callback
????????{
????????????public void OnMessageAdded(string message, DateTime timestamp)
????????????{
????????????????Console.WriteLine(">>> Receive Message {0} {1}", message, timestamp);
????????????}
????????}

編寫這個代碼時就會發現:現在Client的構造函數需要傳入一個參數了,在這個參數中就可以指定實現了回調接口的對象,從而響應回調通知。運行客戶端多個實例,發送消息,每個消息都會通知到所有客戶端,與我們預期結果一致。

總結

以上是生活随笔為你收集整理的WCF入门(六)——回调的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。