CloudEvents-Erweiterung für Azure Web PubSub-Ereignishandler mit HTTP-Protokoll
Der Web PubSub-Dienst übergibt Clientereignisse mithilfe der CloudEvents-HTTP-Protokollbindung an den Upstream-Webhook.
Die Daten, die vom Web PubSub-Dienst an den Server gesendet werden, weisen immer das CloudEvents-Format binary
auf.
- Webhookvalidierung
- Web PubSub CloudEvents-Attributerweiterung
- Ereignisse
- Blockierende Ereignisse
- Nicht-blockierende Ereignisse
Webhookvalidierung
Die Webhookvalidierung folgt CloudEvents. Die Anforderung enthält immer WebHook-Request-Origin: xxx.webpubsub.azure.com
im Header.
Wenn und nur dann, wenn das Übermittlungsziel die Übermittlung der Ereignisse gestattet, MUSS es auf die Anforderung antworten, indem es den WebHook-Allowed-Origin
-Header mit einschließt, z. B.:
WebHook-Allowed-Origin: *
Oder:
WebHook-Allowed-Origin: xxx.webpubsub.azure.com
Vorerst werden WebHook-Request-Rate und WebHook-Request-Callback nicht unterstützt.
Web PubSub CloudEvents-Attributerweiterung
Es wurde auch erwähnt, dass die HTTP-Spezifikation jetzt einem ähnlichen Muster folgt, d. h. es wird nicht mehr vorgeschlagen, dass Erweiterungs-HTTP-Headern das Präfix X- vorangestellt wird.
Diese Erweiterung definiert Attribute, die von der Web PubSub-Anwendung für jedes von ihr erzeugte Ereignis verwendet werden.
Attribute
Name | Typ | Beschreibung des Dataflows | Beispiel |
---|---|---|---|
userId |
string |
Der Benutzer, für den die Verbindung authentifiziert wurde | |
hub |
string |
Der Hub, zu dem die Verbindung gehört | |
connectionId |
string |
Die connectionId ist für die Clientverbindung eindeutig definiert. | |
eventName |
string |
Der Name des Ereignisses ohne Präfix | |
subprotocol |
string |
Das Unterprotokoll, das der Client verwendet, sofern vorhanden. | |
connectionState |
string |
Legt den Status der Verbindung fest. Sie können denselben Antwort-Header verwenden, um den Wert des Status zurückzusetzen. Mehrere connectionState -Header sind nicht zulässig. Codieren Sie den Zeichenfolgenwert mit Base64, wenn er komplexe Zeichen enthält, z. B. base64(jsonString) , um komplexe Objekte mit diesem Attribut übergeben. |
|
signature |
string |
Die Signatur für den Upstreamwebhook, um zu überprüfen, ob die eingehende Anforderung vom erwarteten Ursprung stammt. Der Dienst berechnet den Wert mithilfe des primären Zugriffsschlüssels und des sekundären Zugriffsschlüssels als HMAC -Schlüssel: Hex_encoded(HMAC_SHA256(accessKey, connectionId)) . Der Upstream sollte vor der Verarbeitung überprüfen, ob die Anforderung gültig ist. |
Ereignisse
Es gibt zwei Arten von Ereignissen. Eine Art sind blockierende Ereignisse, d. h. der Dienst wartet und wird erst fortgesetzt, wenn die Antwort des Ereignisses vorliegt. Die andere Art sind nicht-blockierende Ereignisse, d. h. der Dienst wartet nicht auf die Antwort des Ereignisses, bevor die nächste Nachricht verarbeitet wird.
- Blockierende Ereignisse
- Nicht-blockierende Ereignisse
Systemconnect
ereignis
ce-type
:azure.webpubsub.sys.connect
Content-Type
:application/json
Anforderungsformat:
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 der Antwort bei Erfolg:
Kopfzeile
ce-connectionState
: Wenn dieser Header existiert, wird der Verbindungsstatus dieser Verbindung auf den Wert des Headers aktualisiert. Nur blockierende Ereignisse können den Verbindungsstatus aktualisieren. Das folgende Beispiel verwendet einen base64-kodierten JSON-String, um den komplexen Status der Verbindung zu speichern.Statuscode:
204
: Erfolg; ohne Inhalt.200
: Erfolg; der Inhalt SOLLTE ein JSON-Format mit den folgenden zulässigen Eigenschaften aufweisen:subprotocols
Das
connect
-Ereignis gibt das Unterprotokoll und die Authentifizierungsinformationen an Upstream vom Client weiter. Der Web PubSub-Dienst verwendet den Statuscode, um zu bestimmen, ob die Anforderung auf das WebSocket-Protokoll aktualisiert wird.Wenn die Anforderung die Eigenschaft
subprotocols
enthält, sollte der Server ein von ihm unterstütztes Unterprotokoll zurückgeben. Wenn der Server keine Unterprotokolle verwenden möchte, sollte er diesubprotocol
-Eigenschaft nicht als Antwort senden. Das Senden eines leeren Headers ist ungültig.userId
:{auth-ed user ID}
Da der Dienst anonyme Verbindungen zulässt, liegt es in der Verantwortung des
connect
Ereignisses, dem Dienst die Benutzer-ID der Clientverbindung mitzuteilen. Der Dienst liest die Benutzer-ID aus den AntwortnutzdatenuserId
, sofern diese existiert. Die Verbindung wird getrennt, wenn die Benutzer-ID weder aus den Anforderungsansprüchen noch aus der Antwortnutzdaten desconnect
-Ereignisses gelesen werden kann.groups
:{groups to join}
Die Eigenschaft bietet dem Benutzer eine praktische Möglichkeit, diese Verbindung zu einer oder mehreren Gruppen hinzuzufügen. Auf diese Weise ist kein weiterer Aufruf erforderlich, um diese Verbindung zu einer Gruppe hinzuzufügen.
roles
:{roles the client has}
Die Eigenschaft bietet dem Upstream-Webhook eine Möglichkeit, den Client zu autorisieren. Für PubSub WebSocket-Clients gibt es verschiedene Rollen, um anfängliche Berechtigungen zu erteilen. Weitere Informationen zu den Berechtigungen finden Sie unter Clientberechtigungen.
HTTP/1.1 200 OK
ce-connectionState: eyJrZXkiOiJhIn0=
{
"groups": [],
"userId": "",
"roles": [],
"subprotocol": ""
}
Format von Fehlerantworten:
4xx
: Fehler; die Antwort von Upstream wird als Antwort für die Clientanforderung zurückgegeben.
HTTP/1.1 401 Unauthorized
Systemconnected
ereignis
Der Dienst ruft Upstream auf, wenn der Client den WebSocket-Handshake abschließt und erfolgreich verbunden ist.
ce-type
:azure.webpubsub.sys.connected
Content-Type
:application/json
ce-connectionState
:eyJrZXkiOiJhIn0=
Der Anforderungstext ist ein leerer JSON-Code.
Anforderungsformat:
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=
{}
Antwortformat:
2xx
: Antwort bei Erfolg
connected
ist ein asynchrones Ereignis. Wenn der Antwortstatuscode nicht erfolgreich ist, protokolliert der Dienst einen Fehler.
HTTP/1.1 200 OK
Systemdisconnected
ereignis
Das disconnected
-Ereignis wird immer ausgelöst, wenn die Clientanforderung abgeschlossen wird, falls das connectEreignis (Verbinden) den Statuscode 2xx
zurückgibt.
ce-type
:azure.webpubsub.sys.disconnected
Content-Type
:application/json
Anforderungsformat:
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
beschreibt den Grund für die getrennten Clientverbindungen.
Antwortformat:
2xx
: Antwort bei Erfolg
disconnected
ist ein asynchrones Ereignis. Wenn der Antwortstatuscode nicht erfolgreich ist, protokolliert der Dienst einen Fehler.
HTTP/1.1 200 OK
Benutzerereignis message
für einfache WebSocket-Clients
Der Dienst ruft den Ereignishandler upstream für jeden WebSocket-Nachrichtenframe auf.
ce-type
:azure.webpubsub.user.message
Content-Type
:application/octet-stream
für binären Frame;text/plain
für Textframe;
UserPayload ist das, was der Client sendet.
Anforderungsformat:
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 der Antwort bei Erfolg
- Statuscode
204
: Erfolg; ohne Inhalt.200
: Erfolg; das Format vonUserResponsePayload
hängt vonContent-Type
der Antwort ab.
Content-Type
:application/octet-stream
für binären Frame;text/plain
für Textframe;- Kopfzeile
Content-Type
:application/octet-stream
für Binärrahmen;text/plain
für Textrahmen; - Kopfzeile
ce-connectionState
: Wenn dieser Header existiert, wird der Verbindungsstatus dieser Verbindung auf den Wert des Headers aktualisiert. Nur blockierende Ereignisse können den Verbindungsstatus aktualisieren. Das folgende Beispiel verwendet einen base64-kodierten JSON-String, um den komplexen Status der Verbindung zu speichern.
Wenn Content-Type
application/octet-stream
ist, sendet der Dienst UserResponsePayload
mithilfe des binary
WebSocket-Frames an den Client. Wenn Content-Type
text/plain
ist, sendet der Dienst UserResponsePayload
mithilfe des text
WebSocket-Frames an den Client.
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 von Fehlerantworten
Wenn der Statuscode nicht „Erfolg“ lautet, wird er als Fehlerantwort betrachtet. Die Verbindung wird getrennt, wenn der Antwortstatuscode message
nicht „Erfolg“ lautet.
Benutzerdefiniertes Ereignis {custom_event}
für PubSub WebSocket-Clients
Der Dienst ruft den Ereignishandler-Webhook für jede gültige benutzerdefinierte Ereignismeldung auf.
Fall 1: Ereignis mit Textdaten versenden:
{
"type": "event",
"event": "<event_name>",
"dataType" : "text",
"data": "text data"
}
Was der Upstream-Ereignishandler empfängt (siehe unten). Der Content-Type
der CloudEvents-HTTP-Anforderung ist text/plain
für 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
Fall 2: Ereignis mit JSON-Daten versenden:
{
"type": "event",
"event": "<event_name>",
"dataType" : "json",
"data": {
"hello": "world"
},
}
Was der Upstream-Ereignishandler empfängt (siehe unten). Der Content-Type
der CloudEvents-HTTP-Anforderung ist application/json
für 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"
}
Fall 3: Ereignis mit Binärdaten versenden:
{
"type": "event",
"event": "<event_name>",
"dataType" : "binary",
"data": "aGVsbG8gd29ybGQ=" // base64 encoded binary
}
Was der Upstream-Ereignishandler empfängt (siehe unten). Der Content-Type
der CloudEvents-HTTP-Anforderung ist application/octet-stream
für 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 der Antwort bei Erfolg
HTTP/1.1 200 OK
Content-Type: application/octet-stream | text/plain | application/json
Content-Length: nnnn
UserResponsePayload
- Statuscode
204
: Erfolg; ohne Inhalt.200
: Erfolg; daten, die an den PubSub WebSocket-Client gesendet werden, hängen vonContent-Type
ab.
- Kopfzeile
ce-connectionState
: Wenn dieser Header existiert, wird der Verbindungsstatus dieser Verbindung auf den Wert des Headers aktualisiert. Nur blockierende Ereignisse können den Verbindungsstatus aktualisieren. Das folgende Beispiel verwendet einen base64-kodierten JSON-String, um den komplexen Status der Verbindung zu speichern. - Wenn Kopfzeile
Content-Type
gleichapplication/octet-stream
ist, sendet der DienstUserResponsePayload
unter Verwendung vondataType
alsbinary
mit base64-kodierter Nutzlast an den Client zurück. Eine Beispielantwort:{ "type": "message", "from": "server", "dataType": "binary", "data" : "aGVsbG8gd29ybGQ=" }
- Wenn
Content-Type
text/plain
ist, sendet der Dienst mit der NutzdatenzeichenfolgeUserResponsePayload
mitdataType
alstext
an den Client. - Wenn
Content-Type
application/json
ist, sendet der Dienst mitdata
-Werttoken als AntwortnutzdatenkörperUserResponsePayload
mitdataType
=json
an den Client.
Format von Fehlerantworten
Wenn der Statuscode nicht „Erfolg“ lautet, wird er als Fehlerantwort betrachtet. Die Verbindung wird getrennt, wenn der Antwortstatuscode {custom_event}
nicht „Erfolg“ lautet.
Nächste Schritte
Erstellen Sie mithilfe dieser Ressourcen Ihre eigene Anwendung: