WCFProxy.cs 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. 
  2. using System;
  3. using System.ServiceModel;
  4. //using Curtain.WCF.Contract;
  5. namespace Curtain.WCF.Proxy
  6. {
  7. /// <summary>
  8. /// WCF服务代理基类
  9. /// </summary>
  10. public abstract class WCFProxy<TChannel> : IDisposable//, IWCFProxy
  11. where TChannel : class//, IWCFContract
  12. {
  13. #region 常量
  14. #endregion
  15. #region 成员变量
  16. /// <summary>
  17. /// 终结点的配置名称
  18. /// </summary>
  19. private string _endpointName = null;
  20. private string _serviceName = null;
  21. /// <summary>
  22. /// WCF通道工厂
  23. /// </summary>
  24. private ChannelFactory<TChannel> _channelFactory = null;
  25. /// <summary>
  26. /// WCF代理配置
  27. /// </summary>
  28. private WCFProxySetting _setting = null;
  29. /// <summary>
  30. /// WCF代理配置版本
  31. /// </summary>
  32. private int _settingVersion = 0;
  33. #endregion
  34. #region 构造
  35. /// <summary>
  36. /// WCF服务代理基类
  37. /// </summary>
  38. /// <param name="endpointName"></param>
  39. /// <param name="settingName"></param>
  40. /// <param name="serviceName"></param>
  41. protected WCFProxy(string endpointName, string settingName, string serviceName)
  42. {
  43. if (string.IsNullOrWhiteSpace(endpointName))
  44. {
  45. throw new ArgumentNullException("endpointName");
  46. }
  47. this._endpointName = endpointName;
  48. this._serviceName = serviceName;
  49. this._setting = WCFProxySetting.CreateSetting(settingName);
  50. }
  51. /// <summary>
  52. /// WCF服务代理基类
  53. /// </summary>
  54. /// <param name="endpointName"></param>
  55. /// <param name="setting"></param>
  56. protected WCFProxy(string endpointName, WCFProxySetting setting, string serviceName)
  57. {
  58. if (string.IsNullOrWhiteSpace(endpointName))
  59. {
  60. throw new ArgumentNullException("endpointName");
  61. }
  62. this._endpointName = endpointName;
  63. this._serviceName = serviceName;
  64. this._setting = (setting == null ? WCFProxySetting.DefaultSetting : setting);
  65. }
  66. #endregion
  67. #region 属性
  68. public string EndpointName
  69. {
  70. get
  71. {
  72. return this._endpointName;
  73. }
  74. }
  75. public string ServiceName
  76. {
  77. get
  78. {
  79. return this._serviceName;
  80. }
  81. }
  82. /// <summary>
  83. /// WCF代理配置
  84. /// </summary>
  85. public WCFProxySetting ProxySetting
  86. {
  87. get
  88. {
  89. return this._setting;
  90. }
  91. }
  92. /// <summary>
  93. /// 信道工厂
  94. /// </summary>
  95. public ChannelFactory<TChannel> ChannelFactory
  96. {
  97. get
  98. {
  99. return this._channelFactory;
  100. }
  101. }
  102. #endregion
  103. #region 公有方法
  104. /// <summary>
  105. /// 执行
  106. /// </summary>
  107. /// <param name="serviceInvocation"></param>
  108. /// <param name="timeout">超时(分钟)</param>
  109. public virtual void Invoke(Action<TChannel> serviceInvocation, double timeout = 0)
  110. {
  111. TChannel channel = null;//default(TChannel);
  112. IContextChannel contextChannel = null;
  113. string methodName = serviceInvocation.Method.ToString();
  114. try
  115. {
  116. if (this._setting.Type == 1)
  117. {
  118. channel = this.GetServerInstance();
  119. }
  120. else
  121. {
  122. this.OpenChannelFactory();
  123. channel = this._channelFactory.CreateChannel();
  124. contextChannel = channel as IContextChannel;
  125. if (contextChannel != null)
  126. {
  127. if (timeout > WCFProxySetting.OPERATION_TIMEOUT_MAX)
  128. {
  129. timeout = WCFProxySetting.OPERATION_TIMEOUT_MAX;
  130. }
  131. if (timeout > 0)
  132. {
  133. contextChannel.OperationTimeout = TimeSpan.FromMinutes(timeout);
  134. }
  135. }
  136. }
  137. serviceInvocation(channel);
  138. this.InvokeDone<object>(methodName, null, true);
  139. }
  140. catch (Exception ex)
  141. {
  142. Exception newEx = this.InvokeException(methodName, ex);
  143. if (newEx == null)
  144. {
  145. return;
  146. }
  147. throw newEx;
  148. }
  149. finally
  150. {
  151. if (contextChannel != null)
  152. {
  153. try
  154. {
  155. contextChannel.Close();
  156. }
  157. catch
  158. {
  159. contextChannel.Abort();
  160. }
  161. }
  162. }
  163. }
  164. /// <summary>
  165. /// 执行
  166. /// </summary>
  167. /// <typeparam name="TResult"></typeparam>
  168. /// <param name="serviceInvocation"></param>
  169. /// <param name="timeout">超时(分钟)</param>
  170. /// <returns></returns>
  171. public virtual TResult Invoke<TResult>(Func<TChannel, TResult> serviceInvocation,
  172. double timeout = 0)
  173. {
  174. TChannel channel = null;// default(TChannel);
  175. IContextChannel contextChannel = null;
  176. string methodName = serviceInvocation.Method.ToString();
  177. try
  178. {
  179. //if (this._setting.Type == 1)
  180. //{
  181. // channel = this.GetServerInstance();
  182. //}
  183. ////else
  184. //if(channel == null)
  185. {
  186. this.OpenChannelFactory();
  187. channel = this._channelFactory.CreateChannel();
  188. contextChannel = channel as IContextChannel;
  189. if (contextChannel != null)
  190. {
  191. if (timeout > WCFProxySetting.OPERATION_TIMEOUT_MAX)
  192. {
  193. timeout = WCFProxySetting.OPERATION_TIMEOUT_MAX;
  194. }
  195. if (timeout > 0)
  196. {
  197. contextChannel.OperationTimeout = TimeSpan.FromMinutes(timeout);
  198. }
  199. }
  200. }
  201. TResult result = serviceInvocation(channel);
  202. result = this.InvokeDone<TResult>(methodName, result);
  203. return result;
  204. }
  205. catch (Exception ex)
  206. {
  207. Exception newEx = this.InvokeException(methodName, ex);
  208. if (newEx == null)
  209. {
  210. return default(TResult);
  211. }
  212. throw newEx;
  213. }
  214. finally
  215. {
  216. if (contextChannel != null)
  217. {
  218. try
  219. {
  220. contextChannel.Close();
  221. }
  222. catch
  223. {
  224. contextChannel.Abort();
  225. }
  226. }
  227. }
  228. }
  229. /// <summary>
  230. /// 关闭通道工厂
  231. /// </summary>
  232. public void CloseChannelFactory()
  233. {
  234. try
  235. {
  236. this._channelFactory.Close();
  237. }
  238. catch
  239. {
  240. this._channelFactory.Abort();
  241. }
  242. finally
  243. {
  244. this._channelFactory = null;
  245. }
  246. }
  247. /// <summary>
  248. /// 释放分配的资源
  249. /// </summary>
  250. public void Dispose()
  251. {
  252. this._setting = null;
  253. this.CloseChannelFactory();
  254. }
  255. #endregion
  256. #region 保护方法
  257. protected virtual TChannel GetServerInstance()
  258. {
  259. //throw new NotImplementedException();
  260. return null;
  261. }
  262. /// <summary>
  263. /// 异常处理
  264. /// 1.写日志
  265. /// 2.客户端连接异常处理
  266. /// 3.服务端异常处理
  267. /// </summary>
  268. /// <param name="cre"></param>
  269. /// <param name="sre"></param>
  270. /// <param name="ex"></param>
  271. /// <returns>抛出未处理异常</returns>
  272. protected virtual Exception InvokeException(string methodName, Exception ex)
  273. {
  274. return ex;
  275. }
  276. /// <summary>
  277. /// 请求被处理后
  278. /// 1.如果服务端异常已处理,写日志,提示消息等处理。
  279. /// </summary>
  280. /// <param name="result"></param>
  281. protected virtual TResult InvokeDone<TResult>(string methodName, TResult result, bool isOneWay = false)
  282. {
  283. return result;
  284. }
  285. #endregion
  286. #region 私有方法
  287. /// <summary>
  288. /// 打开通道工厂
  289. /// </summary>
  290. protected void OpenChannelFactory()
  291. {
  292. lock (this)
  293. {
  294. if (this._channelFactory != null &&
  295. this._settingVersion != this._setting.Version)
  296. {
  297. this.CloseChannelFactory();
  298. }
  299. if (this._channelFactory == null)
  300. {
  301. this._settingVersion = this._setting.Version;
  302. EndpointAddress remoteAddress = new EndpointAddress(this._setting.GetEndpointAddress(this._serviceName));
  303. this._channelFactory = new ChannelFactory<TChannel>(this._endpointName, remoteAddress);
  304. this._channelFactory.Open();
  305. }
  306. }
  307. }
  308. #endregion
  309. }
  310. }