Subprotocolo WebSocket JSON confiável do Azure Web PubSub

O subprotocolo WebSocket JSON json.reliable.webpubsub.azure.v1 permite a troca altamente confiável de mensagens de publicação/assinatura diretamente entre clientes por meio do serviço sem uma viagem de ida e volta para o servidor upstream.

Este documento descreve o subprotocolo json.reliable.webpubsub.azure.v1.

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 e podem não detectar a perda de conexão ou mensagem de um assinante.

Para superar problemas de rede intermitentes e manter a entrega de mensagens confiável, você pode usar o subprotocolo json.reliable.webpubsub.azure.v1 do Azure WebPubSub para criar um cliente WebSocket PubSub confiável.

Um cliente WebSocket PubSub confiável pode:

Por exemplo, você pode criar um cliente WebSocket PubSub confiável com o seguinte código JavaScript:

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

Veja Como criar clientes confiáveis para implementar a reconexão e a confiabilidade de mensagens para clientes editor e assinante.

Quando o cliente está usando esse subprotocolo, os quadros de dados de saída e de entrada precisam conter conteúdos JSON.

Permissões

Um cliente WebSocket PubSub só pode publicar em outros clientes quando estiver autorizado. O atribuído roles ao cliente determina as permissões concedidas ao cliente:

Função Permissão
Não especificado O cliente pode enviar solicitações de evento.
webpubsub.joinLeaveGroup O cliente pode ingressar/sair de qualquer grupo.
webpubsub.sendToGroup O cliente pode publicar mensagens em qualquer grupo.
webpubsub.joinLeaveGroup.<group> O cliente pode ingressar/sair do grupo <group>.
webpubsub.sendToGroup.<group> O cliente pode publicar mensagens no grupo <group>.
webpubsub.joinLeaveGroups.<pattern> O cliente pode ingressar/sair de qualquer grupo cujo nome corresponde <pattern> (consulte padrões de função de grupo curinga).
webpubsub.sendToGroups.<pattern> O cliente pode publicar mensagens em qualquer grupo cujo nome corresponde <pattern> (consulte padrões de função de grupo curinga).

O servidor pode conceder ou revogar dinamicamente as permissões do cliente pelas APIs REST ou SDKs de servidor.

Observação

Funções curinga (por exemplo, webpubsub.sendToGroups.<pattern>) ainda não têm suporte em APIs REST ou SDKs de servidor durante o runtime.

Requests

Ingressar grupos

Formato:

{
    "type": "joinGroup",
    "group": "<group_name>",
    "ackId" : 1
}
  • ackId é a identidade de cada solicitação e deve ser exclusiva. O serviço envia uma mensagem de resposta ack para notificar o resultado do processo da solicitação. Para obter detalhes, consulte AckId e Ack Response

Sair dos grupos

Formato:

{
    "type": "leaveGroup",
    "group": "<group_name>",
    "ackId" : 1
}
  • ackId é a identidade de cada solicitação e deve ser exclusiva. O serviço envia uma mensagem de resposta ack para notificar o resultado do processo da solicitação. Para obter detalhes, consulte AckId e Ack Response

Publicar mensagens

Formato:

{
    "type": "sendToGroup",
    "group": "<group_name>",
    "ackId" : 1,
    "noEcho": true|false,
    "dataType" : "json|text|binary",
    "data": {}, // data can be string or valid json token depending on the dataType 
}
  • ackId é a identidade de cada solicitação e deve ser exclusiva. O serviço envia uma mensagem de resposta ack para notificar o resultado do processo da solicitação. Para obter detalhes, consulte AckId e Ack Response
  • noEcho é opcional. Se definida como verdadeira, essa mensagem não será ecoada de volta para a mesma conexão. Se não for definida, o valor padrão será falso.
  • dataType pode ser definido como json, text ou binary:
    • json: data pode ser qualquer tipo que o JSON dá suporte e será publicado como ele é. Se dataType não for especificado, o padrão será json.
    • text: data deve estar no formato de cadeia de caracteres e os dados da cadeia de caracteres serão publicados;
    • binary: data deve estar no formato base64 e os dados binários serão publicados;

Caso 1: publicar dados de texto:

{
    "type": "sendToGroup",
    "group": "<group_name>",
    "dataType" : "text",
    "data": "text data",
    "ackId": 1
}
  • Os clientes do subprotocolo em <group_name> recebem:
{
    "type": "message",
    "from": "group",
    "group": "<group_name>",
    "dataType" : "text",
    "data" : "text data"
}
  • Os clientes WebSocket simples em <group_name> recebem a cadeia de caracteres text data.

Caso 2: publicar dados JSON:

