Partage via


Extension CloudEvents pour le gestionnaire d’événements Azure Web PubSub avec le protocole HTTP

Le service Web PubSub fournit des événements client au webhook en amont à l’aide de liaison de protocole HTTP CloudEvents.

Les données envoyées du service web PubSub au serveur sont toujours au format binary CloudEvents.

Validation de webhook

La validation de webhook suit CloudEvents. La requête contient toujours WebHook-Request-Origin: xxx.webpubsub.azure.com dans l’en-tête.

Si et seulement si la cible de remise autorise la remise des événements, elle DOIT répondre à la requête en incluant l’en-tête WebHook-Allowed-Origin, par exemple :

WebHook-Allowed-Origin: *

Ou :

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

À l’heure actuelle, WebHook-Request-Rate et WebHook-Request-Callback ne sont pas pris en charge.

Extension d’attribut CloudEvents pour Web PubSub

Notez également que la spécification HTTP suit à présent un modèle similaire en ne suggérant plus que les en-têtes HTTP d’extension soient précédés de X-.

Cette extension définit les attributs utilisés par Web PubSub pour chaque événement généré.

Attributs

Nom Type Description Exemple
userId string L’utilisateur que la connexion a authentifié
hub string Le hub auquel appartient la connexion
connectionId string L’ID de connexion est unique pour la connexion cliente
eventName string Le nom de l’événement sans préfixe
subprotocol string Le sous-protocole utilisé par le client, le cas échéant
connectionState string Définit l’état de la connexion. Vous pouvez utiliser le même en-tête de réponse pour réinitialiser la valeur de l’état. Il est interdit d'utiliser plusieurs en-têtes connectionState. Codez en base64 la valeur de chaîne si elle contient des caractères complexes. Par exemple, base64(jsonString) pour transmettre un objet complexe à l’aide de cet attribut.
signature string La signature du webhook en amont pour valider si la requête entrante provient de l’origine attendue. Le service calcule la valeur à l’aide de la clé d’accès primaire et de la clé d’accès secondaire comme la clé HMAC : Hex_encoded(HMAC_SHA256(accessKey, connectionId)). L’amont doit vérifier si la requête est valide avant de la traiter.

Événements

Il existe deux types d’événements. D’une part, les événements bloquants pour lesquels le service attend la réponse de l’événement pour continuer. D’autre part, les événements débloquantspour lesquels le service n’attend pas la réponse de cet événement avant de traiter le message suivant.

Événement connect système

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

Format de la requête :

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-----"
        }
    ]
}

Format de la réponse en cas de réussite :

  • En-tête ce-connectionState : si cet en-tête existe, l’état de cette connexion est mis à jour avec la valeur de l’en-tête. Seuls les événements bloquants peuvent mettre à jour l’état de la connexion. L’exemple ci-dessous utilise une chaîne JSON codée en base64 pour stocker un état complexe pour la connexion.

  • Code d’état :

    • 204 : Réussite, sans contenu.
    • 200 : Réussite, le contenu DOIT être au format JSON, avec les propriétés suivantes autorisées :
      • subprotocols

        L’événement connect transmet à l’amont les informations de sous-protocole et d’authentification du client. Le service Web PubSub utilise le code d’état pour déterminer si la requête sera mise à niveau vers le protocole WebSocket.

        Si la requête contient la propriété subprotocols, le serveur doit retourner un sous-protocole qu’il prend en charge. Si le serveur ne souhaite pas utiliser de sous-protocoles, il ne doit pas envoyer la propriété subprotocol dans sa réponse. L’envoi d’un en-tête vide n’est pas valide.

      • userId: {auth-ed user ID}

        Étant donné que le service autorise les connexions anonymes, il incombe à l’événement connect d’indiquer au service l’identifiant utilisateur de la connexion cliente. Le service lit l’identifiant utilisateur à partir de la charge utile de réponse userId le cas échéant. La connexion est annulée si l’identifiant utilisateur ne peut pas être lu à partir des revendications de la requête ni de la charge utile de réponse de l’événement connect.

      • groups: {groups to join}

        La propriété est un moyen pratique pour l’utilisateur d’ajouter cette connexion à un ou plusieurs groupes. De cette façon, un autre appel n’est pas nécessaire pour ajouter cette connexion à un groupe.

      • roles: {roles the client has}

        La propriété est un moyen pour le Webhook en amont d’autoriser le client. Il existe différents rôles pour accorder des autorisations initiales pour les clients WebSocket PubSub. Des informations détaillées sur les autorisations sont fournies dans Autorisations client.

HTTP/1.1 200 OK
ce-connectionState: eyJrZXkiOiJhIn0=

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

Format de la réponse en cas d’erreur :

  • 4xx : Erreur, la réponse de l’amont sera renvoyée comme réponse à la requête du client.
HTTP/1.1 401 Unauthorized

Événement connected système

Le service appelle l’amont lorsque le client termine l’établissement de liaison WebSocket et est bien connecté.

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

Le corps de la requête est un JSON vide.

Format de la requête :

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=

{}

Format de la réponse :

2xx : réponse en cas de réussite.

connected est un événement asynchrone, si le code d’état de la réponse n’indique pas une réussite, le service consigne une erreur.

HTTP/1.1 200 OK

Événement disconnected système

L’événement disconnected est toujours déclenché quand la requête du client est terminée si l’événement connect renvoie le code d’état 2xx.

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

Format de la requête :

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

    reason décrit le motif de la déconnexion du client.

Format de la réponse :

2xx : réponse en cas de réussite.

disconnected est un événement asynchrone, si le code d’état de la réponse n’indique pas une réussite, le service consigne une erreur.

HTTP/1.1 200 OK

Événement utilisateur message pour les clients WebSocket simples

Le service appelle le gestionnaire d’événements en amont pour chaque trame de message WebSocket.

  • ce-type: azure.webpubsub.user.message
  • Content-Type : application/octet-stream pour une trame binaire ; text/plain pour une trame texte.

UserPayload correspond à ce que le client envoie.

Format de la requête :

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

Format de la réponse en cas de réussite

  • Code d’état
    • 204 : Réussite, sans contenu.
    • 200 : Réussite, le format de UserResponsePayload dépend du Content-Type de la réponse.
  • Content-Type : application/octet-stream pour une trame binaire ; text/plain pour une trame texte.
  • En-tête Content-Type : application/octet-stream pour une trame binaire ; text/plain pour une trame texte ;
  • En-tête ce-connectionState : si cet en-tête existe, l’état de cette connexion est mis à jour avec la valeur de l’en-tête. Seuls les événements bloquants peuvent mettre à jour l’état de la connexion. L’exemple ci-dessous utilise une chaîne JSON codée en base64 pour stocker un état complexe pour la connexion.

Lorsque Content-Type est application/octet-stream, le service envoie UserResponsePayload au client à l’aide d’une trame WebSocket binary. Lorsque Content-Type est text/plain, le service envoie UserResponsePayload au client à l’aide d’une trame 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

Format de la réponse en cas d’erreur

Lorsque le code d’état n’indique pas une réussite, il est considéré comme une réponse d’erreur. La connexion sera annulée si le code d’état de réponse message n’est pas une réussite.

Événement personnalisé utilisateur {custom_event} pour les clients WebSocket PubSub

Le service appelle le webhook du gestionnaire d’événements pour chaque message d’événement personnalisé valide.

Cas 1 : envoyer un événement avec des données texte :

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

Ce que le gestionnaire d’événements en amont reçoit ressemble à ceci, le Content-Type pour la requête HTTP CloudEvents est text/plain pour 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

Cas 2 : envoyer un événement avec des données JSON :

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

Ce que le gestionnaire d’événements en amont reçoit ressemble à ceci, le Content-Type pour la requête HTTP CloudEvents est application/json pour 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"
}

Cas 3 : envoyer un événement avec des données binaires :

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

Ce que le gestionnaire d’événements en amont reçoit ressemble à ceci, le Content-Type pour la requête HTTP CloudEvents est application/octet-stream pour 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>

Format de la réponse en cas de réussite

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

UserResponsePayload
  • Code d’état
    • 204 : Réussite, sans contenu.
    • 200 : Réussite, l’envoi de données au client WebSocket PubSub dépend du Content-Type.
  • En-tête ce-connectionState : si cet en-tête existe, l’état de cette connexion est mis à jour avec la valeur de l’en-tête. Seuls les événements bloquants peuvent mettre à jour l’état de la connexion. L’exemple ci-dessous utilise une chaîne JSON codée en base64 pour stocker un état complexe pour la connexion.
  • Lorsque En-tête Content-Type est application/octet-stream, le service renvoie UserResponsePayload au client avec dataType correspondant à binary et une charge utile codée en base64. Exemple de réponse :
    {
        "type": "message",
        "from": "server",
        "dataType": "binary",
        "data" : "aGVsbG8gd29ybGQ="
    }
    
  • Lorsque Content-Type est text/plain, le service envoie UserResponsePayload au client avec dataType correspondant à text et une chaîne de charge utile.
  • Lorsque Content-Type est application/json, le service envoie UserResponsePayload au client avec dataType=json et le jeton de valeur data comme corps de la charge utile de réponse.

Format de la réponse en cas d’erreur

Lorsque le code d’état n’indique pas une réussite, il est considéré comme une réponse d’erreur. La connexion sera annulée si le code d’état de réponse {custom_event} n’est pas une réussite.

Étapes suivantes

Utilisez ces ressources pour commencer à créer votre propre application :