Extensão CloudEvents para o manipulador de eventos do Azure Web PubSub com protocolo HTTP
O serviço Web PubSub fornece eventos de cliente para o webhook upstream usando a Associação de protocolo HTTP CloudEvents.
Os dados enviados do serviço Web PubSub para o servidor estão sempre no formato binary
do CloudEvents.
- Validação de Webhook
- Extensão de Atributo CloudEvents da Web PubSub
- Eventos
- Eventos de bloqueio
- Eventos de desbloqueio
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 DEVERÁ responder à solicitação incluindo o cabeçalho WebHook-Allowed-Origin
, por exemplo:
WebHook-Allowed-Origin: *
Ou:
WebHook-Allowed-Origin: xxx.webpubsub.azure.com
Por enquanto, WebHook-Request-Rate e WebHook-Request-Callback não têm suporte.
Extensão de atributo CloudEvents da Web PubSub
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 tenham o prefixo X-.
Essa extensão define os atributos usados pelo Web PubSub para cada evento que produz.
Atributos
Nome | Tipo | Descrição | Exemplo |
---|---|---|---|
userId |
string |
O usuário com a conexão autenticada | |
hub |
string |
O hub ao qual a conexão pertence | |
connectionId |
string |
O connectionId é único 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 é permitido usar vários cabeçalhos connectionState . Codifique o valor da cadeia de caracteres em base64 se ele contiver caracteres complexos, por exemplo, use base64(jsonString) para transmitir um objeto complexo usando esse atributo. |
|
signature |
string |
A assinatura do webhook de 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 secundária como a chave HMAC : Hex_encoded(HMAC_SHA256(accessKey, connectionId)) . O upstream deve verificar se a solicitação é válida antes de processá-la. |
Eventos
Há dois tipos de eventos. Um é o evento de bloqueio, cuja resposta é aguardada pelo serviço para continuar. Outro é o evento de desbloqueio para que o serviço não espere a resposta de tal evento antes de processar a próxima mensagem.
- Eventos de bloqueio
- Eventos de desbloqueio
Evento connect
do sistema
ce-type
:azure.webpubsub.sys.connect
Content-Type
:application/json
Formato de solicitação:
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 êxito:
Cabeçalho
ce-connectionState
: se esse cabeçalho existir, o estado dessa conexão será atualizado para o valor do cabeçalho. Somente os 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
: êxito, sem conteúdo.200
: êxito, o conteúdo DEVE ser um formato JSON, com as seguintes propriedades permitidas:subprotocols
O evento
connect
encaminha as informações de subprotocolo e de autenticação para upstream 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 propriedade
subprotocols
, o servidor deverá retornar um subprotocolo com suporte. Se o servidor não quiser usar nenhum subprotocolo, ele não deve enviar a propriedadesubprotocol
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, é responsabilidade do evento
connect
informar ao serviço a ID de usuário da conexão do cliente. O serviço lê a ID de usuário do conteúdo de respostauserId
, se existir. A conexão será interrompida se a ID de usuário não puder ser lida das declarações de solicitação nem do conteúdo de resposta do eventoconnect
.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 autorizar o cliente. Há funções diferentes para conceder permissões iniciais para clientes WebSocket do PubSub. 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 da 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 connected
do sistema
O serviço chama o upstream quando o cliente conclui o handshake do WebSocket e é conectado com êxito.
ce-type
:azure.webpubsub.sys.connected
Content-Type
:application/json
ce-connectionState
:eyJrZXkiOiJhIn0=
O corpo da solicitação é um JSON vazio.
Formato de solicitação:
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 êxito.
connected
é um evento assíncrono; quando o código de status de resposta não é bem-sucedido, o serviço registra um erro.
HTTP/1.1 200 OK
Evento disconnected
do sistema
O evento disconnected
é sempre disparado quando a solicitação do cliente é concluída, se o evento connect retorna o código de status 2xx
.
ce-type
:azure.webpubsub.sys.disconnected
Content-Type
:application/json
Formato de solicitação:
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 êxito.
disconnected
é um evento assíncrono; quando o código de status de resposta não é bem-sucedido, o serviço registra um erro.
HTTP/1.1 200 OK
Evento de usuário message
para 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 de solicitação:
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 êxito
- Código de status
204
: êxito, sem conteúdo.200
: êxito, o formato deUserResponsePayload
depende deContent-Type
da resposta.
Content-Type
:application/octet-stream
para quadro binário;text/plain
para quadro de texto;- Cabeçalho
Content-Type
:application/octet-stream
para o quadro binário;text/plain
para o quadro de texto; - Cabeçalho
ce-connectionState
: se esse cabeçalho existir, o estado dessa conexão será atualizado para o valor do cabeçalho. Somente os 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 Content-Type
for application/octet-stream
, o serviço envia UserResponsePayload
para o cliente usando o quadro WebSocket binary
. Quando Content-Type
for text/plain
, o serviço envia UserResponsePayload
para o cliente usando o quadro WebSocket text
.
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 da resposta de erro
Quando o código de status não é êxito, ele é considerado uma resposta de erro. A conexão será interrompida se o código de status de resposta message
não for de êxito.
Evento personalizado do usuário {custom_event}
para clientes PubSub WebSocket
O serviço chama o webhook do manipulador de eventos para cada mensagem de evento personalizado 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 de 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 de 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 de 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 êxito
HTTP/1.1 200 OK
Content-Type: application/octet-stream | text/plain | application/json
Content-Length: nnnn
UserResponsePayload
- Código de status
204
: êxito, sem conteúdo.200
: êxito, o envio de dados para o cliente PubSub WebSocket depende doContent-Type
;
- Cabeçalho
ce-connectionState
: se esse cabeçalho existir, o estado dessa conexão será atualizado para o valor do cabeçalho. Somente os 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 cabeçalho
Content-Type
forapplication/octet-stream
, o serviço enviaráUserResponsePayload
de volta ao cliente usandodataType
comobinary
com a carga codificada em Base64. Um exemplo de resposta:{ "type": "message", "from": "server", "dataType": "binary", "data" : "aGVsbG8gd29ybGQ=" }
- Quando
Content-Type
fortext/plain
, o serviço enviaUserResponsePayload
ao cliente usandodataType
comotext
com a cadeia de caracteres do conteúdo. - Quando
Content-Type
forapplication/json
, o serviço enviaUserResponsePayload
ao cliente usandodataType
=json
com o token de valordata
como o corpo conteúdo de resposta.
Formato da resposta de erro
Quando o código de status não é êxito, ele é considerado uma resposta de erro. A conexão será interrompida se o código de status de resposta {custom_event}
não for de êxito.
Próximas etapas
Use estes recursos para começar a criar seu aplicativo: