Udostępnij za pośrednictwem


Tworzenie niezawodnego protokołu Websocket za pomocą podprotocol

Gdy połączenia klienta protokołu Websocket upuszczają się z powodu sporadycznych problemów z siecią, komunikaty mogą zostać utracone. W systemie pub/sub wydawcy są oddzieleni od subskrybentów, więc wydawcy mogą nie wykrywać porzuconego połączenia lub utraty komunikatów subskrybentów. Ważne jest, aby klienci rozwiązywali sporadyczne problemy z siecią i utrzymywali niezawodne dostarczanie komunikatów. Aby to osiągnąć, możesz utworzyć niezawodnego klienta protokołu Websocket za pomocą niezawodnych podprotocols usługi Azure Web PubSub.

Niezawodny protokół

Usługa Web PubSub obsługuje dwa niezawodne podprotokoli json.reliable.webpubsub.azure.v1 i protobuf.reliable.webpubsub.azure.v1. Aby zapewnić niezawodność, klienci muszą postępować zgodnie z częściami wydawcy, subskrybenta i odzyskiwania podprotocol. Nieprawidłowe zaimplementowanie podprotocol może spowodować, że dostarczanie komunikatów nie działa zgodnie z oczekiwaniami lub usługa kończy klienta z powodu naruszeń protokołu.

Łatwy sposób — korzystanie z zestawu SDK klienta

Najprostszym sposobem utworzenia niezawodnego klienta jest użycie zestawu SDK klienta. Zestaw SDK klienta implementuje specyfikację klienta Web PubSub i używa json.reliable.webpubsub.azure.v1 go domyślnie. Aby uzyskać szybki start, zapoznaj się z artykułem Publikowanie/subskrybowanie wśród klientów .

Hard Way - Implementuj ręcznie

W poniższym samouczku przedstawiono ważną część implementacji specyfikacji klienta Web PubSub. Ten przewodnik nie jest przeznaczony dla osób poszukujących szybkiego startu, ale chce znać zasadę osiągnięcia niezawodności. Aby uzyskać szybki start, użyj zestawu SDK klienta.

Inicjalizacja

Aby użyć niezawodnych podprotocols, należy ustawić podprotocol podczas konstruowania połączeń protokołu Websocket. W języku JavaScript można użyć następującego kodu:

  • Użyj niezawodnego podprotokolu Json:

    var pubsub = new WebSocket(
      "wss://test.webpubsub.azure.com/client/hubs/hub1",
      "json.reliable.webpubsub.azure.v1"
    );
    
  • Użyj niezawodnego podprotokolu Protobuf:

    var pubsub = new WebSocket(
      "wss://test.webpubsub.azure.com/client/hubs/hub1",
      "protobuf.reliable.webpubsub.azure.v1"
    );
    

Odzyskiwanie Połączenie ion

Połączenie odzyskiwania jonowego jest podstawą osiągnięcia niezawodności i należy je zaimplementować podczas korzystania z json.reliable.webpubsub.azure.v1 protokołów i protobuf.reliable.webpubsub.azure.v1 .

Połączenia protokołu Websocket korzystają z protokołu TCP. Gdy połączenie nie upuszcza się, komunikaty są bezstratne i dostarczane w kolejności. Aby zapobiec utracie komunikatów w przypadku porzuconych połączeń, usługa Web PubSub zachowuje informacje o stanie połączenia, w tym informacje o grupie i wiadomościach. Te informacje służą do przywracania klienta podczas odzyskiwania połączenia

Gdy klient ponownie łączy się z usługą przy użyciu niezawodnych podprotocols, klient otrzyma Connected komunikat zawierający element connectionId i reconnectionToken. Element connectionId identyfikuje sesję połączenia w usłudze.

{
  "type": "system",
  "event": "connected",
  "connectionId": "<connection_id>",
  "reconnectionToken": "<reconnection_token>"
}

Gdy połączenie protokołu WebSocket spadnie, klient powinien spróbować ponownie nawiązać połączenie z tą samą connectionId sesją, aby przywrócić tę samą sesję. Klienci nie muszą negocjować z serwerem i uzyskiwać .access_token Zamiast tego, aby odzyskać połączenie, klient powinien utworzyć żądanie połączenia WebSocket bezpośrednio z usługą z nazwą hosta usługi, connection_idi :reconnection_token

wss://<service-endpoint>/client/hubs/<hub>?awps_connection_id=<connection_id>&awps_reconnection_token=<reconnection_token>

