Partilhar via


Extensão CloudEvents para manipulador de eventos Azure Web PubSub com protocolo HTTP

O serviço Web PubSub fornece eventos de cliente para o webhook upstream usando a associação do protocolo HTTP CloudEvents.

Os dados enviados do serviço Web PubSub para o servidor estão sempre no formato CloudEvents binary .

Validação de Webhook

A validação do Webhook segue o CloudEvents. A solicitação sempre contém WebHook-Request-Origin: xxx.webpubsub.azure.com no cabeçalho.

Se e somente se o destino de entrega permitir a entrega dos eventos, ele DEVE responder à solicitação incluindo WebHook-Allowed-Origin cabeçalho, por exemplo:

WebHook-Allowed-Origin: *

Ou:

WebHook-Allowed-Origin: xxx.webpubsub.azure.com

Por enquanto, WebHook-Request-Rate e WebHook-Request-Callback não são suportados.

Extensão do atributo Web PubSub CloudEvents

Também foi observado que a especificação HTTP agora está seguindo um padrão semelhante, não sugerindo mais que os cabeçalhos HTTP de extensão sejam prefixados com X-.

Esta extensão define atributos usados pelo Web PubSub para cada evento que produz.

Atributos

Nome Tipo Description Exemplo
userId string O usuário a conexão authed
hub string O hub ao qual a conexão pertence
connectionId string O connectionId é exclusivo para a conexão do cliente
eventName string O nome do evento sem prefixo
subprotocol string O subprotocolo que o cliente está usando, se houver
connectionState string Define o estado da conexão. Você pode usar o mesmo cabeçalho de resposta para redefinir o valor do estado. Não são permitidos vários connectionState cabeçalhos. Faça base64 codificar o valor da cadeia de caracteres se ela contiver caracteres complexos dentro, por exemplo, base64(jsonString) para passar objeto complexo usando esse atributo.
signature string A assinatura do webhook upstream para validar se a solicitação de entrada é da origem esperada. O serviço calcula o valor usando a chave de acesso primária e a chave de acesso secundária como a HMAC chave: Hex_encoded(HMAC_SHA256(accessKey, connectionId)). O upstream deve verificar se o pedido é válido antes de o processar.

Evento

Existem dois tipos de eventos. Uma delas é bloquear eventos que o serviço aguarda a resposta do evento para continuar. Uma delas é desbloquear eventos que o serviço não espera pela resposta desse evento antes de processar a próxima mensagem.

Evento do sistema connect

  • ce-type: azure.webpubsub.sys.connect
  • Content-Type: application/json

Formato do pedido:

POST /upstream HTTP/1.1
Host: xxxxxx
WebHook-Request-Origin: xxx.webpubsub.azure.com
Content-Type: application/json; charset=utf-8
Content-Length: nnnn
ce-specversion: 1.0
ce-type: azure.webpubsub.sys.connect
ce-source: /hubs/{hub}/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}
ce-eventName: connect

{
    "claims": {},
    "query": {},
    "headers": {},
    "subprotocols": [],
    "clientCertificates": [
        {
            "thumbprint": "<certificate SHA-1 thumbprint>",
            "content": "-----BEGIN CERTIFICATE-----\r\n...\r\n-----END CERTIFICATE-----"
        }
    ]
}

