前言:

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客户端为双工服务创建回调对象示例

 

  • 解决方案如下:

  

  • 工程结构说明:
  1. 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客户端为双工服务创建回调对象的更多相关文章

  1. BEGINNING SHAREPOINT&#174; 2013 DEVELOPMENT 第13章节--使用业务连接服务创建业务线解决方式 SP Apps中的BCS

    BEGINNING SHAREPOINT® 2013 DEVELOPMENT 第13章节--使用业务连接服务创建业务线解决方式  SP Apps中的BCS         之前的联系中,你安装了一个业 ...

  2. WCF系列教程之客户端异步调用服务

    本文参考自http://www.cnblogs.com/wangweimutou/p/4409227.html,纯属读书笔记,加深记忆 一.简介 在前面的随笔中,详细的介绍了WCF客户端服务的调用方法 ...

  3. WCF初探-14:WCF服务协定

    前言: 在前面的文章中,我们定义的服务协定上都会有一个ServiceContract的特性来修饰,这是因为服务契约的实现要靠ServiceContractAttribute 属性定义,然后使用一个或多 ...

  4. WCF初探文章列表

    WCF初探-1:认识WCF WCF初探-6:WCF服务配置 WCF初探-2:手动实现WCF程序 WCF初探-7:WCF服务配置工具使用 WCF初探-3:WCF消息交换模式之单向模式 WCF初探-8:W ...

  5. WCF初探-15:WCF操作协定

    前言: 在前面的文章中,我们定义服务协定时,在它的操作方法上都会加上OperationContract特性,此特性属于OperationContractAttribute 类,将OperationCo ...

  6. 【WCF系列】(四)WCF客户端怎么消费服务

    WCF客户端怎么消费服务 获取服务绑定协议.绑定和地址:实现方式 SvcUtil方式:SvcUtil.exe是一个命令行工具,位于:C:\Program Files (x86)\Microsoft S ...

  7. 【WCF全析(一)】--服务协定及消息模式

    上周微软开发布会说.NET支持完全跨平台和并开放Core源码的新闻,让我们顿时感到.NET要迎来它的春天.虽然早在几年前.NET就能开发Android和IOS,但是这次的跨平台把Linux都放到了微软 ...

  8. WCF初探-10:WCF客户端调用服务

    创建WCF 服务客户端应用程序需要执行下列步骤: 获取服务终结点的服务协定.绑定以及地址信息 使用该信息创建 WCF 客户端 调用操作 关闭该 WCF 客户端对象 WCF客户端调用服务存在以下特点: ...

  9. WCF初探-11:WCF客户端异步调用服务

    前言: 在上一篇WCF初探-10:WCF客户端调用服务 中,我详细介绍了WCF客户端调用服务的方法,但是,这些操作都是同步进行的.有时我们需要长时间处理应用程序并得到返回结果,但又不想影响程序后面代码 ...

随机推荐

  1. C# “快捷方式” 实现程序开机启动

    添加引用: COM : Windows Script Host Object Model Name: Interop.IWshRuntimeLibrary 添加命名空间: using IWshRunt ...

  2. js onmouseleave

    onmouseleave  no  propagation onmouseout   will  propagation

  3. Docker 在6.4上安装

      1 在 CentOS 6.4 上安装 docker docker当前官方只支持Ubuntu,所以在 CentOS 安装Docker比较麻烦(Issue #172). docker官方文档说要求Li ...

  4. ligerui_ligerTree_005_动态增加“树”节点

    动态添加ligerTree节点:效果图: 源码地址:http://download.csdn.net/detail/poiuy1991719/8571255 <%@ page language= ...

  5. [Phalcon] Phalcon系统默认事件列表

    版本: 2.0.6 Phalcon\Mvc\Application application:boot 可终止 是 参数 Phalcon\Events\Event $event 事件本身 Phalcon ...

  6. ASP.NET下载远程图片保存到本地的方法、保存抓取远程图片

    以下介绍两种方法:1.利用WebRequest,WebResponse 类 WebRequest wreq=WebRequest.Create("http://www.xueit.com/e ...

  7. 动态的计算行高 加载数据源 有多少显示多少 tableView 包含 colloctionView 显示复杂的界面写法

    有时候,我们经常碰到这样的需求 先遵守代理 @interface PublishCollectionCell ()<UICollectionViewDataSource, UICollectio ...

  8. 将数组里的元素拼接成sql里的in条件

    /** * 将数组里的元素拼接成sql里的in条件,如'a1','a2','a3' * @param array * @returns */function makeSqlInStr(array){ ...

  9. 基于Opencv和Mfc的图像处理增强库GOCVHelper(索引)

    GOCVHelper(GreenOpen Computer Version Helper )是我在这几年编写图像处理程序的过程中积累下来的函数库.主要是对Opencv的适当扩展和在实现Mfc程序时候的 ...

  10. R之data.table速查手册

    R语言data.table速查手册 介绍 R中的data.table包提供了一个data.frame的高级版本,让你的程序做数据整型的运算速度大大的增加.data.table已经在金融,基因工程学等领 ...