合肥程序员群:49313181。 合肥实名程序员群:128131462 (不愿透露姓名和信息者勿加入)
Q Q:408365330 E-Mail:egojit@qq.com
Q Q:408365330 E-Mail:egojit@qq.com
WCF中双程操作。这里主要介绍心跳技术。
每当客户端给服务端发送消息时,服务端在接收到消息后,给客户端反馈一条消息(称为回调操作),而这个反馈消息不需要考虑客户端是否收到这个反馈消息。
本文介绍一个简单例子,例子展示如何实现服务端与客户端的交互。
一、服务端
首先写服务契约
01.[ServiceContract(CallbackContract = typeof(IWCFServiceCallBack))] 02.public interface IWCFService 03.{ 04. //操作契约 05. [OperationContract] 06. string OprT(string name); 07.}
注:
CallbackContract= typeof(IWCFServiceCallBack)表示服务端接收到客户端的消息时给客户的响应(即回调操作),IWCFServiceCallBack即为回调契约,定义如下:
01.public interface IWCFServiceCallBack 02.{ 03. //操作契约 04. [OperationContract(IsOneWay = true)] 05. void FeedBack(string info); 06.}
注:
1.回调服务契约,由于回调方法在客户端执行,因此无须添加 ServiceContract特性。
2.对于成功后回调反馈操作,服务器无须获取其返回信息,因此添加 IsOneWay=true 特性。
接着,服务端实现契约:
01.public class WCFService : IWCFService 02.{ 03. //获取当前操作客户端对象实例 04. IWCFServiceCallBack callback 05. = OperationContext.Current.GetCallbackChannel<IWCFServiceCallBack>(); 06. //实现接口定义的方法(在服务端运行) 07. public string OprT(string clientPCName) 08. { 09. Console.WriteLine("收到客户端的连接消息消息:{0} {1}", DateTime.Now, clientPCName); 10. callback.FeedBack("进过分析后的用户名" + clientPCName.Split('-')[0]); 11. //这边可以返回任何客户端需要的信息//如果客户端不需要信息可以将此函数设为void返回类型 12. return "客户端连接正常"; 13. } 14.}
二、宿主,主要工作就是开启服务
配置文件如下:
01.<?xml version="1.0" encoding="utf-8" ?> 02.<configuration> 03. <system.serviceModel> 04. <services> 05. <service behaviorConfiguration="WCFService.WCFServiceBehavior" 06. name="Service0413.WCFService"> 07. <endpoint 08. address="net.tcp://localhost:9000/WCFService" 09. binding="netTcpBinding" 10. contract="Service0413.IWCFService"> 11. </endpoint> 12. <host> 13. <baseAddresses> 14. <!--这里的baseAddress是客户端服务引用的URI--> 15. <add baseAddress="http://localhost:9090/"/> 16. </baseAddresses> 17. </host> 18. </service> 19. </services> 20. <behaviors> 21. <serviceBehaviors> 22. <behavior name="WCFService.WCFServiceBehavior"> 23. <!--为了可以通过URI引用服务,这里需设置httpGetEnabled为true--> 24. <serviceMetadata httpGetEnabled="true" /> 25. <serviceDebug includeExceptionDetailInFaults="false" /> 26. </behavior> 27. </serviceBehaviors> 28. </behaviors> 29. </system.serviceModel> 30.</configuration>
寄宿宿主:
01.//服务宿主就干一件事:打开服务
02.class Host
03.{
04. static void Main(string[] args)
05. {
06. //回调服务WCFServiceCallBack
07. ServiceHost host = new ServiceHost(typeof(Service0413.WCFService));
08. try
09. {
10. //判断是否以及打开连接,如果尚未打开,就打开侦听端口
11. if (host.State != CommunicationState.Opening)
12. host.Open();
13. //显示运行状态
14. Console.WriteLine("ServiceHost is runing! and state is {0}", host.State);
15. Console.Read();
16. }
17. catch (Exception ex)
18. {
19. Console.WriteLine(ex.ToString());
20. }
21. finally
22. {
23. host.Close();
24. }
25. }
26.}
三、客户端:
首先要实现回调的契约接口(通俗点将就是服务端接收到客户端消息后给客户端发聩信息,在客户端执行):
01./// <summary>要实现回调的契约接口 02./// </summary> 03.public class WCFCallback : Service2012.IWCFServiceCallback 04.{ 05. public void FeedBack(string info) 06. { 07. Console.WriteLine("服务器已经收到您的消息!消息内容:" + info); 08. } 09.}
最后是入口函数部分
01.public class Client 02. { 03. //获得客户端的计算机名(实际可以扩展到获取客户端的一切想要的数据) 04. private static string clientName = Environment.MachineName; 05. private static Service2012.IWCFServiceCallback callBack = new WCFCallback(); 06. private static InstanceContext context = new InstanceContext(callBack); 07. private static Service2012.WCFServiceClient WCFServiceCallBackClientProxy = 08. new WCFServiceClient(context, "NetTcpBinding_IWCFService"); 09. static void Main(string[] args) 10. { 11. System.Timers.Timer timer = new System.Timers.Timer(2000); 12. //绑定定期自动执行的操作 13. timer.Elapsed += new ElapsedEventHandler(OnTimedEvent); 14. timer.Enabled = true; 15. string s=Console.ReadLine(); 16. Console.WriteLine(s); 17. } 18. private static void OnTimedEvent(object source, ElapsedEventArgs e) 19. { 20. string operateInfo = WCFServiceCallBackClientProxy.OprT(clientName); 21. Console.WriteLine(operateInfo); 22. } 23. }
至此完成,本例没有进行异常处理,请注意先运行服务端,再运行客户端。