在我们的系统里有多个wcf支撑。但是有的时候会莫名的停止,于是今天写了一个服务,定时去检测其他wcf服务是否在线。那么最简单的办法自然是引用其他wcf服务让vs给我们自动生成clientProxy然后一个个去调用是否正常。但是这种办法显然不是我要的。我要弄一个通用的服务检测。

  方案1:

  对于httpbinding的wcf服务有个最简单的检测方法:就是用httpClient去请求一下服务地址看有没有服务描述xml返回。如果有就是live不然就是服务异常关闭了。这个方法对于net.tcp绑定等不适用。

  方案2:

  使用反射动态生成channelProxy然后去尝试执行一个方法。当然这个方法最好不是Update等会影响到业务数据的方法,最好是query级别的方法。

  正常使用ChannelFactory<T>调用wcf服务:

  1. var channelFactory = new ChannelFactory<T>(endpoint);
  2. var proxy = this._channelFactory.CreateChannel();
    proxy.Add(1,2);

  很简单,我们只需要把T接口协定,endpoint节点名称,调用的方法名称,以及程序集名称或者路径提取到配置文件里就行了。然后把上面的代码转换成反射代码就行。

看一下最主要的方法吧,废话不多了。

  

  1. private bool IsLive(string assemblyName, string apiServiceFullName, string endpointName, string testMethodName)
  2. {
  3. var basePath = AppDomain.CurrentDomain.BaseDirectory;
  4. Type apiType = null;
  5.  
  6. var asm = Assembly.LoadFrom(basePath + "/services/" + assemblyPath);
  7. apiType = asm.GetType(apiServiceFullName);
  8. var channelType = typeof(ChannelFactory<>).MakeGenericType(apiType);
  9.  
  10. try
  11. {
  12. FuncExtension.TryDo(() =>
  13. {
  14. var channel = Activator.CreateInstance(channelType, endpointName);
  15. Type[] types = new Type[];
  16. var createChannelMethod = channelType.GetMethod("CreateChannel", types);
  17. var proxy = createChannelMethod.Invoke(channel, null);
  18. try
  19. {
  20. var testMethod = apiType.GetMethod(testMethodName);
  21. var patameterInfos = testMethod.GetParameters();
  22. List<object> parameters = new List<object>();
  23. foreach (var patameterInfo in patameterInfos)
  24. {
  25. var defaultValue = patameterInfo.ParameterType.IsValueType
  26. ? Activator.CreateInstance(patameterInfo.ParameterType)
  27. : null;
  28. parameters.Add(defaultValue);
  29. }
  30. testMethod.Invoke(proxy, parameters.ToArray());
  31. }
  32. catch (Exception exc)
  33. {
  34. Logger.Error(
  35. string.Format("Try to connect wcf service error:{0}, ExceptionType:{1}", endpointName,
  36. exc.GetType()), GetType(), exc);
  37. throw;
  38. }
  39. finally
  40. {
  41. try
  42. {
  43. (proxy as ICommunicationObject).Close();
  44. }
  45. catch
  46. {
  47. (proxy as ICommunicationObject).Abort();
  48. }
  49. }
  50.  
  51. }, );
  52.  
  53. return true;
  54. }
  55. catch (Exception exc)
  56. {
  57. PrintWholeException(exc);
  58. return !IsHttpOrSocketException(exc);
  59. }
  60.  
  61. }
  62.  
  63. private void PrintWholeException(Exception exc)
  64. {
  65. Logger.Error(exc.GetType().ToString(), GetType(), exc);
  66. if (exc.InnerException != null)
  67. {
  68. PrintWholeException(exc.InnerException);
  69. }
  70. }
  71.  
  72. private bool IsHttpOrSocketException(Exception exc)
  73. {
  74. if (exc is EndpointNotFoundException || exc is SocketException)
  75. {
  76. return true;
  77. }
  78. else
  79. {
  80. if (exc.InnerException != null)
  81. {
  82. return IsHttpOrSocketException(exc.InnerException);
  83. }
  84. }
  85.  
  86. return false;
  87. }

  其中FuncExtension.TryDo是自动尝试一个Actoin的封装,不影响理解反射的代码。

  我们的目的是判断wcf是否还live,所以不要在意返回值。我们只要判断这次调用的异常是否是SocketException或者EndpointNotFindException即可。

  这样,当需要监控新的wcf服务的时候只要在配置文件里添加一行协定,程序集,调用方法,endpoint的配置即可,当然协定所在的dll要复制到程序的跟目录下或者指定的文件下。

