上一版在這里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);
}
}
