上一版在這裡http://www.cnblogs.com/kklldog/p/4878296.html
上一版主要是解決了監控服務不需要手動添加服務引用的問題,但是還是需要在配置文件中添加對應的endpoint信息,以及需要真正的contract接口的dll文件來實現反射生成wcf通道。
這樣其實還是挺繁瑣的,每添加一個監控的服務,都需要修改一堆配置,外加復制一堆dll。新版中已經不需要復制真正的contract的dll文件跟endpoint配置了。
上一版我需要contract的dll一是為了反射去創建wcf調用通道,二是為了調用其中一個真正的方法。其實可以使用一個假的contract接口跟一個假的方法來探測就可以。
因為就算使用假的contract接口通道也是可以建立的,調用一個不存在的方法會報一個System.ServiceModel.ActionNotSupportedException的異常,這表明服務是存在的。
然後我們只需要一個假的contract接口:
[ServiceContract] public interface IFakeWcfInterface { [OperationContract] string ThisIsATestMethod(); }
然後使用ChanelFactory去構造通道,這次不用反射了,更加簡單。為了移除endpoint的配置文件,我們直接手動用代碼實例化一個ServiceEndpoint。我這邊所有的服務的binding都是統一的,所以可以寫死了,如果每個服務的binding等信息都不一樣,那麼還需要抽象到config文件裡了。
測試是否alive:
private bool IsALive(string endpointName,string url) { try { FuncExtension.TryDo(() => { var endpoint = new ServiceEndpoint(ContractDescription.GetContract(typeof(IFakeWcfInterface)), new NetTcpBinding(SecurityMode.None), new EndpointAddress(url)); var channelFactory = new ChannelFactory<IFakeWcfInterface>(endpoint); var proxy = channelFactory.CreateChannel(); try { proxy.ThisIsATestMethod(); } catch (Exception exc) { Logger.Trace( string.Format("Try to connect wcf service error:{0}, ExceptionType:{1}", endpointName, exc.GetType()), GetType(), exc); throw; } finally { try { (proxy as ICommunicationObject).Close(); } catch { (proxy as ICommunicationObject).Abort(); } } }, 3); return true; } catch (Exception exc) { PrintWholeException(exc); return !IsHttpOrSocketException(exc); } }