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

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

1.添加一个wcf类库

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.运行结果

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; }
   }
 

wcf中的使用全双工通信的更多相关文章

  1. wcf中的使用全双工通信(转)

    wcf中的使用全双工通信   wcf中的契约通信默认是请求恢复的方式,当客户端发出请求后,一直到服务端回复时,才可以继续执行下面的代码. 除了使用请求应答方式的通信外,还可以使用全双工.下面给出例子: ...

  2. 我的WCF之旅(3):在WCF中实现双工通信

    双工(Duplex)模式的消息交换方式体现在消息交换过程中,参与的双方均可以向对方发送消息.基于双工MEP消息交换可以看成是多个基本模式下(比如请求-回复模式和单项模式)消息交换的组合.双工MEP又具 ...

  3. 在WCF中实现双工通信

    双工(Duplex)模式的消息交换方式体现在消息交换过程中,参与的双方均可以向对方发送消息.基于双工MEP消息交换可以看成是多个基本模式下(比如请求-回复模式和单项模式)消息交换的组合.双工MEP又具 ...

  4. WCF学习之旅—WCF中传统的异常处理(十六)

    WCF中的异常处理 在软件开发过程中,不可能没有异常的出现,所以在开发过程中,对不可预知的异常进行解决时,异常处理显得尤为重要.对于一般的.NET系统来说,我们简单地借助try/catch可以很容易地 ...

  5. WCF初探-26:WCF中的会话

    理解WCF中的会话机制 在WCF应用程序中,会话将一组消息相互关联,从而形成对话.会话”是在两个终结点之间发送的所有消息的一种相互关系.当某个服务协定指定它需要会话时,该协定会指定所有调用(即,支持调 ...

  6. WCF中常用的binding方式

    WCF中常用的binding方式: BasicHttpBinding: 用于把 WCF 服务当作 ASMX Web 服务.用于兼容旧的Web ASMX 服务.WSHttpBinding: 比 Basi ...

  7. 重温WCF之WCF中可靠性会话(十四)

    1.WCF中可靠性会话在绑定层保证消息只会被传输一次,并且保证消息之间的顺序.当使用TCP(Transmission Control Protocol,传输控制协议)通信时,协议本身保证了可靠性.然而 ...

  8. WCF初探-22:WCF中使用Message类(上)

    前言 从我们学习WCF以来,就一直强调WCF是基于消息的通信机制.但是由于WCF给我们做了高级封装,以至于我们在使用WCF的时候很少了解到消息的内部机制.由于WCF的架构的可扩展性,针对一些特殊情况, ...

  9. 跟我一起学WCF(11)——WCF中队列服务详解

    一.引言 在前面的WCF服务中,它都要求服务与客户端两端都必须启动并且运行,从而实现彼此间的交互.然而,还有相当多的情况希望一个面向服务的应用中拥有离线交互的能力.WCF通过服务队列的方法来支持客户端 ...

随机推荐

  1. php学习笔记——基础知识(1)

    1.PHP 脚本在服务器上执行,然后向浏览器发送回纯 HTML 结果. 2.基础 PHP 语法 1)PHP 脚本可放置于文档中的任何位置. 2)PHP 脚本以 <?php 开头,以 ?> ...

  2. php获取url字符串截取路径的文件名和扩展名

    <?php //获取连接里边的id $url = 'http://www.rong123.com/cjbkscbsd/x_dfsdfs/24454_1_1.html'; function get ...

  3. Openjudge-NOI题库-出书最多

    描述 假定图书馆新进了m(10 ≤ m ≤ 999)本图书,它们都是由n(2 ≤ n ≤ 26)个作者独立或相互合作编著的.假设m本图书编号为整数(1到999),作者的姓名为字母('A'到'Z'),请 ...

  4. SharePoint:备份和还原

    注意事项: 1.备份和还原最好都用PowerShell,用时候用管理中心会遇到错误. 2.备份PowerShell要注意数据库服务器名,要与管理中心的数据库服务器一致,用ip可能会报错. Restor ...

  5. 高一的我曾对自己说"要放慢脚步去生活"!?

    看了高一的时候自己写的日记,瞬间被自己感动到了.以下是当时的几段感慨: 慢是一种放松.是生活的一种良好心态,喜欢这样放慢步伐地生活,那是一种享受! 但我们生活在一个快节奏的时代,我们总是被迫卷进那潮流 ...

  6. JavaScript-Curry

    Currying allows you to easily create custom functions by partially invoking an existing function. He ...

  7. Python基础篇-day11 - 协程

    本节主要内容: 1.Gevent协程2.Select\Poll\Epoll异步IO与事件驱动3.RabbitMQ队列 1.Gevent协程 1.1协程的好处 无需线程上下文切换的开销无需原子操作锁定及 ...

  8. @Scheduled(cron = "0 0 * * * ?")实现定时任务

    //每一个小时执行一次 @Scheduled(cron = "0 0 * * * ?") public void saveDailyScoreScheduled() { try { ...

  9. js数组、对象、正则

    1.根据给定的条件在原有的数组上,得到所需要的新数组var a = [-1, -1, 1, 2, -2, -2, -3, -3, 3, -3];function f(s, e) {    var re ...

  10. 浏览器 CSS 兼容写法的测试总结

    做前端最讨厌的就是 IE6,7,8,虽然被淘汰的浏览器,但是在中国用户仍然很多,不可能像国外网站一样直接就不管它了,这样会流失很多流量啊. 现在有了IE9,IE10还好些,几乎和 Chrome,Fir ...