Formato de resposta de sucesso:

  • Cabeçalho ce-connectionState: Se esse cabeçalho existir, o estado da conexão dessa conexão será atualizado para o valor do cabeçalho. Somente eventos de bloqueio podem atualizar o estado da conexão. O exemplo abaixo usa a cadeia de caracteres JSON codificada em base64 para armazenar o estado complexo da conexão.

  • Código de status:

    • 204: Sucesso, sem conteúdo.
    • 200: Sucesso, o conteúdo DEVE ser um formato JSON, com as seguintes propriedades permitidas:
      • subprotocols

        O connect evento encaminha o subprotocolo e as informações de autenticação para Upstream a partir do cliente. O serviço Web PubSub usa o código de status para determinar se a solicitação será atualizada para o protocolo WebSocket.

        Se a solicitação contiver a subprotocols propriedade, o servidor deverá retornar um subprotocolo suportado. Se o servidor não quiser usar nenhum subprotocolo, ele não deve enviar a subprotocol propriedade em resposta. O envio de um cabeçalho em branco é inválido.

      • userId: {auth-ed user ID}

        Como o serviço permite conexões anônimas connect , é responsabilidade do evento informar ao serviço o ID de usuário da conexão do cliente. O serviço lê o ID do usuário da carga userId de resposta, se ele existir. A conexão será descartada se o ID do usuário não puder ser lido das declarações de solicitação nem da carga útil de resposta do connect evento.

      • groups: {groups to join}

        A propriedade fornece uma maneira conveniente para o usuário adicionar essa conexão a um ou vários grupos. Dessa forma, não há necessidade de ter outra chamada para adicionar essa conexão a algum grupo.

      • roles: {roles the client has}

        A propriedade fornece uma maneira para o Webhook upstream para autorizar o cliente. Há diferentes funções para conceder permissões iniciais para clientes PubSub WebSocket. Os detalhes sobre as permissões são descritos em Permissões de cliente.

HTTP/1.1 200 OK
ce-connectionState: eyJrZXkiOiJhIn0=

{
    "groups": [],
    "userId": "",
    "roles": [],
    "subprotocol": ""
}

Formato de resposta de erro:

  • 4xx: Erro, a resposta do Upstream será retornada como a resposta para a solicitação do cliente.
HTTP/1.1 401 Unauthorized

Evento do sistema connected

O serviço chama o Upstream quando o cliente conclui o handshake WebSocket e é conectado com êxito.

  • ce-type: azure.webpubsub.sys.connected
  • Content-Type: application/json
  • ce-connectionState: eyJrZXkiOiJhIn0=

O corpo da solicitação está vazio JSON.

Formato do pedido:

POST /upstream HTTP/1.1
Host: xxxxxx
WebHook-Request-Origin: xxx.webpubsub.azure.com
Content-Type: application/json; charset=utf-8
Content-Length: nnnn
ce-specversion: 1.0
ce-type: azure.webpubsub.sys.connected
ce-source: /hubs/{hub}/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}
ce-eventName: connected
ce-subprotocol: abc
ce-connectionState: eyJrZXkiOiJhIn0=

{}

Formato da resposta:

2xx: resposta de sucesso.

connected é um evento assíncrono, quando o código de status da resposta não é bem-sucedido, o serviço registra um erro.

HTTP/1.1 200 OK

Evento do sistema disconnected

disconnectedO evento é sempre acionado quando a solicitação do cliente é concluída se o evento Connect retornar 2xx o código de status.

  • ce-type: azure.webpubsub.sys.disconnected
  • Content-Type: application/json

Formato do pedido:

POST /upstream HTTP/1.1
Host: xxxxxx
WebHook-Request-Origin: xxx.webpubsub.azure.com
Content-Type: application/json; charset=utf-8
Content-Length: nnnn
ce-specversion: 1.0
ce-type: azure.webpubsub.sys.disconnected
ce-source: /hubs/{hub}/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}
ce-eventName: disconnected
ce-subprotocol: abc
ce-connectionState: eyJrZXkiOiJhIn0=

{
    "reason": "{Reason}"
}

  • reason

    O reason descreve o motivo pelo qual o cliente se desconecta.

Formato da resposta:

2xx: resposta de sucesso.

disconnected é um evento assíncrono, quando o código de status da resposta não é bem-sucedido, o serviço registra um erro.

HTTP/1.1 200 OK

Evento message de usuário para os clientes WebSocket simples

O serviço invoca o manipulador de eventos upstream para cada quadro de mensagem WebSocket.

  • ce-type: azure.webpubsub.user.message
  • Content-Type: application/octet-stream para quadro binário; text/plain para quadro de texto;

UserPayload é o que o cliente envia.

Formato do pedido:

POST /upstream HTTP/1.1
Host: xxxxxx
WebHook-Request-Origin: xxx.webpubsub.azure.com
Content-Type: application/octet-stream | text/plain | application/json
Content-Length: nnnn
ce-specversion: 1.0
ce-type: azure.webpubsub.user.message
ce-source: /hubs/{hub}/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}
ce-eventName: message
ce-connectionState: eyJrZXkiOiJhIn0=

UserPayload

