WCF初探-13:WCF客户端为双工服务创建回调对象
前言:
在WCF初探-5:WCF消息交换模式之双工通讯(Duplex)博文中,我讲解了双工通信服务的一个应用场景,即订阅和发布模式,这一篇,我将通过一个消息发送的例子讲解一下WCF客户端如何为双工服务创建回调对象。
双工服务指定一个回调协定,客户端应用程序必须实现该协定以便提供一个该服务能够根据协定要求调用的回调对象。虽然回调对象不是完整的服务(例如,您无法使用回调对象启动一个通道),但是为了实现和配置,这些回调对象可以被视为一种服务。
双工服务的客户端必须:
- 实现一个回调协定类。
- 创建回调协定实现类的一个实例,并使用该实例创建传递给 WCF 客户端构造函数的 System.ServiceModel.InstanceContext 对象。
- 调用操作并处理操作回调。
双工 WCF 客户端对象除了会公开支持回调所必需的功能(包括回调服务的配置)以外,其他的功能和它们的非双工对应项相同。
示例说明:
- Service服务契约中定义了一个发送方法Send,采用IsOneWay=true,供客户端调用,向服务端发送消息。Service中还提供了用于双工通信的回调接口IMessageExchangeCallback,该接口中定义了服务端接收消息后向客户端发送消息的方法Receive,此方法就是客户端发送消息到服务端后,服务端调用回调方法,将消息发送到客户端。
- Client需要实现双工协定回调接口的类CallBackHandler,并实现Receive方法。
- 针对双工协定生成的 WCF 客户端需要在构造时提供一个 InstanceContext 类。此 InstanceContext 类用作实现回调接口并处理从服务发送回的消息的对象所在的位置。InstanceContext 类是用 CallbackHandler 类的实例构造的。此对象处理通过回调接口从服务发送到客户端的消息。

WCF客户端为双工服务创建回调对象示例:
- 解决方案如下:

- 工程结构说明:
- Service:类库程序,定义服务契约接口和回调接口,实现服务契约。在IMessageExchange中定义了Send方法,并且还定义了双工服务回调接口 IMessageExchangeCallback。
IMessageExchange.cs的代码如下:
using System.ServiceModel;
using System.Collections.Generic;
using System.Runtime.Serialization; namespace Service
{
[ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(IMessageExchangeCallback))]
public interface IMessageExchange
{
[OperationContract(IsOneWay=true)]
void Send(string message);
} public interface IMessageExchangeCallback
{
[OperationContract(IsOneWay = true)]
void Receive(string message);
}
}
MessageExchange.cs的代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel; namespace Service
{
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
public class MessageExchange : IMessageExchange
{
public void Send(string message)
{
Console.WriteLine("服务端监听客户端发出的消息:" + message);
Callback.Receive(message); } IMessageExchangeCallback Callback
{
get
{
return OperationContext.Current.GetCallbackChannel<IMessageExchangeCallback>();
}
}
}
}
注意:回调契约接口IMessageExchangeCallback中的Receive方法是在客户端实现的,所以如果需要在服务端调用回调方法就必须通过当前操作的实例上下文来获取,即上面代码中的Callback对象。
2. Host:控制台应用程序。提供服务寄宿程序,添加对Srevice程序集的引用。完成配置文件和代码就可以承载服务。
Program.cs的代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Service;
using System.ServiceModel; namespace Host
{
class Program
{
static void Main(string[] args)
{
using (ServiceHost host = new ServiceHost(typeof(MessageExchange)))
{
host.Opened += delegate { Console.WriteLine("服务已经启动,按任意键终止!"); };
host.Open();
Console.Read();
}
}
}
}
App.config的代码如下:
<?xml version="1.0"?>
<configuration>
<system.serviceModel> <services>
<service name="Service.MessageExchange" behaviorConfiguration="mexBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:1234/MessageExchange/"/>
</baseAddresses>
</host>
<endpoint address="" binding="wsDualHttpBinding" contract="Service.IMessageExchange" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services> <behaviors>
<serviceBehaviors>
<behavior name="mexBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors> </system.serviceModel>
</configuration>
3. Client:控制台应用程序。客户端程序,启动服务承载程序Host后,添加对服务地址http://localhost:1234/MessageExchange/的引用,将命名空间修改为
MessageExchangeServiceRef,之后在Program.cs完成对双工服务回调接口IMessageExchangeCallback的实现和对服务方法的调用。Program.cs的代码如下:
using System;
using Client.MessageExchangeServiceRef;
using System.ServiceModel; namespace Client1
{ public class CallBackHandler : IMessageExchangeCallback
{
public void Receive(string message)
{
Console.WriteLine("客户端监听服务端接收的消息:" + message);
}
} class Program
{
static void Main(string[] args)
{
InstanceContext instanceContext = new InstanceContext(new CallBackHandler());
MessageExchangeClient proxy = new MessageExchangeClient(instanceContext);
proxy.Send("Wcf Duplex"); Console.Read();
}
}
}
运行结果如下:

