簡體   English   中英

WCF NetTcp雙工通道獨立通信

[英]WCF NetTcp duplex channel independent communication

我想創建一個雙工NetTcp服務。 我不確定什么是最好的方法。 我有一個客戶端,該客戶端定期將其狀態發送到服務器,並且我的服務器必須定期發送獨立於任何客戶端請求的數據。 因為我要避免兩個連接,並且對服務器上的客戶端一無所知,所以我必須使用客戶端打開的連接。 因此,就像我說的那樣,客戶端會定期發送狀態信息。 但是,我如何獨立使用從客戶端建立的連接通道將數據發送到客戶端。 另外,從服務器發送到客戶端的數據確實需要響應。

[ServiceContract(CallbackContract = typeof(IStatusServiceCallBack))]
public interface IStatusService
{
    [OperationContract]
    void SendStatus(int statusCode, string statusMessage);
}

public interface IStatusServiceCallBack
{
    // I know IsOneWay=true cannot work, but how to return value????
    [OperationContract(IsOneWay = true)]
    int SendPayTransaction(PayTransaction payTransaction);
}

public class StatusService : IStatusService
{
    public IStatusServiceCallBack Proxy
    {
        get
        {
            return OperationContext.Current.GetCallbackChannel
            <IStatusServiceCallBack>();
        }
    }

    public void SendNotification(int statusCode, string statusMessage)
    {
        Console.WriteLine($"\nClient status : {(statusCode)} {statusMessage}");
    }
    // Is this possible???
    public int SendPayTransaction(PayTransaction payTransaction){
        return Proxy.SendPayTransaction(payTransaction)
    }

}


class Program
{
    static void Main(string[] args)
    {
        var svcHost = new ServiceHost(typeof(NotificationService));
        svcHost.Open();
        bool closeService = false;
        do{
            string command = Console.ReadLine();
            if(command == "Send"){
               // Is this possible???????
               int result = svcHost.SendPayTransaction(new PaymentTransaction(){Amount = 5.50});
               Console.WriteLine($"Result of payment : {result}");
            } else if (command == "exit"){
               closeService = true;
            }
        }while(!closeService);
    }
}

沒錯,您需要使用客戶端建立的連接。 為此,您必須執行幾個步驟:

  1. 確保您的服務具有PerSession (或Singleton )實例上下文模式。 PerCall不允許您維護客戶端和服務器之間的永久連接。
  2. 確保ReceiveTimeout上的ReceiveTimeout足夠長。 它應該長於客戶端請求之間的時間間隔,以便WCF基礎結構不會終止空閑連接。
  3. 在服務類中,您必須記住回調通道。 這必須在客戶端調用的方法中完成。 因此,當您使用SendNotification方法時,應將OperationContext.Current.GetCallbackChannel<IStatusServiceCallBack>()的結果保存到StatusService私有字段中。 如果您的服務具有PerSession實例模式,則每個服務類將只有一個客戶端。 如果使用Singleton服務,則需要一組回調。
  4. 可以為回調方法提供返回值,但是您需要一個回調通道對象(在步驟3中保存)來調用它。
  5. 如果要在所有客戶端上調用回調方法,則應將所有客戶端回調保留在StatusService的靜態字段中,然后在所有客戶端上調用方法。
  6. 如果只想在特定客戶端上調用回調方法,則需要一種區分客戶端(ID,名稱等)並在字典中保留對回調通道的引用的方法。 如果您的服務具有PerSession實例上下文模式,則無法直接訪問服務對象,因此,最好還是以某種方式區分客戶端並通過靜態字段或其他方式訪問客戶端。 您還可以注入自定義工廠來創建服務對象,然后可以訪問它們(假設工廠還在某個位置注冊了這些對象)。

注意,如果客戶端斷開連接,它不會立即使回調通道無效。 僅當調用回調方法時,您才會發現-異常將被拋出。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM