zoukankan      html  css  js  c++  java
  • wcf中的使用全双工通信(转)

    wcf中的使用全双工通信

     

    wcf中的契约通信默认是请求恢复的方式,当客户端发出请求后,一直到服务端回复时,才可以继续执行下面的代码。

    除了使用请求应答方式的通信外,还可以使用全双工。下面给出例子:

    1.添加一个wcf类库

    image

    2.在服务契约添加如下一个片段

    [ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples", SessionMode = SessionMode.Required, 
            CallbackContract = typeof(ICalculatorDuplexCallback))]

    public interface ICalculatorDuplex 
       { 
           [OperationContract(IsOneWay = true)] 
           void Clear(); 
           [OperationContract(IsOneWay = true)] 
           void AddTo(double n); 
           [OperationContract(IsOneWay = true)] 
           void SubtractFrom(double n); 
           [OperationContract(IsOneWay = true)] 
           void MultiplyBy(double n); 
           [OperationContract(IsOneWay = true)] 
           void DivideBy(double n); 
       }

    其中ICalculatorDuplexCallback为实现全双工客户端的接口

    3.定义ICalculatorDuplexCallback接口。该接口目的主要是回调客户端的方法。和服务端无关,所以让该接口的方法设置为单向的

    public interface ICalculatorDuplexCallback 

        [OperationContract(IsOneWay = true)] 
        void Equals(double result); 
        [OperationContract(IsOneWay = true)] 
        void Equation(string eqn); 

    4.由于回话是必须的,那么在契约实现的时候也要加上一个特性

      [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]

    public class Service1 : IService1 
       { 
           double result; 
           string equation; 
           ICalculatorDuplexCallback callback = null;

           public Service1() 
           { 
               result = 0.0D; 
               equation = result.ToString(); 
               callback = OperationContext.Current.GetCallbackChannel<ICalculatorDuplexCallback>(); 
           }

           public void Clear() 
           { 
               callback.Equation(equation + " = " + result.ToString()); 
               result = 0.0D; 
               equation = result.ToString(); 
           }

           public void AddTo(double n) 
           { 
               result += n; 
               equation += " + " + n.ToString(); 
               callback.Equals(result); 
           }

           public void SubtractFrom(double n) 
           { 
               result -= n; 
               equation += " - " + n.ToString(); 
               callback.Equals(result); 
           }

           public void MultiplyBy(double n) 
           { 
               result *= n; 
               equation += " * " + n.ToString(); 
               callback.Equals(result); 
           }

           public void DivideBy(double n) 
           { 
               result /= n; 
               equation += " / " + n.ToString(); 
               callback.Equals(result); 
           } 
    }

    5.接着在项目中添加一个控制台程序,添加服务。服务会报异常

    System.InvalidOperationException: 协定需要会话,但是绑定“BasicHttpBinding”不支持它或者因配置不正确而无法支持它。 
       在 System.ServiceModel.Description.DispatcherBuilder.BuildChannelListener(StuffPerListenUriInfo stuff, ServiceHostBase serviceHost, Uri listenUri, ListenUriMode listenUriMode, Boolean supportContextSession, IChannelListener& result) 
       在 System.ServiceModel.Description.DispatcherBuilder.InitializeServiceHost(ServiceDescription description, ServiceHostBase serviceHost) 
       在 System.ServiceModel.ServiceHostBase.InitializeRuntime() 
       在 System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout) 
       在 System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) 
       在 Microsoft.Tools.SvcHost.ServiceHostHelper.OpenService(ServiceInfo info)

    需要把服务端配置文件中改一下:

    <system.serviceModel>
    <services>
    <service name="WcfService1.Service1" behaviorConfiguration="WcfService1.Service1Behavior">

    <!-- Service Endpoints -->
    <!-- 除非完全限定,否则地址将与上面提供的基址相关 -->
    <endpoint address="" binding="wsDualHttpBinding" contract="WcfService1.IService1">
    <!--
    部署时,应删除或替换下列标识元素,以反映
    用来运行所部署服务的标识。删除之后,WCF 将
    自动推断相应标识。
    -->
    <identity>
    <dns value="localhost"/>
    </identity>
    </endpoint>
    <!-- Metadata Endpoints -->
    <!-- 元数据交换终结点供相应的服务用于向客户端做自我介绍。 -->
    <!-- 此终结点不使用安全绑定,应在部署前确保其安全或将其删除-->
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
    </service>
    </services>
    <behaviors>
    <serviceBehaviors>
    <behavior name="WcfService1.Service1Behavior">
    <!-- 为避免泄漏元数据信息,
    请在部署前将以下值设置为 false -->
    <serviceMetadata httpGetEnabled="False" httpsGetEnabled="False"/>
    <!-- 要接收故障异常详细信息以进行调试,
    请将以下值设置为 true。在部署前设置为 false
    以避免泄漏异常信息-->
    <serviceDebug includeExceptionDetailInFaults="True" />
    </behavior>
    </serviceBehaviors>
    </behaviors>
    </system.serviceModel>

    6.在控制台端,添加服务引用,实现服务定义的ICalculatorDuplexCallback接口(该接口自动生成的对应到服务引用中的IService1Callback)

    public class CallbackHandler : IService1Callback 
      { 
          public void Equals(double result) 
          { 
              Console.WriteLine("Result({0})", result); 
          }

          public void Equation(string eqn) 
          { 
              Console.WriteLine("Equation({0})", eqn); 
          } 
      }

    7.在main函数中,去调用服务

               InstanceContext instanceContext = new InstanceContext(new CallbackHandler());

                // Create a client 
                ServiceReference1.Service1Client client = new ServiceReference1.Service1Client(instanceContext);

                Console.WriteLine("Press <ENTER> to terminate client once the output is displayed."); 
                Console.WriteLine();

                // Call the AddTo service operation. 
                double value = 100.00D; 
                client.AddTo(value);

                // Call the SubtractFrom service operation. 
                value = 50.00D; 
                client.SubtractFrom(value);

                // Call the MultiplyBy service operation. 
                value = 17.65D; 
                client.MultiplyBy(value);

                // Call the DivideBy service operation. 
                value = 2.00D; 
                client.DivideBy(value);

                // Complete equation 
                client.Clear();

                Console.ReadLine();

                //Closing the client gracefully closes the connection and cleans up resources 
                client.Close();

    8.运行结果

    image

  • 相关阅读:
    git---如何解决The authenticity of host can't be established.
    前端模板引擎artTemplate.js
    微信小程序
    小程序的项目结构设计
    拖拽插件SortableJS
    iscroll.js的简单使用方法
    头疼的闭包
    关于setTimeout的妙用前端函数节流
    webpack 加载动态图片
    在React中实现条件渲染的7种方法
  • 原文地址:https://www.cnblogs.com/fuchongjundream/p/3833248.html
Copyright © 2011-2022 走看看