{
    "type": "sendToGroup",
    "group": "<group_name>",
    "dataType" : "json",
    "data": {
        "hello": "world"
    }
}
  • Os clientes do subprotocolo em <group_name> recebem:
{
    "type": "message",
    "from": "group",
    "group": "<group_name>",
    "dataType" : "json",
    "data" : {
        "hello": "world"
    }
}
  • Os clientes WebSocket simples em <group_name> recebem a cadeia de caracteres serializada {"hello": "world"}.

Caso 3: publicar dados binários:

{
    "type": "sendToGroup",
    "group": "<group_name>",
    "dataType" : "binary",
    "data": "<base64_binary>",
    "ackId": 1
}
  • Os clientes do subprotocolo em <group_name> recebem:
{
    "type": "message",
    "from": "group",
    "group": "<group_name>",
    "dataType" : "binary",
    "data" : "<base64_binary>", 
}
  • Os clientes WebSocket simples em <group_name> recebem os dados binários no quadro binário.

Enviar eventos personalizados

Formato:

{
    "type": "event",
    "event": "<event_name>",
    "ackId": 1,
    "dataType" : "json|text|binary",
    "data": {}, // data can be string or valid json token depending on the dataType 
}
  • ackId é a identidade de cada solicitação e deve ser exclusiva. O serviço envia uma mensagem de resposta ack para notificar o resultado do processo da solicitação. Para obter detalhes, consulte AckId e Ack Response

dataType pode ser um de text, binary ou json:

  • json: os dados podem ser qualquer tipo para o qual o JSON dá suporte e serão publicados como eles são. O padrão é json.
  • text: os dados estão no formato de cadeia de caracteres e os dados da cadeia de caracteres serão publicados;
  • binary: os dados devem estar no formato base64 e os dados binários serão publicados;

Caso 1: enviar evento com dados de texto:

{
    "type": "event",
    "event": "<event_name>",
    "ackId": 1,
    "dataType" : "text",
    "data": "text data", 
}

O manipulador de eventos upstream recebe uma solicitação semelhante a:

POST /upstream HTTP/1.1
Host: xxxxxx
WebHook-Request-Origin: xxx.webpubsub.azure.com
Content-Type: text/plain
Content-Length: nnnn
ce-specversion: 1.0
ce-type: azure.webpubsub.user.<event_name>
ce-source: /client/{connectionId}
ce-id: {eventId}
ce-time: 2021-01-01T00:00:00Z
ce-signature: sha256={connection-id-hash-primary},sha256={connection-id-hash-secondary}
ce-userId: {userId}
ce-connectionId: {connectionId}
ce-hub: {hub_name}
ce-eventName: <event_name>

text data

O Content-Type da solicitação HTTP do CloudEvents é text/plain, em que dataType é text.

Caso 2: enviar evento com dados JSON:

{
    "type": "event",
    "event": "<event_name>",
    "ackId": 1,
    "dataType" : "json",
    "data": {
        "hello": "world"
    }, 
}

O manipulador de eventos upstream recebe uma solicitação semelhante a:

POST /upstream HTTP/1.1
Host: xxxxxx
WebHook-Request-Origin: xxx.webpubsub.azure.com
Content-Type: application/json
Content-Length: nnnn
ce-specversion: 1.0
ce-type: azure.webpubsub.user.<event_name>
ce-source: /client/{connectionId}
ce-id: {eventId}
ce-time: 2021-01-01T00:00:00Z
ce-signature: sha256={connection-id-hash-primary},sha256={connection-id-hash-secondary}
ce-userId: {userId}
ce-connectionId: {connectionId}
ce-hub: {hub_name}
ce-eventName: <event_name>

{
    "hello": "world"
}

O Content-Type da solicitação HTTP do CloudEvents é application/json, em que dataType é json

Caso 3: enviar evento com dados binários:

{
    "type": "event",
    "event": "<event_name>",
    "ackId": 1,
    "dataType" : "binary",
    "data": "base64_binary", 
}

O manipulador de eventos upstream recebe uma solicitação semelhante a:

POST /upstream HTTP/1.1
Host: xxxxxx
WebHook-Request-Origin: xxx.webpubsub.azure.com
Content-Type: application/octet-stream
Content-Length: nnnn
ce-specversion: 1.0
ce-type: azure.webpubsub.user.<event_name>
ce-source: /client/{connectionId}
ce-id: {eventId}
ce-time: 2021-01-01T00:00:00Z
ce-signature: sha256={connection-id-hash-primary},sha256={connection-id-hash-secondary}
ce-userId: {userId}
ce-connectionId: {connectionId}
ce-hub: {hub_name}
ce-eventName: <event_name>

binary

O Content-Type da solicitação HTTP do CloudEvents é application/octet-stream, em que dataType é binary. O quadro WebSocket pode ser o formato text para os quadros de mensagem de texto ou binários codificados UTF8 para quadros de mensagem binary.

O serviço Web PubSub recusará o cliente se a mensagem não corresponder ao formato descrito.

