Pytanie SignalR .Net Client: jak przywrócić połączenie


przeczytałem ten post

W niektórych aplikacjach może być konieczne ponowne automatyczne nawiązanie połączenia po jego utracie, a próba ponownego nawiązania połączenia przekroczyła limit czasu. Aby to zrobić, możesz wywołać metodę Start z zamkniętej procedury obsługi zdarzeń (odłączony moduł obsługi zdarzeń na klientach JavaScript). Możesz chcieć poczekać jakiś czas przed wywołaniem Startu, aby uniknąć tego zbyt często, gdy serwer lub fizyczne połączenie są niedostępne. Poniższy przykładowy kod jest dla klienta JavaScript używającego wygenerowanego proxy.

Kiedy wołam metodę Start ze zdarzenia Closed

connection.Closed += connection_Closed;
static void connection_Closed()
    {
        Console.WriteLine("connection closed");
        ServerConnection.Start().Wait();
    }

Wystąpił wyjątek:     połączenie nie zostało nawiązane.

Chcę, aby trwało to aż do sukcesu, gdy serwer jest w porządku. Nie wyrzucaj wyjątków. Jak mogę to osiągnąć?

jakieś pomysły?

dzięki


14
2017-07-03 01:40


pochodzenie




Odpowiedzi:


na kliencie .net można wywołać metodę startową z zamkniętej procedury obsługi zdarzeń. jeśli serwer jest niedostępny, należy wykonać wywołanie rekurencyjne.

na przykład

_connection.Closed += OnDisconnected;
static void OnDisconnected()
{
    Console.WriteLine("connection closed");
    var t=_connection.Start()

    bool result =false;
    t.ContinueWith(task=>
    {
       if(!task.IsFaulted)
       {
           result = true;
       }
    }).Wait();

    if(!result)
    {
         OnDisconnected();
    }
}

10
2017-10-11 00:54



Cf. @ Dunc's odpowiedź na udoskonalenia (stackoverflow.com/a/37333594/1958726). Jawne przywołanie obsługi nie jest konieczne, a rekursja wprowadza możliwość przepełnienia stosu. (Prawdopodobnie usługa będzie zachodzić przed zachodem słońca, jeśli wystąpi jakiś limit czasu połączenia, ale w tym przypadku łatwo się go pozbyć.) - Eric Eskildsen


Różnice w stosunku do feniksa:

  • Bez wyraźnego połączenia z OnDisconnected jest rzeczywiście wymagane od Closed zdarzenie jest wywoływane przy niepowodzeniu połączenia
  • Małe opóźnienie przed ponowną próbą
  • Odtworzenie ConnectionHub za każdym razem - wydaje się konieczne z mojego doświadczenia (stary powinien zostać usunięty przez GC)

Kod:

private HubConnection _hubConnection = null;
private IHubProxy _chatHubProxy = null;

private void InitializeConnection()
{
    if (_hubConnection != null)
    {
        // Clean up previous connection
        _hubConnection.Closed -= OnDisconnected;
    }

    _hubConnection = new HubConnection("your-url");
    _hubConnection.Closed += OnDisconnected;
    _chatHubProxy = _hubConnection.CreateHubProxy("YourHub");

    ConnectWithRetry();
}

void OnDisconnected()
{
    // Small delay before retrying connection
    Thread.Sleep(5000);

    // Need to recreate connection
    InitializeConnection();
}

private void ConnectWithRetry()
{
    // If this fails, the 'Closed' event (OnDisconnected) is fired
    var t = _hubConnection.Start();

    t.ContinueWith(task =>
    {
        if (!task.IsFaulted)
        {
            // Connected => re-subscribe to groups etc.
            ...
        }
    }).Wait();
}

7
2018-05-19 20:39



Szybkie pytanie. Dlaczego mamy ConnectWithRetry() osobna funkcja? Czy możemy to po prostu włączyć? InitializeConnection() samo? Czy mogę przeoczyć coś bardzo oczywistego? - skjoshi
Po prostu czytelność (programmers.stackexchange.com/q/195989) - Dunc


Właśnie znalazłem odpowiedź na http://www.asp.net/signalr/overview/signalr-20/hubs-api/handling-connection-lifetime-events

"Jak ciągle się łączyć

W niektórych aplikacjach może być konieczne ponowne automatyczne nawiązanie połączenia po jego utracie, a próba ponownego nawiązania połączenia przekroczyła limit czasu. Aby to zrobić, możesz wywołać metodę Start z zamkniętej procedury obsługi zdarzeń (odłączony moduł obsługi zdarzeń na klientach JavaScript). Możesz chcieć poczekać jakiś czas przed wywołaniem Startu, aby uniknąć tego zbyt często, gdy serwer lub fizyczne połączenie są niedostępne. Poniższy przykładowy kod jest dla klienta JavaScript używającego wygenerowanego proxy.

$.connection.hub.disconnected(function() {
   setTimeout(function() {
       $.connection.hub.start();
   }, 5000); // Restart connection after 5 seconds.
});

Potencjalnym problemem, na który należy zwrócić uwagę w przypadku klientów mobilnych, jest to, że ciągłe próby ponownego połączenia, gdy serwer lub fizyczne połączenie nie jest dostępne, mogą spowodować niepotrzebny rozładowanie baterii. "


6
2017-12-19 17:33



Przeczytałem ten post; Myślę, że powinienem ustawić wartość zmiennej na false, gdy zdarzenie zamknięte zostanie uruchomione. Gdy zmienna jest prawdziwa, mogę użyć metody "Invoke". - phoenix
Możesz użyć stanu połączenia zamiast zmiennej globalnej - Nestor
czy nie powinno to używać metody "setInterval" Javascript? W przeciwnym razie ponowne połączenie jest podejmowane tylko raz. - willem