昨天发布了《WCF服务创建与使用(请求应答模式)》,今天继续学习与强化在双工模式下WCF服务创建与使用,步骤与代码如下。

第一步,定义服务契约(Service Contract),注意ServiceContract特性上需指定回调契约

//服务契约
using System.ServiceModel; namespace WcfServiceLibrary1
{
[ServiceContract(Namespace = "http://www.zuowenjun.cn",
CallbackContract = typeof(ICallback))]
public interface IHello
{
[OperationContract(IsOneWay = true)]
void SetName(string name);
}
} //回调契约(由于回调契约本质也是一个服务契约,所以定义方式和一般意义上的服务契约基本一样。
//有一点不同的是,由于定义服务契约时候已经通过[ServiceContract(CallbackContract=typeof(ICallback))]指明ICallback是一个服务契约了,所以ICallback不再需要添加ServiceContractAttribute特性)
using System.ServiceModel; namespace WcfServiceLibrary1
{
public interface ICallback
{
[OperationContract(IsOneWay = true)]
void ShowHello(string name);
}
}

第二步,实现服务契约,这里通过OperationContext.Current.GetCallbackChannel()获取回调契约

using System.ServiceModel;

namespace WcfServiceLibrary1
{
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]
public class HelloService:IHello
{
public void SetName(string name)
{
ICallback callback = OperationContext.Current.GetCallbackChannel<ICallback>();
callback.ShowHello(name);
}
}
}

注意:ConcurrencyMode = ConcurrencyMode.Reentrant是设置并发模式,Reentrant与Multiple均可适用于多并发,默认是Single

第三步,创建服务寄宿程序,方法很多,我这里采取常用的配置方法

1.CONFIG文件配置部份:

