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
- Extensão de atributo WebPubSub CloudEvents
- Eventos
- Bloquear eventos
- Desbloqueando eventos
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.
- Bloquear eventos
- Desbloqueando eventos
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 asubprotocol
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 cargauserId
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 doconnect
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
disconnected
O 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 doUserResponsePayload
depende daContent-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 doContent-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 enviaUserResponsePayload
de volta para o cliente usandodataType
comobinary
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 enviaUserResponsePayload
para o cliente usandodataType
comotext
com a cadeia de caracteres de carga útil. - Quando o
Content-Type
éapplication/json
, o serviço enviaUserResponsePayload
para o cliente usandodataType
=json
comdata
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: