2009-10-12 15 views
7

Próbuję zaimplementować logikę ponownych połączeń dla klienta wcf. Mam świadomość, że musisz utworzyć nowy kanał po tym, jak bieżący kanał wszedł w stan błędu. Zrobiłem to w kanale zarzucić obsługi zdarzenia:Kanał zwrotny WCF był uszkodzony


internal class ServiceClient : DuplexClientBase, IServiceClient 
{ 
    public ServiceClient(ICallback callback, EndpointAddress serviceAddress) 
    : base(callback, MyUtility.GetServiceBinding("NetTcpBinding"), serviceAddress) 
    { 
    // Open the connection. 
    Open(); 
    } 

    public void Register(string clientName) 
    { 
    // register to service 
    } 

    public void DoSomething() 
    { 
    // some code 
    } 
} 

public class ClientApp 
{ 
    private IServiceClient mServiceClient; 

    private ICallback mCallback; 

    public ClientApp() 
    { 
    mServiceClient = new ServiceClient(mCallback, new EndpointAddress("someAddress")); 

    mServiceClient.Register(); 

    // register faulted event for the service client 
    ((ICommunicationObject)mServiceClient).Faulted += new EventHandler(ServiceClient_Faulted); 
    } 

    void ServiceClient_Faulted(object sender, EventArgs e) 
    { 
    // Create new Service Client. 
    mServiceClient = new ServiceClient(mCallback, new EndpointAddress("someAddress")); 

    // Register the EI at Cell Controller 
    mServiceClient.Register(); 
    } 

    public void DoSomething() 
    { 
    mServiceClient.DoSomething(); 
    } 
} 

Ale w moim badanej jednostki I jeszcze dostać „obiektu komunikacyjnego, System.ServiceModel.Channels.ServiceChannel, nie mogą być używane do komunikacji, ponieważ jest w uszkodzonego "wyjątek stanu".

Czy jest możliwe, że kanał zwrotny nadal jest błędny, a jeśli tak, w jaki sposób mogę zamienić kanał zwrotny?

+0

Czy możesz określić, co robi test twojej jednostki, gdy wyzwala wyjątek? –

+0

W mojej jednostce testowej tworzę host usługi i instancję klienta. Rejestruję klienta w usłudze, a następnie zatrzymuję usługę, ustawiając odwołanie na wartość null. Następnie czekam 20 sekund (używam niezawodnej sesji z czasem nieaktywności wynoszącym 10 sekund, więc jestem pewien, że połączenie zostanie utracone po 20 sekundach), a następnie wywołuję metodę DoSomething() na kliencie. Teraz odtwarzam usługę i oczekuję, że klient ponownie się połączy. W tym momencie otrzymuję wyjątek. – phatoni

Odpowiedz

5

Do tej pory doświadczyłem, że połączenie WCF musi zostać odtworzone w przypadku błędu - nie ma sposobu na odzyskanie go w inny sposób. Jeśli chodzi o wystąpienie błędu, metoda wydaje się działać dobrze, ale często uruchamia i czyści połączenie WCF (ustanawiając nowe, itd.), Ponieważ bieżące żądanie przechodzi dalej - powodując niepowodzenie - zwłaszcza w przypadku przekroczenia limitu czasu.

Kilka sugestii: - Jeśli jest związany z limitem czasu, należy śledzić ostatni raz wykonane połączenie i stałą zawierającą wartość limitu czasu. Jeśli połączenie WCF zostało przerwane z powodu braku aktywności, upuść je i odtwórz je przed wysłaniem żądania przez przewód. - Po drugie, wygląda na to, że nie dodajesz ponownie procedury obsługi błędów, co oznacza, że ​​pierwsza usterka zostanie potraktowana, ale za drugim razem, gdy ulegnie uszkodzeniu, przewróci się bez obsługi, ponieważ nie jest dołączony żaden nowy.

Mam nadzieję, że to pomoże

0

Czy próbowałeś zresetować kanał komunikacyjny, wywołując mServiceClient.Abort w module obsługi zdarzeń Faulted?

Edit:

widzę, że nie ponownie zainicjować obiekt mCallback w kodzie odzyskiwania. Może być konieczne przypisanie go do nowej instancji.

+0

Dzięki za pomoc. Tak, próbowałem tego wcześniej, ale to nie pomogło tak bardzo, ponieważ otrzymałem komunikat "Obiekt komunikacyjny System.ServiceModel.Channels.ServiceChannel, nie może być używany do komunikacji, ponieważ jest w stanie Aborted" wyjątek zamiast wyżej wspomnianego wyjątek. – phatoni