• 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)

    需要把服务端配置文件中的Binding换成

    <endpoint address="" binding="BasicHttpBinding" contract="WcfServiceLibrary1.IService1">

    <endpoint address="" binding="wsDualHttpBinding" contract="WcfServiceLibrary1.IService1">

    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

    9.源码

     
     
    分类: WCF
     
    好文要顶 关注我 收藏该文
    1
    0
     
     
     
    « 上一篇:委托所想
    » 下一篇:wcf配置
    posted @ 2013-12-29 21:53 haiziguo 阅读(4619) 评论(3) 编辑 收藏

     
     
      
    #1楼 2015-11-13 13:26 勇哥哥  
    请教下楼主,这个全双工通信有什么好处或者说有什么优势,像这样的用请求-应答的形式就可以了又简单,为什么要弄这么复杂,或者说全双工通信在什么情况下使用最能体现它的价值所在,既然微软有这么个东西肯定也有它的用武之地的!
      
    #2楼 2015-11-13 15:43 勇哥哥  
    楼主,我想把回调的结果保存在一个变量中,怎样做,下面是代码:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    public partial class Form1 : Form
       {
           public Form1()
           {
               InitializeComponent();
               
           }
     
           private void button1_Click(object sender, EventArgs e)
           {
               MyData aData = new MyData();
               InstanceContext instanceContext = new InstanceContext(new CallbackHandler(aData));
     
               // 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);
               double a = aData.Datadouble;
     
               //MessageBox.Show(a.ToString());
               // 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();
           }
       }
     
       public class CallbackHandler :ServiceReference1.IService1Callback
       {
     
           MyData data = null;
           public CallbackHandler(MyData aData)
           {
               data = aData;
           }
           public void Equals(double result)
           {
               data.Datadouble = result;
               //Console.WriteLine("Result({0})", result);
           }
     
           public void Equation(string eqn)
           {
               data.DataString = eqn;
               //Console.WriteLine("Equation({0})", eqn);
           }
       }
     
       public class MyData
       {
           public double Datadouble { get; set; }
           public string DataString { get; set; }
       }
     
  • 相关阅读:
    机器学习: t-Stochastic Neighbor Embedding 降维算法 (二)
    数学辨异 —— 泰勒展开与等比数列求和
    HDU 4705 Y
    C#实现的内存分页机制的一个实例
    java程序获得SqlServer数据表的表结构
    GLSL中的各种变量总结
    HTTP协议学习
    Jedis中的一致性hash
    C语言数据结构----双向链表
    ios7毛玻璃效果实现
  • 原文地址:https://www.cnblogs.com/lizhenlin/p/6001949.html
Copyright © 2020-2023  润新知