仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 753|回复: 8
打印 上一主题 下一主题

[学习教程] WCF操纵形式-双向操纵(双工通讯)示例演示

[复制链接]
飘灵儿 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-16 14:19:16 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
如果需要重新编写代码,几乎任何一门计算机语言都可以跨平台了,还用得着Java嘛,而且像PHP/C#等语言不需要修改代码都可以跨Windows/Linux。在后面一节中我们有演示了WCF操纵形式-单向操纵(单工通讯)。这节我们接着演示双向操纵(双工通讯)形式。

在单向操纵形式中,客户端向服务器发送哀求,然后服务器回应。但服务器却不克不及自动向客户端发送信息。但在双向操纵形式中,不仅客户端能够向服务器发送哀求,服务器也能够自动向客户端播送动静(也就是回调客户端中的办法)。在WCF中,不是一切的绑建都能够完成双向操纵形式的,好比http协定,它自己就是基于哀求-复兴的传输形式,以是实质上是完成不了双向操纵的。但WCF供应了WSDualHttpBinding协定让我们在http上完成了双向操纵。实在WSDualHttpBinding并没有违背http单向传输的实质,它实践上是创立两个了通道,一个用于客户端向服务器哀求,一个用于服务器向客户端播送,直接完成了双向操纵。但《WCF服务编程》书上有说,WSDualHttpBinding没法穿越客户端与服务器的重重停滞,以是不同意利用WSDualHttpBinding来完成双向操纵。

那末除WSDualHttpBinding协定外,另有那些协定撑持双向操纵呢?就是NetTcpBinding与NetNamedPipeBinding了。这两个协定都是从实质上撑持双向操纵的。但我们这节的示例利用的是WSDualHttpBinding绑定。

上面入手下手示例:
起首仍是先界说服务左券:
[ServiceContract(CallbackContract=typeof(ICallBack))]
publicinterfaceIMessageService
{
[OperationContract]
voidRegisterMes();
}

和单向操纵比拟,我们会发明服务左券上多了一行代码:
[ServiceContract(CallbackContract=typeof(ICallBack))]

这是由于我们在界说左券的时分,就要事前商定好向客户端回调的办法。好比下面的代码就申明了该左券只能回调持续自ICallBack接口的客户端办法。

ICallBack接口固然也是本人界说的,本示例ICallBack接口以下:
publicinterfaceICallBack
{
[OperationContract(IsOneWay=true)]
voidSayHello(stringmes);
}

注重,ICallBack接口不必要声明ServiceContract特征,但SayHello()办法却必需声明OperationContract特征,并且必需指定IsOneWay=true,假如不指定它,我们在运转时服务端会激发InvalidOperationException非常。

上面完成wcf服务类:
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
publicclassMessageService:IMessageService,IDisposable
{
        //代码段一
publicstaticList<ICallBack>CallBackList
{
get;
set;
}
        //代码段二
publicMessageService()
{
CallBackList=newList<ICallBack>();
}

        //代码段三
publicvoidRegisterMes()
{
ICallBackcallback=OperationContext.Current.GetCallbackChannel<ICallBack>();
CallBackList.Add(callback);

stringSessionid=OperationContext.Current.SessionId;
Console.WriteLine("{0}isregister",Sessionid);
OperationContext.Current.Channel.Closing+=
delegate
{
lock(CallBackList)
{
CallBackList.Remove(callback);
Console.WriteLine("{0}isremove",Sessionid);
}
};
}

//代码段四
publicvoidDispose()
{
CallBackList.Clear();
}
}

在下面代码中起首我们界说了一个静态的List<ICallBack>属性CallBackList(代码段一)。我们用这个属性来装载一切注册到服务下面的客户端实例,以便前面我们向一切的客户端播送动静。

然后在服务的机关函数中实例化CallBackList静态属性(代码段二)。

重点是服务器端猎取到一切的客户端实例,即(代码段三)。在服务器端我们要利用OperationContext.Current.GetCallbackChannel()办法来猎取客户端实例,如代码段三中的上面代码:
ICallBackcallback=OperationContext.Current.GetCallbackChannel<ICallBack>();

将callback装载到CallBackList属性中后,注册实践就已完成了,代码段三中前面的代码是在注册时输入一些信息便利我们检察效果,没有也没有干系。
OperationContext.Current.SessionId猎取到以后注册的客户端会话ID,这个ID是独一的。注册时服务器端输入”会话isregister”,然后客户端在封闭的时分服务器端输入”会话isremove”。

代码段四是在服务封闭时清空静态属性CallBackList中的一切值。

完成了服务类,就入手下手我们服务的托管了。我们在把持台程序中投止服务,由于把持台程序完成起来复杂,代码以下:
classProgram
{
staticvoidMain(string[]args)
{
using()ServiceHosthost=newServiceHost(typeof(MessageService))
{
host.AddServiceEndpoint(typeof(IMessageService),newWSDualHttpBinding(),"http://localhost:8011");
host.Opening+=delegate{Console.WriteLine("服务开启:{0}",DateTime.Now.ToString());};
host.Open();

start:
stringcommand=Console.ReadLine();
switch(command)
{
case"send":
lock(MessageService.CallBackList)
{
foreach(ICallBackcallbackinMessageService.CallBackList)
{
callback.SayHello(string.Format("hello,我是服务器{0}",DateTime.Now.ToString()));
}
}
gotostart;
case"close":
host.Close();
break;
default:
Console.WriteLine("nocommand!");
gotostart;
}
}
}
}