Formato de resposta de sucesso

  • Código de status
    • 204: Sucesso, sem conteúdo.
    • 200: Sucesso, o formato do UserResponsePayload depende da Content-Type resposta.
  • Content-Type: application/octet-stream para quadro binário; text/plain para quadro de texto;
  • Cabeçalho Content-Type: application/octet-stream para quadro binário; text/plain para quadro de texto;
  • Cabeçalho ce-connectionState: Se esse cabeçalho existir, o estado da conexão dessa conexão será atualizado para o valor do cabeçalho. Somente eventos de bloqueio podem atualizar o estado da conexão. O exemplo abaixo usa a cadeia de caracteres JSON codificada em base64 para armazenar o estado complexo da conexão.

Quando o Content-Type é application/octet-stream, o serviço envia UserResponsePayload para o cliente usando binary o quadro WebSocket. Quando o Content-Type é text/plain, o serviço envia UserResponsePayload para o cliente usando text o quadro WebSocket.

HTTP/1.1 200 OK
Content-Type: application/octet-stream (for binary frame) or text/plain (for text frame)
Content-Length: nnnn
ce-connectionState: eyJrZXkiOiJhIn0=

UserResponsePayload

Formato de resposta de erro

Quando o código de status não é bem-sucedido, é considerado uma resposta de erro. A conexão será descartada se o código de status da message resposta não for bem-sucedido.

Evento {custom_event} personalizado do usuário para clientes PubSub WebSocket

O serviço chama o webhook do manipulador de eventos para cada mensagem de evento personalizada válida.

Caso 1: enviar evento com dados de texto:

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

O que o manipulador de eventos upstream recebe como abaixo, o Content-Type para a solicitação HTTP do CloudEvents é text/plain para dataType=text

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>
ce-subprotocol: json.webpubsub.azure.v1
ce-connectionState: eyJrZXkiOiJhIn0=

text data

Caso 2: enviar evento com dados JSON:

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

O que o manipulador de eventos upstream recebe como abaixo, o Content-Type para a solicitação HTTP do CloudEvents é application/json para dataType=json

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>
ce-subprotocol: json.webpubsub.azure.v1
ce-connectionState: eyJrZXkiOiJhIn0=

{
    "hello": "world"
}

Caso 3: enviar evento com dados binários:

{
    "type": "event",
    "event": "<event_name>",
    "dataType" : "binary",
    "data": "aGVsbG8gd29ybGQ=" // base64 encoded binary
}

O que o manipulador de eventos upstream recebe como abaixo, o Content-Type para a solicitação HTTP do CloudEvents é application/octet-stream para dataType=binary

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>
ce-subprotocol: json.webpubsub.azure.v1

<binary data>

Formato de resposta de sucesso

HTTP/1.1 200 OK
Content-Type: application/octet-stream | text/plain | application/json
Content-Length: nnnn

UserResponsePayload
  • Código de status
    • 204: Sucesso, sem conteúdo.
    • 200: Sucesso, o envio de dados para o cliente PubSub WebSocket depende do Content-Type;
  • Cabeçalho ce-connectionState: Se esse cabeçalho existir, o estado da conexão dessa conexão será atualizado para o valor do cabeçalho. Somente eventos de bloqueio podem atualizar o estado da conexão. O exemplo abaixo usa a cadeia de caracteres JSON codificada em base64 para armazenar o estado complexo da conexão.
  • Quando Header Content-Type é application/octet-stream, o serviço envia UserResponsePayload de volta para o cliente usando dataType como binary com payload base64 codificado. Um exemplo de resposta:
    {
        "type": "message",
        "from": "server",
        "dataType": "binary",
        "data" : "aGVsbG8gd29ybGQ="
    }
    
  • Quando o Content-Type é text/plain, o serviço envia UserResponsePayload para o cliente usando dataType como text com a cadeia de caracteres de carga útil.
  • Quando o Content-Type é application/json, o serviço envia UserResponsePayload para o cliente usando dataType=json com data token de valor como o corpo da carga útil de resposta.

Formato de resposta de erro

Quando o código de status não é bem-sucedido, é considerado uma resposta de erro. A conexão será descartada se o código de status da {custom_event} resposta não for bem-sucedido.

Próximos passos

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