Crie websocket fiável com subprotocol
As ligações do cliente websocket podem cair devido a problemas de rede intermitentes e quando as ligações caírem, as mensagens também serão perdidas. Num sistema pubsub, as editoras são dissociadas dos assinantes, pelo que as editoras são difíceis de detetar a queda de subscritores ou a perda de mensagens. É crucial para os clientes superarem o problema de rede intermitente e manterem a fiabilidade da entrega de mensagens. Para isso, pode criar um cliente Websocket confiável com a ajuda de subprotocols fiáveis.
Nota
Protocolos fiáveis ainda estão em pré-visualização. Esperam-se algumas mudanças no futuro.
Protocolo fiável
O serviço suporta dois subprotocols json.reliable.webpubsub.azure.v1
fiáveis e protobuf.reliable.webpubsub.azure.v1
. Os clientes devem seguir o protocolo, incluindo principalmente a parte da reconexão, editor e assinante para obter a fiabilidade, ou a entrega de mensagens pode não funcionar como esperado ou o serviço pode rescindir o cliente uma vez que viola a especificação do protocolo.
Inicialização
Para utilizar subprotocols fiáveis, deve definir subprotocol ao construir ligações Websocket. No JavaScript, pode utilizar como seguinte:
Use subprotocol Json fiável
var pubsub = new WebSocket('wss://test.webpubsub.azure.com/client/hubs/hub1', 'json.reliable.webpubsub.azure.v1');
Utilize subprotocol protobuf fiável
var pubsub = new WebSocket('wss://test.webpubsub.azure.com/client/hubs/hub1', 'protobuf.reliable.webpubsub.azure.v1');
Reconexão
As ligações websocket retransmitimem no TCP, por isso, se a ligação não cair, todas as mensagens devem ser sem perdas e em ordem. Quando confrontados com problemas de rede e ligações caem, todo o estado como informações de grupo e de mensagens são mantidos pelo serviço e aguardam a reconexão para recuperar. Uma ligação Websocket é proprietária de uma sessão no serviço e o identificador é connectionId
. A reconexão é a base para a fiabilidade e deve ser implementada. Quando uma nova ligação se ligar ao serviço utilizando subprotocols fiáveis, a ligação receberá uma Connected
mensagem e connectionId
reconnectionToken
.
{
"type":"system",
"event":"connected",
"connectionId": "<connection_id>",
"reconnectionToken": "<reconnection_token>"
}
Uma vez que a ligação WebSocket caiu, o cliente deve primeiro tentar reconectar-se com o mesmo connectionId
para manter a sessão. Os clientes não precisam de negociar com o servidor e obter o access_token
. Em vez disso, a reconexão deve fazer um pedido de ligação websocket ao serviço diretamente com connection_id
e reconnection_token
com os seguintes uri:
wss://<service-endpoint>/client/hubs/<hub>?awps_connection_id=<connection_id>&awps_reconnection_token=<reconnection_token>
A reconexão pode falhar, uma vez que o problema da rede ainda não foi recuperado. O cliente deve continuar a tentar reconectar-se até
- Ligação websocket fechada com o código de estado 1008. O código de estado significa que a ligaçãoId foi removida do serviço.
- A falha de reconexão mantém-se mais de 1 minuto.
Publisher
Os clientes que enviam eventos para o manipulador de eventos ou publicam mensagem a outros clientes são chamados editores no documento. Os editores devem definir ackId
a mensagem para ser reconhecido pelo serviço sobre se a mensagem publica o sucesso ou não. A ackId
mensagem na mensagem é o identificador da mensagem, o que significa que mensagens diferentes devem usar diferentes ackId
s, enquanto a mensagem de reencamamento deve manter o mesmo ackId
para o serviço des duplicado.
Um grupo de amostras envia mensagem:
{
"type": "sendToGroup",
"group": "group1",
"dataType" : "text",
"data": "text data",
"ackId": 1
}
Uma resposta de amostra ack:
{
"type": "ack",
"ackId": 1,
"success": true
}
Se o serviço voltar a funcionar, success: true
a mensagem foi processada pelo serviço e o cliente pode esperar que a mensagem seja entregue a todos os assinantes.
No entanto, em alguns casos, o Serviço encontra algum erro interno transitório e a mensagem não pode ser enviada para assinante. Nesse caso, a editora receberá uma mensagem como seguir e deve reencaixar a mensagem com a mesma ackId
se for necessária com base na lógica de negócio.
{
"type": "ack",
"ackId": 1,
"success": false,
"error": {
"name": "InternalServerError",
"message": "Internal server error"
}
}
O serviço pode ser abandonado devido à ligação WebSockets ter caído. Assim, os editores devem ser notificados quando a ligação Websocket cair e reencamender a mensagem com a mesma ackId
após a reconexão. Se a mensagem tiver realmente sido processada pelo serviço, irá responder ack com Duplicate
e os editores devem parar de reencaender esta mensagem novamente.
{
"type": "ack",
"ackId": 1,
"success": false,
"error": {
"name": "Duplicate",
"message": "Message with ack-id: 1 has been processed"
}
}
Assinante
Os clientes que recebem mensagens enviadas de manipuladores de eventos ou editores são chamados de assinante no documento. Quando as ligações deixam de ser por problemas de rede, o serviço não sabe quantas mensagens são realmente enviadas para os assinantes. Assim, os assinantes devem dizer ao serviço que mensagem foi recebida. As mensagens de dados contêm sequenceId
e os assinantes devem ack o id de sequência com a mensagem ack de sequência:
Uma sequência de amostra ack:
{
"type": "sequenceAck",
"sequenceId": 1
}
O id de sequência é um número incremental uint64 com uma sessão de id de ligação. Os assinantes devem registar o maior id de sequência que já recebeu e aceitar todas as mensagens com id de sequência maior e deixar cair todas as mensagens com id de sequência menor ou igual. A sequência ack suporta ack cumulativa, o que significa que se você ack sequence-id=5
, o serviço irá tratar todas as mensagens com id de sequência inferior a 5 já foram recebidas por assinantes. Os subscritores deverão encontrar o maior id de sequência que registou, para que o serviço possa saltar para reenvirar mensagens que os assinantes já receberam.
Todas as mensagens são entregues aos assinantes por ordem até que a ligação WebSockets caia. Com o id de sequência, o serviço pode ter o conhecimento de quantas mensagens os assinantes receberam através de ligações WebSockets com uma sessão de id de ligação. Após a queda de uma ligação WebSockets, o serviço irá reaquecê-las mensagens que deve entregar, mas não ack-ed pelo assinante. O serviço retém mensagens que não são ack-ed com limite, se as mensagens excederem o limite, o serviço fechará a ligação WebSockets e removerá a sessão de id de ligação. Assim, os subscritores devem ack ad a sequência id o mais rapidamente possível.