WCF操纵形式-双向操纵(双工通讯)示例演示
如果需要重新编写代码,几乎任何一门计算机语言都可以跨平台了,还用得着Java嘛,而且像PHP/C#等语言不需要修改代码都可以跨Windows/Linux。在后面一节中我们有演示了WCF操纵形式-单向操纵(单工通讯)。这节我们接着演示双向操纵(双工通讯)形式。在单向操纵形式中,客户端向服务器发送哀求,然后服务器回应。但服务器却不克不及自动向客户端发送信息。但在双向操纵形式中,不仅客户端能够向服务器发送哀求,服务器也能够自动向客户端播送动静(也就是回调客户端中的办法)。在WCF中,不是一切的绑建都能够完成双向操纵形式的,好比http协定,它自己就是基于哀求-复兴的传输形式,以是实质上是完成不了双向操纵的。但WCF供应了WSDualHttpBinding协定让我们在http上完成了双向操纵。实在WSDualHttpBinding并没有违背http单向传输的实质,它实践上是创立两个了通道,一个用于客户端向服务器哀求,一个用于服务器向客户端播送,直接完成了双向操纵。但《WCF服务编程》书上有说,WSDualHttpBinding没法穿越客户端与服务器的重重停滞,以是不同意利用WSDualHttpBinding来完成双向操纵。
那末除WSDualHttpBinding协定外,另有那些协定撑持双向操纵呢?就是NetTcpBinding与NetNamedPipeBinding了。这两个协定都是从实质上撑持双向操纵的。但我们这节的示例利用的是WSDualHttpBinding绑定。
上面入手下手示例:
起首仍是先界说服务左券:
publicinterfaceIMessageService
{
voidRegisterMes();
}
和单向操纵比拟,我们会发明服务左券上多了一行代码:
这是由于我们在界说左券的时分,就要事前商定好向客户端回调的办法。好比下面的代码就申明了该左券只能回调持续自ICallBack接口的客户端办法。
ICallBack接口固然也是本人界说的,本示例ICallBack接口以下:
publicinterfaceICallBack
{
voidSayHello(stringmes);
}
注重,ICallBack接口不必要声明ServiceContract特征,但SayHello()办法却必需声明OperationContract特征,并且必需指定IsOneWay=true,假如不指定它,我们在运转时服务端会激发InvalidOperationException非常。
上面完成wcf服务类:
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好厉害,希望有一天能去微软,虽然现在还距离遥远,呵呵:) 我觉得什么语言,精通就好,你要做的就是比其他80%的人都厉害,你就能得到只有20%的人才能得到的高薪。 ASP在执行的时候,是由IIS调用程序引擎,解释执行嵌在HTML中的ASP代码,最终将结果和原来的HTML一同送往客户端。 ASP(ActiveServerPages)是Microsfot公司1996年11月推出的WEB应用程序开发技术,它既不是一种程序语言,也不是一种开发工具,而是一种技术框架,不须使用微软的产品就能编写它的代码。 在调试JSP代码时,如果程序出错,JSP服务器会返回出错信息,并在浏览器中显示。这时,由于JSP是先被转换成Servlet后再运行的,所以,浏览器中所显示的代码出错的行数并不是JSP源代码的行数。 我觉得什么语言,精通就好,你要做的就是比其他80%的人都厉害,你就能得到只有20%的人才能得到的高薪。 asp.net最主要特性包括:◆编程代码更简洁◆网站可实现的功能更强大◆运行效率高◆节省服务器的动作资源 现在的ASP.net分为两个版本:1.1和2.0Asp.net1.1用VS2003(visualstudio2003)编程。Asp.net2.0用VS2005(visualstudio2005)编程。现在一般开发用的是VS2003。 同时也感谢博客园给我们这个平台,也感谢博客园的编辑们做成专题引来这么多高人指点。
页:
[1]