2014-07-11 58 views
2

如果我創建了一個WCF服務與提供回調和我有幾個客戶端註冊接收事件呢,怎麼這些客戶知道,如果服務中斷或下降?目前他們正在等待一個永遠不會開火的事件。當使用WCF回調客戶如何知道如果服務器已中斷

我想也許我可以實現某種形式的投票的(這是我試圖從逃脫)。但即使投票似乎是一個可憐的修復。例如,如果我每隔30秒輪詢一次,但服務或應用程序池在下次檢查之前重新啓動,則客戶端會認爲一切正常,儘管服務器失去了對它們的引用。

+0

你有沒有考慮使用超時機制,通過一個代理類?有可能是內置一個。 – Aelphaeis

+0

恐怕我不完全確定你的意思? – jrandomuser

回答

2

你可以利用的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; 
+0

你是對的,這是InnerChannel.Faulted我需要訂閱。不過,我現在也要爲許多其他事件添加處理程序。非常感謝! – jrandomuser

2

看一看這個倉庫我寫來回答另一個問題: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(); 
    } 
} 
+0

這是一個很好的例子!它涵蓋了我甚至沒有想過要解決的很多問題。我要研究它並且經過幾次。這對我生產質量更好的東西會有很大的幫助。非常感謝! – jrandomuser

+0

一個很好的答案。稍微偏離主題,但是你沒有正確實現'IDisposable'。請參閱_ [MSDN - 實現Dispose方法](http://msdn.microsoft.com/en-us/library/fs2xkftw(v = vs.110).aspx)_ – MickyD

+0

@MickyDuncan謝謝你,我不知道。我會詳細閱讀。 – Aelphaeis

相關問題