总结:
- 本文模拟了客户端向服务端发送消息,服务端接收到消息后,将监听到的消息显示在客户端。希望通过本示例对双工通信有进步一的认识,关于实例和会话,我将在后面的博文中做解析。

WCF初探-13:WCF客户端为双工服务创建回调对象的更多相关文章
- BEGINNING SHAREPOINT® 2013 DEVELOPMENT 第13章节--使用业务连接服务创建业务线解决方式 SP Apps中的BCS
BEGINNING SHAREPOINT® 2013 DEVELOPMENT 第13章节--使用业务连接服务创建业务线解决方式 SP Apps中的BCS 之前的联系中,你安装了一个业 ...
- WCF系列教程之客户端异步调用服务
本文参考自http://www.cnblogs.com/wangweimutou/p/4409227.html,纯属读书笔记,加深记忆 一.简介 在前面的随笔中,详细的介绍了WCF客户端服务的调用方法 ...
- WCF初探-14:WCF服务协定
前言: 在前面的文章中,我们定义的服务协定上都会有一个ServiceContract的特性来修饰,这是因为服务契约的实现要靠ServiceContractAttribute 属性定义,然后使用一个或多 ...
- WCF初探文章列表
WCF初探-1:认识WCF WCF初探-6:WCF服务配置 WCF初探-2:手动实现WCF程序 WCF初探-7:WCF服务配置工具使用 WCF初探-3:WCF消息交换模式之单向模式 WCF初探-8:W ...
- WCF初探-15:WCF操作协定
前言: 在前面的文章中,我们定义服务协定时,在它的操作方法上都会加上OperationContract特性,此特性属于OperationContractAttribute 类,将OperationCo ...
- 【WCF系列】(四)WCF客户端怎么消费服务
WCF客户端怎么消费服务 获取服务绑定协议.绑定和地址:实现方式 SvcUtil方式:SvcUtil.exe是一个命令行工具,位于:C:\Program Files (x86)\Microsoft S ...
- 【WCF全析(一)】--服务协定及消息模式
上周微软开发布会说.NET支持完全跨平台和并开放Core源码的新闻,让我们顿时感到.NET要迎来它的春天.虽然早在几年前.NET就能开发Android和IOS,但是这次的跨平台把Linux都放到了微软 ...
- WCF初探-10:WCF客户端调用服务
创建WCF 服务客户端应用程序需要执行下列步骤: 获取服务终结点的服务协定.绑定以及地址信息 使用该信息创建 WCF 客户端 调用操作 关闭该 WCF 客户端对象 WCF客户端调用服务存在以下特点: ...
- WCF初探-11:WCF客户端异步调用服务
前言: 在上一篇WCF初探-10:WCF客户端调用服务 中,我详细介绍了WCF客户端调用服务的方法,但是,这些操作都是同步进行的.有时我们需要长时间处理应用程序并得到返回结果,但又不想影响程序后面代码 ...
随机推荐
- git设置hooks 钩子
github是可以设置hooks的,看:在设置webhooks & services,可在Just the push event.是设定向你的服务器发请求,然后再做相应的处理. https:/ ...
- C#.NET 字符串转数组,数组转字符串
string str = "1,2,3,4,5,6,7"; string[] strArray = str.Split(','); //字符串转数组 ...
- WebApi 接口测试工具:WebApiTestClient
文章来源:http://www.cnblogs.com/landeanfen/p/5210356.html 一.WebApiTestClient介绍 1.WebApiTestClient组件作用主要有 ...
- css3创建一个上下线性渐变色背景的div
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title> ...
- Qt之多窗口切换
在新建对象(下一页面)的时候,把自身的this指针带进去,然后把自身hide(),隐藏起来,在(下一页面中)要回退的时候只需通过: 1. parentWidget()->show(); //显示 ...
- 从简单需求到OLAP的RANK系列函数
同事问了一个非常简单的问题,怎么取出每个partition里面另外一个列的最小值? create table t1 (int c1, int c2); 假如按照c2分区,0-10,10-20,20 ...
- swif tableview全选
func selctAll() { idArr.removeAll() for var i = 0; i<sellingArr.count; i++ { let path: NSIndexPat ...
- WordPress 添加Meta Box的方法步骤
需要使用到add meta boxes Action,该Action允许我们为任何文章类型注册Meta Box,在该Action中,我们需要使用add_meta_box()方法来添加Meta Box的 ...
- 二、快速起步(Mysql镜像)
1.登录镜像站点 docker login daocloud.io 用户名 密码 邮箱 1.1 拉取镜像 docker pull [option] name:[tag] 例如 docker pull ...
- 升级PHP
wget http://down.wdlinux.cn/in/php_up53.shsh php_up53.sh