如果我創建了一個WCF服務與提供回調和我有幾個客戶端註冊接收事件呢,怎麼這些客戶知道,如果服務中斷或下降?目前他們正在等待一個永遠不會開火的事件。當使用WCF回調客戶如何知道如果服務器已中斷
我想也許我可以實現某種形式的投票的(這是我試圖從逃脫)。但即使投票似乎是一個可憐的修復。例如,如果我每隔30秒輪詢一次,但服務或應用程序池在下次檢查之前重新啓動,則客戶端會認爲一切正常,儘管服務器失去了對它們的引用。
如果我創建了一個WCF服務與提供回調和我有幾個客戶端註冊接收事件呢,怎麼這些客戶知道,如果服務中斷或下降?目前他們正在等待一個永遠不會開火的事件。當使用WCF回調客戶如何知道如果服務器已中斷
我想也許我可以實現某種形式的投票的(這是我試圖從逃脫)。但即使投票似乎是一個可憐的修復。例如,如果我每隔30秒輪詢一次,但服務或應用程序池在下次檢查之前重新啓動,則客戶端會認爲一切正常,儘管服務器失去了對它們的引用。
你可以利用的IClientChannel
各種事件監測與連接發生了什麼。對於您的情況,Faulted
事件似乎是最合適的。但也有其他事件可能會對您有用。
_proxy.InnerChannel.Opening += OnChannelOpening;
_proxy.InnerChannel.Opened += OnChannelOpened;
_proxy.InnerChannel.Faulted += OnChannelFaulted;
_proxy.InnerChannel.UnknownMessageReceived += OnChannelUnknownMessageReceived;
_proxy.InnerChannel.Closing += OnChannelClosing;
_proxy.InnerChannel.Closed += OnChannelClosed;
你是對的,這是InnerChannel.Faulted我需要訂閱。不過,我現在也要爲許多其他事件添加處理程序。非常感謝! – jrandomuser
看一看這個倉庫我寫來回答另一個問題:https://github.com/Aelphaeis/MyWcfDuplexPipeExample/tree/MultiClient
在這個倉庫有雙工連接和兩個客戶端。
如果客戶端斷開連接,並服務嘗試當您嘗試在客戶端調用回調函數,你會應該捕獲CommunicationObjectAbortedException訪問的客戶端。
如果該服務被斷開,客戶端試圖叫你應該試圖捕獲的EndPointNotFoundException服務。
public class MyServiceClient: IMyService, IDisposable
{
DuplexChannelFactory<IMyService> myServiceFactory { get; set; }
public MyServiceClient(IMyServiceCallback Callback)
{
InstanceContext site = new InstanceContext(Callback);
NetNamedPipeBinding binding = new NetNamedPipeBinding();
EndpointAddress endpointAddress = new EndpointAddress(Constants.myPipeService + @"/" + Constants.myPipeServiceName);
myServiceFactory = new DuplexChannelFactory<IMyService>(site, binding, endpointAddress);
Init();
}
public void Init()
{
myServiceFactory.CreateChannel().Init();//EndPointNotFoundException Thrown here
}
public void DoWork()
{
myServiceFactory.CreateChannel().DoWork();//EndPointNotFoundException Thrown here
}
public void Dispose()
{
myServiceFactory.Close();
}
}
服務
public class MyServiceServer : IDisposable
{
public Boolean IsDisposed { get; private set; }
ServiceHost host { get; set; }
MyService service;
public void Open()
{
if (host != null)
Dispose();
IsDisposed = false;
service = new MyService();
host = new ServiceHost(service, new Uri(Constants.myPipeService));
host.AddServiceEndpoint(typeof(IMyService), new NetNamedPipeBinding(), Constants.myPipeServiceName);
host.BeginOpen(OnOpen, host);
}
public void Msg(int ClientId)
{
foreach (var cb in service.Callbacks)
if (cb.GetClientId() == ClientId) // CommunicationObjectAbortedException here
cb.RecieveMessage("We have called you choosen one");
}
public void Close()
{
host.BeginClose(OnClose, host);
}
public void Dispose()
{
((IDisposable)host).Dispose();
IsDisposed = true;
host = null;
}
void OnOpen(IAsyncResult ar)
{
ServiceHost service = (ServiceHost)ar.AsyncState;
service.EndOpen(ar);
}
void OnClose(IAsyncResult ar)
{
ServiceHost service = (ServiceHost)ar.AsyncState;
service.EndClose(ar);
Dispose();
}
}
這是一個很好的例子!它涵蓋了我甚至沒有想過要解決的很多問題。我要研究它並且經過幾次。這對我生產質量更好的東西會有很大的幫助。非常感謝! – jrandomuser
一個很好的答案。稍微偏離主題,但是你沒有正確實現'IDisposable'。請參閱_ [MSDN - 實現Dispose方法](http://msdn.microsoft.com/en-us/library/fs2xkftw(v = vs.110).aspx)_ – MickyD
@MickyDuncan謝謝你,我不知道。我會詳細閱讀。 – Aelphaeis
你有沒有考慮使用超時機制,通過一個代理類?有可能是內置一個。 – Aelphaeis
恐怕我不完全確定你的意思? – jrandomuser