Ping

Formato:

{
    "type": "ping",
}

O cliente pode enviar uma mensagem de ping para o serviço para habilitar o serviço Web PubSub a detectar a atividade do cliente.

Confirmação de sequência

Formato:

{
    "type": "sequenceAck",
    "sequenceId": "<sequenceId>",
}

O cliente WebSocket PubSub confiável precisará enviar uma mensagem de confirmação de sequência assim que receber uma mensagem do serviço. Para obter mais informações, confira Como criar clientes confiáveis

  • sequenceId é um número uint64 incremental da mensagem recebida.

Respostas

As mensagens recebidas pelo cliente podem ser de vários tipos: ack, message, system e pong. As mensagens com o tipo message têm a propriedade sequenceId. O cliente precisa enviar a Confirmação de sequência ao serviço depois de receber uma mensagem.

Resposta Ack

Quando a solicitação contiver ackId, o serviço retornará uma resposta rápida para essa solicitação. A implementação do cliente deve lidar com esse mecanismo de confirmação, incluindo aguardar a resposta de confirmação para uma operação asyncawait e ter uma verificação de tempo limite quando a resposta de confirmação não for recebida durante um determinado período.

Formato:

{
    "type": "ack",
    "ackId": 1, // The ack id for the request to ack
    "success": false, // true or false
    "error": {
        "name": "Forbidden|InternalServerError|Duplicate",
        "message": "<error_detail>"
    }
}

A implementação do cliente DEVERÁ sempre primeiro verificar se o success é true ou false. Somente quando success for false, o cliente lê a partir de error.

Resposta da mensagem

Os clientes podem receber mensagens publicadas de um grupo que o cliente ingressou ou do servidor, que, operando em uma função de gerenciamento de servidor, envia mensagens para clientes ou usuários específicos.

  1. A mensagem de resposta de um grupo:

    {
        "sequenceId": 1,
        "type": "message",
        "from": "group",
        "group": "<group_name>",
        "dataType": "json|text|binary",
        "data" : {} // The data format is based on the dataType
        "fromUserId": "abc"
    }
    
  2. A mensagem de resposta do servidor:

    {
        "sequenceId": 1,
        "type": "message",
        "from": "server",
        "dataType": "json|text|binary",
        "data" : {} // The data format is based on the dataType
    }
    

Casa 1: enviar dados Hello World para conexão por meio da API REST com Content-Type=text/plain

  • Um cliente WebSocket simples recebe um quadro WebSocket de texto com os dados: Hello World;

  • Um cliente WebSocket PubSub recebe a mensagem em JSON:

    {
        "sequenceId": 1,
        "type": "message",
        "from": "server",
        "dataType" : "text",
        "data": "Hello World", 
    }
    

Caso 2: enviar dados { "Hello" : "World"} para a conexão API REST com Content-Type=application/json

  • Um cliente WebSocket simples recebe um quadro WebSocket de texto com os dados de cadeia de caracteres: { "Hello" : "World"};

  • Um cliente WebSocket PubSub recebe a mensagem em JSON:

    {
        "sequenceId": 1,
        "type": "message",
        "from": "server",
        "dataType" : "json",
        "data": {
            "Hello": "World"
        }
    }
    

Se a API REST estiver enviando uma cadeia de caracteres Hello World usando o tipo de conteúdo application/json, o cliente WebSocket simples receberá a cadeia de caracteres JSON "Hello World" encapsulada em ".

Caso 3: enviar dados binários para a conexão por meio da API REST com Content-Type=application/octet-stream

  • Um cliente WebSocket simples recebe um quadro WebSocket binário com os dados binários.

  • Um cliente WebSocket PubSub recebe a mensagem em JSON:

    {
        "sequenceId": 1,
        "type": "message",
        "from": "server",
        "dataType" : "binary",
        "data": "<base64_binary>"
    }
    

Resposta do sistema

O serviço Web PubSub também pode retornar respostas relacionadas ao sistema para o cliente.

Resposta Pong

O serviço Web PubSub envia uma mensagem de pong para o cliente quando ele recebe uma mensagem de ping do cliente.

Formato:

{
    "type": "pong",
}

Conectado

A resposta à solicitação de conexão do cliente:

{
    "type": "system",
    "event": "connected",
    "userId": "user1",
    "connectionId": "abcdefghijklmnop",
    "reconnectionToken": "<token>"
}

connectionId e reconnectionToken são usados para reconexão. Faça a solicitação de conexão com URI para reconexão:

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

Encontre mais detalhes na Recuperação de Conexão

Desconectado

Quando o servidor fecha a conexão ou quando o serviço recusa a conexão do cliente:

{
    "type": "system",
    "event": "disconnected",
    "message": "reason"
}

Próximas etapas

Use estes recursos para começar a criar seu aplicativo: