Compartilhar via


Crie WebSocket confiável com subprotocolo

Quando as conexões de cliente WebSocket são descartadas devido a problemas de rede intermitentes, as mensagens podem ser perdidas. Em um sistema pub/sub, os editores são dissociados dos assinantes, portanto, os editores podem não detectar a queda de conexão ou a perda de mensagens de um assinante. É crucial que os clientes superem problemas de rede intermitentes e mantenham a entrega confiável de mensagens. Para conseguir isso, você pode criar um cliente WebSocket confiável com a ajuda de subprotocolos confiáveis do Azure Web PubSub.

Protocolo confiável

O serviço Web PubSub oferece suporte a dois subprotocolos json.reliable.webpubsub.azure.v1 confiáveis e protobuf.reliable.webpubsub.azure.v1. Os clientes devem seguir as partes do editor, do assinante e da recuperação do subprotocolo para obter confiabilidade. A falha na implementação adequada do subprotocolo pode fazer com que a entrega da mensagem não funcione conforme o esperado ou o serviço encerre o cliente devido a violações de protocolo.

A maneira mais fácil - Use o SDK do cliente

A maneira mais simples de criar um cliente confiável é usar o SDK do cliente. O SDK do cliente implementa a especificação do cliente Web PubSub e usa json.reliable.webpubsub.azure.v1 por padrão. Consulte Publicar/assinar entre clientes para iniciar rapidamente.

A maneira mais difícil - Implemente manualmente

O tutorial a seguir orienta você pela parte importante da implementação da especificação do cliente Web PubSub. Este guia não é para pessoas que procuram um início rápido, mas que desejam conhecer o princípio de alcançar a confiabilidade. Para um início rápido, use o SDK do cliente.

Inicialização

Para usar subprotocolos confiáveis, você deve definir o subprotocolo ao construir conexões WebSocket. Em JavaScript, você pode usar o seguinte código:

  • Use o subprotocolo confiável Json:

    var pubsub = new WebSocket(
      "wss://test.webpubsub.azure.com/client/hubs/hub1",
      "json.reliable.webpubsub.azure.v1"
    );
    
  • Use o subprotocolo confiável do Protobuf:

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

Recuperação da conexão

A recuperação de conexão é a base para alcançar a confiabilidade e deve ser implementada ao usar os json.reliable.webpubsub.azure.v1 protocolos e protobuf.reliable.webpubsub.azure.v1 .

As conexões WebSocket dependem do TCP. Quando a conexão não cai, as mensagens são entregues sem perdas e em ordem. Para evitar a perda de mensagens em conexões descartadas, o serviço Web PubSub retém as informações de status da conexão, incluindo informações de grupo e mensagem. Essas informações são usadas para restaurar o cliente na recuperação da conexão

Quando o cliente se reconectar ao serviço usando subprotocolos confiáveis, o cliente receberá uma Connected mensagem contendo o connectionId e reconnectionToken. O connectionId identifica a sessão da conexão no serviço.

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

Depois que a conexão WebSocket cair, o cliente deverá tentar se reconectar com o mesmo connectionId para restaurar a mesma sessão. Os clientes não precisam negociar com o servidor e obter o access_tokenarquivo . Em vez disso, para recuperar a conexão, o cliente deve fazer uma solicitação de conexão WebSocket diretamente para o serviço com o nome do host do serviço, connection_ide reconnection_token:

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

A recuperação de conexão pode falhar se o problema de rede ainda não tiver sido recuperado. O cliente deve continuar tentando se reconectar até que:

  1. A conexão WebSocket é fechada com o código de status 1008. O código de status significa que a ConnectionID foi removida do serviço.
  2. Uma falha de recuperação continua a ocorrer por mais de 1 minuto.

Publicador

Os clientes que enviam eventos para manipuladores de eventos ou publicam mensagens para outros clientes são chamados de editores. Os editores devem definir ackId a mensagem para receber uma confirmação do serviço Web PubSub de que a publicação da mensagem foi bem-sucedida ou não.

O ackId é o identificador da mensagem, cada nova mensagem deve usar um ID exclusivo. O original ackId deve ser usado ao reenviar uma mensagem.

Uma mensagem de envio de grupo de exemplo:

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

Uma resposta ACK de exemplo:

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

Quando o serviço Web PubSub retorna uma resposta ack com success: true, a mensagem foi processada pelo serviço e o cliente pode esperar que a mensagem seja entregue a todos os assinantes.

Quando o serviço apresentar um erro interno transitório e a mensagem não puder ser enviada ao assinante, o editor receberá um ack com success: false. O editor deve ler o erro para determinar se deve ou não reenviar a mensagem. Se a mensagem for reenviada, a mesma ackId deve ser usada.

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

Falha da mensagem

Se a resposta de confirmação do serviço for perdida porque a conexão WebSocket caiu, o editor deverá reenviar a mensagem com a mesma ackId após a recuperação. Quando a mensagem foi processada anteriormente pelo serviço, ele enviará um ack contendo um Duplicate erro. O editor deve parar de reenviar essa mensagem.

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

Mensagem duplicada

Assinante

Os clientes que recebem mensagens de manipuladores de eventos ou editores são chamados de assinantes. Quando as conexões caem devido a problemas de rede, o serviço Web PubSub não sabe quantas mensagens foram enviadas aos assinantes. Para determinar a última mensagem recebida pelo assinante, o serviço envia uma mensagem de dados contendo um sequenceIdarquivo . O assinante responde com uma mensagem de confirmação de sequência:

Uma confirmação de sequência de exemplo:

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

O sequenceId é um número incremental uint64 em uma sessão de ID de conexão. Os assinantes devem registrar o maior sequenceId que recebeu, aceitar apenas mensagens com um maior sequenceId, e descartar mensagens com um menor ou igual sequenceId. O assinante deve aceitar o maior sequenceId que registrou, para que o serviço possa ignorar a reentrega de mensagens que os assinantes já receberam. Por exemplo, se o assinante responder com um sequenceAck with sequenceId: 5, o serviço só reenviará mensagens com um sequenceId maior que 5.

Todas as mensagens são entregues aos assinantes em ordem até que a conexão WebSocket caia. Com sequenceIdo , o serviço pode saber quantas mensagens os assinantes receberam em conexões WebSocket em uma sessão. Depois que uma conexão WebSocket for interrompida, o serviço entregará novamente as mensagens não confirmadas pelo assinante. O serviço armazena um número limitado de mensagens não confirmadas. Quando o número de mensagens exceder o limite, o serviço fechará a conexão WebSocket e removerá a sessão. Assim, os assinantes devem ackar o sequenceId mais rápido possível.