Niezawodność transportu w sieci Web (utrata danych Socket.io podczas ponownego łączenia)

Używany

NodeJS, Socket.io

Problem

Wyobraź sobie, że jest 2 użytkownikówU1 & U2, podłączony do aplikacji za pośrednictwem Socket.io. Algorytm jest następujący:

U1 całkowicie traci połączenie z Internetem (np. wyłącza Internet)U2 wysyła wiadomość doU1.U1 nie otrzymała jeszcze wiadomości, ponieważ Internet jest wyłączonyserwer wykrywaU1 rozłączenie przez limit czasu pulsuU1 ponownie łączy się z socket.ioU1 nigdy nie odbiera wiadomości odU2 - Zgubiłem się w kroku 4.Możliwe wyjaśnienie

Myślę, że rozumiem, dlaczego tak się dzieje:

w kroku 4serwer zabija instancję gniazda i kolejkę komunikatów doU1 takżePonadto w kroku 5U1 iserwer utwórz nowe połączenie (nie jest ponownie używane), więc nawet jeśli wiadomość jest nadal w kolejce, poprzednie połączenie i tak zostanie utracone.Potrzebuję pomocy

Jak mogę zapobiec tego rodzaju utracie danych? Muszę używać dźwięków słyszących, ponieważ ludzie nie wiszą w aplikacji na zawsze. Muszę także dać możliwość ponownego połączenia, ponieważ kiedy wdrażam nową wersję aplikacji, chcę mieć zerowy czas przestoju.

P.S. To, co nazywam „wiadomością”, nie jest tylko wiadomością tekstową, którą mogę przechowywać w bazie danych, ale cenną wiadomością systemową, której dostarczenie musi być zagwarantowane, lub wkręcenie interfejsu użytkownika.

Dzięki!

Dodatek 1

Mam już system kont użytkowników. Ponadto moja aplikacja jest już skomplikowana. Dodanie statusów offline / online nie pomoże, ponieważ mam już tego rodzaju rzeczy. Problem jest inny.

Sprawdź krok 2. Na tym etapie technicznienie mogę powiedzieć, czy U1 przechodzi w tryb offline, po prostu traci połączenie, powiedzmy na 2 sekundy, prawdopodobnie z powodu złego internetu. Więc U2 wysyła mu wiadomość, ale U1 go nie odbiera, ponieważ internet jest dla niego nadal niedostępny (krok 3). Krok 4 jest potrzebny do wykrycia użytkowników offline, powiedzmy, limit czasu wynosi 60 sekund. Ostatecznie w ciągu kolejnych 10 sekund połączenie z Internetem dla U1 jest gotowe i ponownie łączy się z socket.io. Ale wiadomość z U2 jest tracona w kosmosie, ponieważ na serwerze U1 został rozłączony przez limit czasu.

To jest problem, nie chcę 100% dostawy.

RozwiązanieZbierz emitującego (emituj nazwę i dane) użytkownika {}, identyfikowanego przez losowy identyfikator. Wyślij emitujPotwierdź emisję po stronie klienta (wyślij emisje z powrotem do serwera za pomocą emitID)Jeśli potwierdzono - usuń obiekt z {} zidentyfikowany przez emitIDJeśli użytkownik ponownie nawiązał połączenie - sprawdź {} dla tego użytkownika i przeprowadź pętlę wykonując Krok 1 dla każdego obiektu w {}

Gdy jest odłączony lub / i podłączony w razie potrzeby do użytkownika {}

// Stała serwera pendingEmits = {};

socket.on ('reconnection', () => resendAllPendingLimits); socket.on ('confirm', (emitID) => {delete (pendingEmits [emitID]);});

// Klient socket.on ('coś', () => {socket.emit ('confirm', emitID);});

questionAnswers(6)

yourAnswerToTheQuestion