odzyskiwanie Połączenie ion może zakończyć się niepowodzeniem, jeśli problem z siecią nie został jeszcze odzyskany. Klient powinien ponowić próbę ponownego nawiązania połączenia do czasu:

  1. Połączenie protokołu Websocket jest zamykane z kodem stanu 1008. Kod stanu oznacza, że identyfikator connectionId został usunięty z usługi.
  2. Awaria odzyskiwania nadal występuje przez ponad 1 minutę.

Wydawca

Klienci wysyłający zdarzenia do programów obsługi zdarzeń lub publikują komunikaty do innych klientów są nazywane wydawcami. Wydawcy powinni ustawić ackId w komunikacie potwierdzenie z usługi Web PubSub, że publikowanie wiadomości zakończyło się pomyślnie.

Jest ackId to identyfikator komunikatu. Każdy nowy komunikat powinien używać unikatowego identyfikatora. Oryginał ackId powinien być używany podczas ponownego wysłania wiadomości.

Przykładowa wiadomość wysyłana przez grupę:

{
  "type": "sendToGroup",
  "group": "group1",
  "dataType": "text",
  "data": "text data",
  "ackId": 1
}

Przykładowa odpowiedź ack:

{
  "type": "ack",
  "ackId": 1,
  "success": true
}

Gdy usługa Web PubSub zwraca odpowiedź ack z usługą success: true, komunikat został przetworzony przez usługę, a klient może oczekiwać, że komunikat zostanie dostarczony do wszystkich subskrybentów.

Gdy usługa wystąpi przejściowy błąd wewnętrzny i nie można wysłać komunikatu do subskrybenta, wydawca otrzyma ack z success: false. Wydawca powinien odczytać błąd, aby określić, czy wysłać ponownie wiadomość. Jeśli komunikat jest ponownie wyświetlany, należy użyć tego samego ackId polecenia.

{
  "type": "ack",
  "ackId": 1,
  "success": false,
  "error": {
    "name": "InternalServerError",
    "message": "Internal server error"
  }
}

Message Failure

Jeśli odpowiedź ack usługi zostanie utracona, ponieważ połączenie protokołu WebSocket zostało porzucone, wydawca powinien ponownie wysłać komunikat o tej samej nazwie ackId po odzyskaniu. Gdy komunikat został wcześniej przetworzony przez usługę, wyśle kod ack zawierający Duplicate błąd. Wydawca powinien przestać ponownie wysyłać tę wiadomość.

{
  "type": "ack",
  "ackId": 1,
  "success": false,
  "error": {
    "name": "Duplicate",
    "message": "Message with ack-id: 1 has been processed"
  }
}

Message duplicated

Subskrybent

Klienci odbierający komunikaty z programów obsługi zdarzeń lub wydawców są nazywani subskrybentami. Gdy połączenia upuszczają się z powodu problemów z siecią, usługa Web PubSub nie wie, ile komunikatów zostało wysłanych do subskrybentów. Aby określić ostatni komunikat odebrany przez subskrybenta, usługa wysyła komunikat dotyczący danych zawierający element sequenceId. Subskrybent odpowiada za pomocą komunikatu ack sekwencji:

Przykładowa sekwencja ack:

{
  "type": "sequenceAck",
  "sequenceId": 1
}

Jest sequenceId to liczba przyrostowa uint64 w sesji identyfikatora połączenia. Subskrybenci powinni rejestrować największe sequenceId odebrane komunikaty, akceptować tylko komunikaty o większym sequenceIdrozmiarze i usuwać komunikaty o mniejszej lub równej sequenceIdwartości . Subskrybent powinien znajdować się z największą sequenceId zarejestrowaną wartością, aby usługa mogła pominąć ponowne pobieranie komunikatów, które już otrzymali subskrybenci. Jeśli na przykład subskrybent odpowie za pomocą sequenceAck sequenceId: 5polecenia , usługa będzie ponownie wysyłać komunikaty o rozmiarze sequenceId większym niż 5.

Wszystkie komunikaty są dostarczane do subskrybentów w kolejności, dopóki połączenie protokołu WebSocket nie spadnie. Dzięki sequenceIdusłudze usługa może wiedzieć, ile komunikatów subskrybentów odebrało w ramach połączeń protokołu WebSocket w sesji. Po spadku połączenia protokołu WebSocket usługa będzie ponownie obsługiwać komunikaty nieuznane przez subskrybenta. Usługa przechowuje ograniczoną liczbę niezaznaczonych komunikatów. Gdy liczba komunikatów przekroczy limit, usługa zamknie połączenie protokołu WebSocket i usunie sesję. W związku z tym subskrybenci powinni jak sequenceId najszybciej.