【问题标题】:WCF NetTcp duplex channel independent communicationWCF NetTcp 双工通道独立通信
【发布时间】:2017-11-24 08:30:53
【问题描述】:

我想创建一个双工 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);
    }
}

【问题讨论】:

    标签: wcf nettcpbinding duplex-channel


    【解决方案1】:

    您是对的,您需要使用客户端建立的连接。为此,您必须执行几个步骤:

    1. 确保您的服务具有PerSession(或Singleton)实例上下文模式。 PerCall 不允许您在客户端和服务器之间保持永久连接。
    2. 确保绑定上的ReceiveTimeout 足够长。它应该比客户端请求之间的时间长,以便 WCF 基础结构不会终止空闲连接。
    3. 在您的服务类中,您必须记住回调通道。这必须在客户端调用的方法中完成。因此,当您在 SendNotification 方法中时,OperationContext.Current.GetCallbackChannel&lt;IStatusServiceCallBack&gt;() 的结果应该保存到 StatusService 的私有字段中。如果您的服务具有PerSession 实例模式,那么每个服务类将只有一个客户端。对于Singleton 服务,您需要一个回调集合。
    4. 回调方法有返回值是可以的,但是你需要一个回调通道对象(保存在第3步)来调用它。
    5. 如果要在所有客户端上调用回调方法,则应将所有客户端回调保留在StatusService 的静态字段中,然后在所有客户端上调用方法。
    6. 如果您只想在特定客户端上调用回调方法,那么您需要一种方法来区分客户端(ID、名称等)并将对回调通道的引用保存在字典中。如果您的服务具有PerSession 实例上下文模式,您无法直接访问服务对象,因此以某种方式区分客户端并通过静态字段或其他方式访问它们仍然是个好主意。您还可以注入您的自定义工厂以创建服务对象,然后访问它们(假设工厂也在某处注册这些对象)。

    请注意,如果客户端断开连接,它不会立即使回调通道无效。只有当你调用回调方法时你才会发现——异常会被抛出。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-23
      • 2017-06-28
      • 2012-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-04
      • 1970-01-01
      相关资源
      最近更新 更多