zoukankan      html  css  js  c++  java
  • (转)HTTP与Tcp协议下双工通信的差异

    原文地址:http://www.cnblogs.com/tyb1222/archive/2012/04/12/2443857.html

    WCF中经常会使用HTTP协议与Tcp协议来实现双工通讯,对应使用的协议分别为WsDualHttpBinding、NetTcpBinding。
    HTTP是基于应用层的协议,而Tcp是基于传输层的协议。Tcp经过三次握手建立起客户端到服务端的可靠连接,发起请求的客户端与回调客户端的服务端都使用一个连接就能完成。使用HTTP协议时,从客户端到服务端发起请求到服务端返回给客户端回复完成后,连接就关闭。
    由于HTTP的这种无连接性,基于WsDualHttpBinding的双工在进行通讯时实际上服务端在回调客户端时,会与NetTcpBinding在使用上有些差异。
    1、NetTcpBinding实现双工
    1.1契约部分:
    1.1.1 契约接口定义:
    复制代码
        [ServiceContract(CallbackContract = typeof(ICallback))]
        public interface ICalculator
        {
            [OperationContract]
            void Add(double x, double y);
        }
    复制代码
    1.1.2 回调接口定义:
        public interface ICallback
        {
            [OperationContract]
            void Display(double x, double y , double result);
        }
    1.2服务实现:
    复制代码
            public void Add(double x, double y)

            {
                Console.WriteLine("开始Add计算");
                ICallback callback = OperationContext.Current.GetCallbackChannel<ICallback>();
                callback.Display(x, y, x + y);
                Console.WriteLine(string.Format("{0},{1}", x, y));
            }

    复制代码
    服务通过OperationContext.Current.GetCallbackChannel<T>泛型方法获取对客户端回调代理类,对客户端进行回调
     
    复制代码
        public T GetCallbackChannel<T>()

        {
            if ((this.channel != null) && !this.IsUserContext)
            {
                return (T) this.channel.Proxy;
            }
            return default(T);
        }

    复制代码

    1.3 服务端配置:

    复制代码
    <system.serviceModel>

    <services>
                <service name="Services.CalculatorServices">
                    <endpoint address="Calaulator" binding="netTcpBinding" contract="Contract.ICalculator"></endpoint>
                    <host>
                        <baseAddresses>
                            <add baseAddress="net.tcp://127.0.0.1:6688"/>
                        </baseAddresses>
                    </host>
                </service>       
            </services>
    </system.serviceModel>

    复制代码
    1.4 客户端部分:
    回调接口的实现:
         public void Display(double x, double y, double result)

        {
                Console.WriteLine(string.Format("{0}+{1}={2}", x, y, result));
        }

    客户端配置:
    复制代码
    <system.serviceModel>       

    <client>
                <endpoint address="net.tcp://127.0.0.1:6688/Calaulator" binding="netTcpBinding" contract="Contract.ICalculator" name="calculatorTcp"></endpoint>
            </client>
    </system.serviceModel>

    复制代码
    接口调用:
    复制代码
                InstanceContext context = new InstanceContext(new CallBack());
                using (var channelFactory = new DuplexChannelFactory<ICalculator>(context, "calculatorTcp"))
                {
                    ICalculator proxy = channelFactory.CreateChannel();
                    proxy.Add(1.0, 2.0);
                    Console.ReadLine();
                }
    复制代码
    结果如下图:
    服务端:

    客户端:

    2、WsDualHttpBinding实现双工。

    操作系统:XP SP3。IIS版本:5.1
    同样以上面的契约为例.在数据包、或者请求-响应模式中,如果更换协议一般只需更改所使用的绑定即可。我们将客户端配置改为如下:
    复制代码
    <system.serviceModel>      
    <client>
                <endpoint address="http://127.0.0.1:8866/Calaulator/ws" binding="wsDualHttpBinding" contract="Contract.ICalculator" name="calculatorWsDual" ></endpoint>
            </client>
    </system.serviceModel>
    复制代码

    然后使用calculatorWsDual重新生成ChannelFactory:

    using (var channelFactory = new DuplexChannelFactory<ICalculator>(context, "calculatorWsDual"))
    运行调试:有如下异常:
    解决办法为Endpoint配置绑定行为,如下:

    复制代码
    <system.serviceModel>      
         <bindings>
                <wsDualHttpBinding>
                    <binding name ="myWsDualBinding" clientBaseAddress="http://127.0.0.1:3636/Service/CallbackService"></binding>
                </wsDualHttpBinding>
            </bindings>
            <client>
                <endpoint address="http://127.0.0.1:8888/Service/Calculator"  binding="wsDualHttpBinding" contract="Contracts.ICalculator"  name="calculatorService" bindingConfiguration="myWsDualBinding"/>
            </client>

    </system.serviceModel> 

    复制代码


    这样,问题就得以解决

  • 相关阅读:
    AngularJS ui-router (嵌套路由)
    解决Can't connect to MySQL server on 'localhost' (10048)
    PHP获取一年有几周以及每周开始日期和结束日期
    MySQL(八)之DML
    MySQL(七)MySQL常用函数
    MySQL(六)之MySQL常用操作符
    MySQL(五)之DDL(数据定义语言)与六大约束
    MySQL(四)之MySQL数据类型
    MySQL(三)之SQL语句分类、基本操作、三大范式
    linux命令详解之netstat
  • 原文地址:https://www.cnblogs.com/fcsh820/p/2458802.html
Copyright © 2011-2022 走看看