Wcf(,service callback client)

大家好,这段时间又研究了一下wcf的通信,一般都是client call service,service响应,返回信息给client,这个时候需要用到的binding(如wsHttpBinding,basicHttpBinding).
但是有时候,可能逻辑都写在服务端,然后界面写在客户端,控制界面的逻辑都是由服务端控制的,这就需要由服务端去callback客户端,这时候就需要用到binding(WSDualHttpBinding,NetTcpBinding)
在WCF预定义绑定类型中,WSDualHttpBinding和NetTcpBinding均提供了对双工通信的支持,但是两者在对双工通信的实现机制上却有本质的区别。WSDualHttpBinding是基于HTTP传输协议的;而HTTP协议本身是基于请求-回复的传输协议,基于HTTP的通道本质上都是单向的。WSDualHttpBinding实际上创建了两个通道,一个用于客户端向服务端的通信,而另一个则用于服务端到客户端的通信,从而间接地提供了双工通信的实现。而NetTcpBinding完全基于支持双工通信的TCP协议。
下面就是一个简单地列子:客户端调用服务端,服务端计算后,回调客户端显示。

第一步:定义服务契约和回调契约:

[ServiceContract(CallbackContract = typeof(ICalculatorCallback))]
    public interface ICalculator
    {
        [OperationContract(IsOneWay = true)]
        void Add(double x, double y);
    }

public interface ICalculatorCallback
    {
        [OperationContract(IsOneWay = true)]
        void DisplayResult(double x, double y, double result);
    }

其中发现在回调契约这可以不用定义[ServiceContract]

第二部:实现服务

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
    public class CalculatorService : ICalculator
    {
        public void Add(double x, double y)
        {
            double result = x + y;
            ICalculatorCallback callback = OperationContext.Current.GetCallbackChannel<ICalculatorCallback>();
            callback.DisplayResult(x, y, result);
        }
    }

第三部:配置文件

<system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="calculatorServieBehavior">
          <serviceMetadata httpGetEnabled="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>

    <services>
      <service name="Platform.Service.CalculatorService" behaviorConfiguration="calculatorServieBehavior">
                <endpoint address="" binding="wsDualHttpBinding" contract="Platform.Contract.ICalculator" name="wsDualHttpBinding"/>
                <endpoint address="" binding="netTcpBinding" contract="Platform.Contract.ICalculator" name="netTcpBinding"/>
                <host>
                    <baseAddresses>
                        <add baseAddress="http://127.0.0.1:9888/CalculatorService"/>                      
                        <add baseAddress="net.tcp://127.0.0.1:9999//CalculatorService"/>
                    </baseAddresses>
                </host>
            </service>
    </services>
  </system.serviceModel>

第四部:启动服务

using (ServiceHost calculatorSerivceHost = new ServiceHost(typeof(CalculatorService)))
            {
                calculatorSerivceHost.Opened += delegate
                {
                    Console.WriteLine("Calculator Service has begun to listen ... ...");
                };

                calculatorSerivceHost.Open();

                Console.Read();
            }

第五步:客户端调用,在客户端选择add service reference,添加CalculatorService服务,生成代理
代理主要包括两个接口服务接口和回调接口

第六步:客户端代码,继承实现服务端回调接口

 public class CalculateCallback : ICalculatorCallback
    {
        public void DisplayResult(double x, double y, double result)
        {
            Console.WriteLine("x + y = {2} when x = {0} and y = {1}", x, y, result);
        }
    }

第七部:实现客户端调用代理

InstanceContext instanceContext = new InstanceContext(new CalculateCallback());
            using (DuplexChannelFactory<ICalculator> channelFactory = new DuplexChannelFactory<ICalculator>(instanceContext, "wsDualHttpBinding"))
            {
                ICalculator proxy = channelFactory.CreateChannel();
                using (proxy as IDisposable)
                {
                    proxy.Add(1, 2);
                    Console.Read();
                }
            }
原文地址:https://www.cnblogs.com/gavinhuang/p/2991060.html