检测WCF服务是否在线(动态执行WCF服务)的更多相关文章

  1. 动态的调用服务端的WCF中的方法

    客户端调用wcf ,有时需要动态的调用服务端的WCF中的方法,本方法,反射wcf 的接口,动态调用接口中的方法. 主要为,动态绑定,反射动态调用. public static object Execu ...

  2. 动态调用WCF服务

    动态调用WCF服务,只需要提供*.svc地址, 1:命名空间: using System.ServiceModel.Channels;using System.ServiceModel; 2:创建访问 ...

  3. 创建一个简单的WCF程序2——手动开启/关闭WCF服务与动态调用WCF地址

    一.创建WCF服务器 1.创建WCF服务器的窗体应用程序 打开VS2010,选择文件→新建→项目菜单项,在打开的新建项目对话框中,依次选择Visual C#→Windows→Windows窗体应用程序 ...

  4. 记录:Web无引用无配置方式动态调用WCF服务

    这几年一直用WebApi较多,最近项目中有个需求比较适合使用WCF,以前也用过JQuery直接调用Wcf的,但是说实话真的忘了… 所以这次解决完还是花几分钟记录一下 WCF服务端:宿主在现有Win服务 ...

  5. 动态调用WCF

    最近在做的一个项目中需要动态调用WCF地址,因为有很多终端服务器,而每台终端服务器上都部署一个WCF服务,中央服务器需要不定时调用其中某个或者多个WCF服务执行相关操作,因此添加引用及配置文件配置的方 ...

  6. c# 动态调用WCF方法笔记!

    //动态调用wcf方法 string url = "http://localhost:54379/ServiceWCF.svc"; IDoubleService proxy = W ...

  7. C#动态调用WCF接口,两种方式任你选。

    写在前面 接触WCF还是它在最初诞生之处,一个分布式应用的巨作. 从开始接触到现在断断续续,真正使用的项目少之又少,更谈不上深入WCF内部实现机制和原理去研究,最近自己做一个项目时用到了WCF. 从这 ...

  8. 【WCF全析(一)】--服务协定及消息模式

    上周微软开发布会说.NET支持完全跨平台和并开放Core源码的新闻,让我们顿时感到.NET要迎来它的春天.虽然早在几年前.NET就能开发Android和IOS,但是这次的跨平台把Linux都放到了微软 ...

  9. WCF学习心得------(三)配置服务

    配置服务 配置服务概述 在设计和实现服务协定后,便可以进行服务的配置.在其中可以定义和自定义如何向客户段公开服务,包括指定可以找到服务的地址,服务用于发送和接受消息的传输和消息编码,以及服务需要的安全 ...

随机推荐

  1. note of introduction of Algorithms(Lecture 3 - Part1)

    Lecture 3(part 1) Divide and conquer 1. the general paradim of algrithm as bellow: 1. divide the pro ...

  2. 客户端GUI程序开发漫谈

    这篇文章包含了这个领域的很多开源项目的介绍,还有我多年来的心血和汗水  去年夏天的时候,我用QT做了一个小工具 后来还用QT做了流程设计器 我把程序分享给飞扬青云之后,他甚至搞出来一套QT的皮肤来 说 ...

  3. Linux Shell函数

    200 ? "200px" : this.width)!important;} --> 介绍 正文 $? $?是shell变量,表示"最后一次执行命令"的 ...

  4. Windows内存小结

    以前写过一篇理解程序内存, 当时主要是针对用户态,下面再稍微深入一点: 我们以32位程序为例(不启用AWE), 总共4G虚拟空间,其中低2G属于用户态, 高2G属于操作系统内核, 每个程序都有自己的低 ...

  5. 使用FiddlerCore来测试WebAPI

    大家在调试Web相关的API时,经常会用Fiddler来查看相关的请求,以及返回结果.当然你也可以尝试修改或者重复你的请求信息.本文主要介绍如何使用代码来实现fiddler的功能. Fiddler C ...

  6. Linux time命令

    说明:喜欢写小程序的人都特别注重自己程序的执行效率,那么在Linux上,就有一个time的命令,用于测量命令的运行时间,还可以测量内存.I/O等的使用情况. 一个程序在运行时使用的系统资源通常包括CP ...

  7. git 修改管理

    查看修改: 撤销某一文件的修改(还没提交): 撤销所有文件的修改: git checkout .

  8. swift 加载 storyboard 里的UIViewController

    let storyBoard:UIStoryboard! = UIStoryboard(name: "Main", bundle: nil) let deskVC:DeskView ...

  9. UIViewController的生命周期

    生命周期 我们建立一个简单的模型来测试生命周期:新建两个ViewController,一个是主视图控制器(main ViewController,以下简称mainVC),一个是副视图控制器(sub V ...

  10. sql基础知识:分页+排序

    Oracle的分页还真是挺恶心地,不像mysql直接Limit就搞定 select name from student limit 0,20; Oracle需要借助rownum实现: select * ...