(注: 1.在WCF预定义绑定类型中,WSDualHttpBinding和NetTcpBinding均提供了对双工通信的支持,但是两者在对双工通信的实现机制上却有本质的区别。WSDualHttpBinding是基于HTTP传输协议的;而HTTP协议本身是基于请求-回复的传输协议,基于HTTP的通道本质上都是单向的。WSDualHttpBinding实际上创建了两个通道,一个用于客户端向服务端的通信,而另一个则用于服务端到客户端的通信,从而间接地提供了双工通信的实现。而NetTcpBinding完全基于支持双工通信的TCP协议。
2.若绑定类型采用NetTcpBinding,则地址应变更为:net.tcp://127.0.0.1:10800/HelloService,且不能有behaviorConfiguration配置)

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
</service>
<service name="WcfServiceLibrary1.HelloService">
<endpoint address="http://127.0.0.1:10800/HelloService" binding="wsDualHttpBinding" contract="WcfServiceLibrary1.IHello"></endpoint>
</service>
</services>
</system.serviceModel>
</configuration>

2.代码部份:

using System;
using WcfServiceLibrary1;
using System.ServiceModel;
using System.ServiceModel.Description; namespace ConsoleApplicationHost
{
class Program
{
static void Main(string[] args)
{
BuildHelloServiceHostByConfig();
} static void BuildHelloServiceHostByConfig()
{
using (ServiceHost host = new ServiceHost(typeof(HelloService)))
{
host.Opened += (s, e) => { Console.WriteLine("HelloService已经启动,按按回车键终止服务!"); };
host.Open();
Console.ReadLine();
}
}
}
}

第四步,客户端程序调用WCF服务

注:在客户端程序中首先需要创建或引用WCF服务类库,然后创建实现回调契约的类

实现回调契约:

using System;
using WcfServiceLibrary1; namespace ConsoleApplicationClient
{
public class HelloCallBack:ICallback
{
public void ShowHello(string name)
{
Console.WriteLine("Hello! {0}.欢迎光临IT文俊社区网,地址:www.zuowenjun.cn",name);
}
}
}

1.CONFIG文件配置部份:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<wsDualHttpBinding>
<binding name="HelloServiceBinding" clientBaseAddress="http://127.0.0.1:10801/HelloServiceCallback"></binding>
</wsDualHttpBinding>
</bindings>
<client>
<endpoint name="HelloService" address="http://127.0.0.1:10800/HelloService" binding="wsDualHttpBinding" contract="WcfServiceLibrary1.IHello">
</endpoint>
</client>
</system.serviceModel>
</configuration>

2.代码部份:

using System;
using System.ServiceModel;
using WcfServiceLibrary1; namespace ConsoleApplicationClient
{
class Program
{
static void Main(string[] args)
{
CallHelloService();
Console.WriteLine("按任意键结束。");
Console.Read();
} static void CallHelloService()
{
Console.Write("请输入您的网名:");
string input = Console.ReadLine();
InstanceContext instanceContext = new InstanceContext(new HelloCallBack());
using (DuplexChannelFactory<IHello> channel = new DuplexChannelFactory<IHello>(instanceContext, "HelloService"))
{
IHello proxy = channel.CreateChannel();
using (proxy as IDisposable)
{
proxy.SetName(input);
Console.ReadLine();//注意这句需保留,目的是为了阻止调用proxy的Dispose方法,因为该方法将会试图关闭底层的TCP连接。由于服务端的回调操作也会使用该TCP连接,如果在回调操作尚未执行完毕就试图关闭网络连接,将会导致回调无法正常执行
}
}
}
}
}

这里特别说明一下,建议在定义服务方法时,若没有返回值,建议为方法添加IsOneWay=True特性,可以使客户端不用等待请求回复,虽然设置ConcurrencyMode = ConcurrencyMode.Reentrant,但若采用WINFORM客户端使用,则会出现TIMEOUT错误,具体分析与解决方法,详见:我的WCF之旅(6):在Winform Application中调用Duplex Service出现TimeoutException的原因和解决方案

说明:发表这篇文章参考了如下作者的文章:

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

文章同步发表于我的个人网站:http://www.zuowenjun.cn/post/2015/03/25/133.html

WCF服务创建与使用(双工模式)的更多相关文章

  1. WCF学习之旅—TCP双工模式(二十一)

    WCF学习之旅—请求与答复模式和单向模式(十九) WCF学习之旅—HTTP双工模式(二十) 五.TCP双工模式 上一篇文章中我们学习了HTTP的双工模式,我们今天就学习一下TCP的双工模式. 在一个基 ...

  2. WCF服务创建与使用(请求应答模式)

    不说废话,直接上代码.以下服务创建是在独立的WCF类库中,若采用WCF应程程序,定义及创建服务代码均相同,但文件名不同,是CalculatorService.svc 第一步,定义服务契约(Servic ...

  3. WCF学习之旅—HTTP双工模式(二十)

    WCF学习之旅—请求与答复模式和单向模式(十九) 四.HTTP双工模式 双工模式建立在上文所实现的两种模式的基础之上,实现客户端与服务端相互调用:前面介绍的两种方法只是在客户端调用服务端的方法,然后服 ...

  4. WCF服务创建与抛出强类型SOAP Fault

    原创地址:http://www.cnblogs.com/jfzhu/p/4060666.html 转载请注明出处 前面的文章<WCF服务的异常消息>中介绍过,如果WCF Service发生 ...

  5. wcf 服务创建,配置,测试

    一.WCF创建: 常规的创建WCF服务是通过SOAP传输的,很多网站开发人员想放弃使用XML而使用JSON,这个时候可以参照:http://www.cnblogs.com/zhili/p/WCFRes ...

  6. WCF服务创建到发布(SqlServer版)

    在本示例开始之前,让我们先来了解一下什么是wcf? wcf有哪些特点? wcf是一个面向服务编程的综合分层架构.该架构的项层为服务模型层. 使用户用最少的时间和精力建立自己的软件产品和外界通信的模型. ...

  7. [SignalR]SignalR与WCF双工模式结合实现服务端数据直推浏览器端

    原文:[SignalR]SignalR与WCF双工模式结合实现服务端数据直推浏览器端 之前开发基于WinForm监控的软件,服务端基于Wcf实现,里面涉及双工模式,在客户端里面,采用心跳包机制保持与服 ...

  8. WCF入门(五)---创建WCF服务

    使用Microsoft Visual Studio2012创建WCF服务,理解如下所有必要的编码,更好地创建WCF服务的概念,这里做一个简单的任务. 启动Visual Studio 2012. 单击新 ...

  9. WCF学习之旅—WCF服务部署到IIS7.5(九)

    上接   WCF学习之旅—WCF寄宿前的准备(八) 四.WCF服务部署到IIS7.5 我们把WCF寄宿在IIS之上,在IIS中宿主一个服务的主要优点是在发生客户端请求时宿主进程会被自动启动,并且你可以 ...

随机推荐

  1. 【腾讯bugly干货分享】解耦---Hybrid H5跨平台性思考

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://bugly.qq.com/bbs/forum.php?mod=viewthread&tid=1275& ...

  2. ENode 1.0 - Command Service设计思路

    开源地址:https://github.com/tangxuehua/enode 上一篇文章,介绍了enode框架的物理部署思路.本文我们再简单分析一下Command Service的API设计: C ...

  3. java提高篇(二四)-----HashSet

          在前篇博文中(java提高篇(二三)-----HashMap)详细讲解了HashMap的实现过程,对于HashSet而言,它是基于HashMap来实现的,底层采用HashMap来保存元素. ...

  4. kafka的一些认识

    原创文章转载请注明出处:@协思, http://zeeman.cnblogs.com   近来无事研究了一下kafka,并且用golang连接kafka做了producer和consumer的简单测试 ...

  5. .net 时间戳和日期互转

    1.时间戳转日期 public static DateTime IntToDateTime(int timestamp) {     ,,)).AddSeconds(timestamp); } 调用: ...

  6. js模版引擎handlebars.js实用教程——由于if功力不足引出的Helper

    返回目录 <!DOCTYPE html> <html> <head> <META http-equiv=Content-Type content=" ...

  7. Django集成百度富文本编辑器uEditor

    UEditor是由百度web前端研发部开发所见即所得富文本web编辑器,具有轻量,可定制,注重用户体验等特点,开源基于MIT协议,允许自由使用和修改代码. 首先从ueEditor官网下载最新版本的包, ...

  8. Senparc.Weixin.MP SDK 微信公众平台开发教程(三):微信公众平台开发验证

    要对接微信公众平台的"开发模式",即对接到自己的网站程序,必须在注册成功之后(见Senparc.Weixin.MP SDK 微信公众平台开发教程(一):微信公众平台注册),等待官方 ...

  9. 我心中的核心组件(可插拔的AOP)~第四回 异常拦截器

    回到目录 之前说过有关拦截器的文章,第二回  缓存拦截器,事实上,在那讲里说的最多是AOP和缓存组件,对于拦截的概念并没有详细的说明,这一讲,不说AOP,主要说一下拦截器,拦截器Interceptio ...

  10. Docker镜像

    docker镜像123? 额,由于没有实验环境,没有亲手实践,因此理解可能有不对的地方. 反正也是学习笔记,以后再修改吧... docker的镜像跟virtualbox的镜像不一样.在虚拟机中,镜像是 ...