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_id
i :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:
- Połączenie protokołu Websocket jest zamykane z kodem stanu 1008. Kod stanu oznacza, że identyfikator connectionId został usunięty z usługi.
- 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"
}
}
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"
}
}
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 sequenceId
rozmiarze i usuwać komunikaty o mniejszej lub równej sequenceId
wartoś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: 5
polecenia , 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 sequenceId
usł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.