程序一入手下手,我们声了然服务ServiceHosthost=newServiceHost(typeof(MessageService),
然后给服务增加闭幕点信息,界说Opening事务,直至服务翻开。

在这段代码中我利用了goto语句,人人不要计算在程序利用goto是不是妥善,由于这仅仅是一个演示。Switch语句处置了我们在服务端把持台输出的命令,假如我们输出了send命令,那末服务就会轮环挪用一切已在服务端注册了的客户真个SayHello办法。输出了close命令,就会封闭服务,别的的命令不实行。

好了,一切服务真个代码全体完成,上面入手下手客户真个代码:
我们是利用编程的办法来挪用服务,以是请在客户端项目中增加对服务端项目标援用。
在客户端我们起首必要完成服务端界说的回调办法ICallBack,代码以下:
publicclassMyCallBack:Host.ICallBack
{
publicvoidSayHello(stringmes)
{
Console.WriteLine(mes);
Console.WriteLine("2秒种后显现客户端信息!");
Thread.Sleep(2000);
Console.WriteLine("hello,我是客户端{0}",DateTime.Now.ToString());
}
}

然后是完成对服务的挪用:
classProgram
{
staticvoidMain(string[]args)
{
Host.ICallBackcallback=newMyCallBack();
InstanceContextcontext=newInstanceContext(callback);
WSDualHttpBindingbinding=newWSDualHttpBinding();
binding.ClientBaseAddress=newUri("http://localhost:8010");
using(DuplexChannelFactory<Host.IMessageService>proxy=newDuplexChannelFactory<Host.IMessageService>(context,binding))
{
Host.IMessageServiceclient=proxy.CreateChannel(newEndpointAddress("http://localhost:8011"));
client.RegisterMes();

Console.ReadLine();
}
}
}

注重代码binding.ClientBaseAddress=newUri("http://localhost:8010");假如我们用的是win7大概以上的体系,这段代码其实不必要。但假如是xp体系,就必要了,由于xp体系下的iis5.x默许的回调监听端口是80端口,假如假如不从头ClientBaseAddress,就会报出80端口正在利用的毛病。并且xp体系下即便我们重写了ClientBaseAddress属性,也只能同时运转一个客户端窗口,但假如是win7体系,则能够同时运转多个客户端窗口。

上面我们看一下运转的效果。
起首是运转服务端窗口,效果以下:



然后运转客户端窗口,服务端窗口会打印出客户真个注册工夫,以下:



然后我们在服务端窗口输出send命令,客户端会打印信息以下:



至此,这节WCF操纵形式-单向操纵(单工通讯)演示就完成了,全体代码下载链接以下:
WCF双工通讯演示实例下载我之所以想学。NET,是因为一直觉的BILLGATES好厉害,希望有一天能去微软,虽然现在还距离遥远,呵呵:)
深爱那片海 该用户已被删除
沙发
发表于 2015-1-18 12:53:06 | 只看该作者
我觉得什么语言,精通就好,你要做的就是比其他80%的人都厉害,你就能得到只有20%的人才能得到的高薪。
小妖女 该用户已被删除
板凳
发表于 2015-1-24 20:02:30 | 只看该作者
ASP在执行的时候,是由IIS调用程序引擎,解释执行嵌在HTML中的ASP代码,最终将结果和原来的HTML一同送往客户端。
透明 该用户已被删除
地板
发表于 2015-2-2 13:08:01 | 只看该作者
ASP(ActiveServerPages)是Microsfot公司1996年11月推出的WEB应用程序开发技术,它既不是一种程序语言,也不是一种开发工具,而是一种技术框架,不须使用微软的产品就能编写它的代码。
山那边是海 该用户已被删除
5#
发表于 2015-2-7 21:40:55 | 只看该作者
在调试JSP代码时,如果程序出错,JSP服务器会返回出错信息,并在浏览器中显示。这时,由于JSP是先被转换成Servlet后再运行的,所以,浏览器中所显示的代码出错的行数并不是JSP源代码的行数。
爱飞 该用户已被删除
6#
发表于 2015-2-23 13:54:11 | 只看该作者
我觉得什么语言,精通就好,你要做的就是比其他80%的人都厉害,你就能得到只有20%的人才能得到的高薪。
老尸 该用户已被删除
7#
发表于 2015-3-7 09:28:20 | 只看该作者
asp.net最主要特性包括:◆编程代码更简洁◆网站可实现的功能更强大◆运行效率高◆节省服务器的动作资源
灵魂腐蚀 该用户已被删除
8#
发表于 2015-3-14 20:54:23 | 只看该作者
现在的ASP.net分为两个版本:1.1和2.0Asp.net1.1用VS2003(visualstudio2003)编程。Asp.net2.0用VS2005(visualstudio2005)编程。现在一般开发用的是VS2003。
活着的死人 该用户已被删除
9#
发表于 2015-3-21 15:32:46 | 只看该作者
同时也感谢博客园给我们这个平台,也感谢博客园的编辑们做成专题引来这么多高人指点。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-6-14 02:47

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表