昨天发布了《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的原因和解决方案
说明:发表这篇文章参考了如下作者的文章:
文章同步发表于我的个人网站:http://www.zuowenjun.cn/post/2015/03/25/133.html
WCF服务创建与使用(双工模式)的更多相关文章
-
WCF学习之旅—TCP双工模式(二十一)
WCF学习之旅—请求与答复模式和单向模式(十九) WCF学习之旅—HTTP双工模式(二十) 五.TCP双工模式 上一篇文章中我们学习了HTTP的双工模式,我们今天就学习一下TCP的双工模式. 在一个基 ...
-
WCF服务创建与使用(请求应答模式)
不说废话,直接上代码.以下服务创建是在独立的WCF类库中,若采用WCF应程程序,定义及创建服务代码均相同,但文件名不同,是CalculatorService.svc 第一步,定义服务契约(Servic ...
-
WCF学习之旅—HTTP双工模式(二十)
WCF学习之旅—请求与答复模式和单向模式(十九) 四.HTTP双工模式 双工模式建立在上文所实现的两种模式的基础之上,实现客户端与服务端相互调用:前面介绍的两种方法只是在客户端调用服务端的方法,然后服 ...
-
WCF服务创建与抛出强类型SOAP Fault
原创地址:http://www.cnblogs.com/jfzhu/p/4060666.html 转载请注明出处 前面的文章<WCF服务的异常消息>中介绍过,如果WCF Service发生 ...
-
wcf 服务创建,配置,测试
一.WCF创建: 常规的创建WCF服务是通过SOAP传输的,很多网站开发人员想放弃使用XML而使用JSON,这个时候可以参照:http://www.cnblogs.com/zhili/p/WCFRes ...
-
WCF服务创建到发布(SqlServer版)
在本示例开始之前,让我们先来了解一下什么是wcf? wcf有哪些特点? wcf是一个面向服务编程的综合分层架构.该架构的项层为服务模型层. 使用户用最少的时间和精力建立自己的软件产品和外界通信的模型. ...
-
[SignalR]SignalR与WCF双工模式结合实现服务端数据直推浏览器端
原文:[SignalR]SignalR与WCF双工模式结合实现服务端数据直推浏览器端 之前开发基于WinForm监控的软件,服务端基于Wcf实现,里面涉及双工模式,在客户端里面,采用心跳包机制保持与服 ...
-
WCF入门(五)---创建WCF服务
使用Microsoft Visual Studio2012创建WCF服务,理解如下所有必要的编码,更好地创建WCF服务的概念,这里做一个简单的任务. 启动Visual Studio 2012. 单击新 ...
-
WCF学习之旅—WCF服务部署到IIS7.5(九)
上接 WCF学习之旅—WCF寄宿前的准备(八) 四.WCF服务部署到IIS7.5 我们把WCF寄宿在IIS之上,在IIS中宿主一个服务的主要优点是在发生客户端请求时宿主进程会被自动启动,并且你可以 ...
随机推荐
-
【开源推荐】AllJoyn:打造全球物联网的通用开源框架
摘要:随着智能设备的发展,物联网逐渐进入了人们的生活.据预测,未来几乎一切东西(超过500亿台设备)都可以互联.高通公司发布了开源项目AllJoyn,这是一个能够使连接设备间进行互操作的通用软件框架和 ...
-
careercup-树与图 4.1
4.1 实现一个函数,检查二叉树是否平衡.在这个问题中,平衡树的定义如下:任意一个结点,其两颗子树的高度差不超过1. C++实现代码: #include<iostream> #includ ...
-
Showing 2 changed files with 3 additions and 3 deletions.
4 lib/matplotlib/__init__.py View @@ -126,9 +126,9 @@ def compare_versions(a, b): else: ...
-
玩转Web之easyui(三)-----easy ui dataGird 重新指定url以获取不同数据源信息
如果已经写了一个dataGird并且已经通过url绑定数据源,能不能在其他地方改变url使其从不同数据源获取信息,从而实现查询等操作?答案当然是肯定的,而且仅需要几行代码 $('#btnq').bin ...
-
wxpython 支持python语法高亮的自定义文本框控件的代码
在研发闲暇时间,把开发过程中比较重要的一些代码做个珍藏,下面的代码内容是关于wxpython 支持python语法高亮的自定义文本框控件的代码,应该是对大家也有用. import keywordimp ...
-
python 中深拷贝和浅拷贝的区别
通俗的理解,浅就是外面,深就是里面.浅拷贝的意思就是只拷贝外面的一层,深拷贝就是拷贝的里面的所有. 看两段代码: 元组: #!/usr/bin/env/python # -*-coding:utf-8 ...
-
springMVC中a标签传递多个参数到后台的应用
1.js页面:返回json填充HTML部分代码 <a class='byCard' href="+path+"/static/toCardView/"+ data. ...
-
LeetCode题解之Second Minimum Node In a Binary Tree
1.题目描述 2.问题分析 使用set. 3.代码 set<int> s; int findSecondMinimumValue(TreeNode* root) { dfs(root); ...
-
jvm本地实战
前言 由于上次线上full gc,让我这个没有机会实战接触jvm的人,尝到了一定的甜头,同时也觉得自己还有很多东西需要去实战并总结.这是一篇记录jvm配置参数,使用jvisualvm工具来让人对j ...
-
卡尔曼滤波算法--核心公式推导导论 - ZZ
卡尔曼滤波算法--核心公式推导导论 10 个月前 写在最前面:这是我第一篇专栏文章,感谢知乎提供这么一个平台,让自己能和大家分享知识.本人会不定期的开始更新文章,文章的内容应该集中在汽车动力学控制,整 ...