Von Azure Web PubSub unterstütztes protobuf-WebSocket-Unterprotokoll
In diesem Dokument wird das Unterprotokoll protobuf.webpubsub.azure.v1
beschrieben.
Wenn ein Client dieses Unterprotokoll verwendet, wird erwartet, dass es sich sowohl bei den ausgehenden als auch den eingehenden Dataframes um Protokollpuffernutzlasten (protobuf) handelt.
Übersicht
Das Unterprotokoll protobuf.webpubsub.azure.v1
ermöglicht es den Clients, direkt Veröffentlichen-Abonnieren-Vorgänge (Publish-Subscribe, PubSub) anstelle eines Roundtrips zum Upstreamserver durchzuführen. Die WebSocket-Verbindung mit dem Unterprotokoll protobuf.webpubsub.azure.v1
wird auch „PubSub-WebSocket-Client“ genannt.
In JavaScript können Sie beispielsweise einen PubSub-WebSocket-Client mit dem protobuf-Unterprotokoll erstellen, indem Sie Folgendes verwenden:
// PubSub WebSocket client
var pubsub = new WebSocket('wss://test.webpubsub.azure.com/client/hubs/hub1', 'protobuf.webpubsub.azure.v1');
Für einen einfachen WebSocket-Client verfügt der Server über die erforderliche Rolle für die Behandlung von Clientereignissen. Eine einfache WebSocket-Verbindung löst beim Senden von Nachrichten immer ein message
-Ereignis aus, und die Verarbeitung von Nachrichten und andere Vorgänge werden immer serverseitig ausgeführt. Mithilfe des Unterprotokolls protobuf.webpubsub.azure.v1
kann ein autorisierter Client unter Verwendung von Joinanforderungen einer Gruppe beitreten und Nachrichten mit Veröffentlichungsanforderungen direkt in einer Gruppe veröffentlichen. Der Client kann mithilfe von Ereignisanforderungen Nachrichten auch an verschiedene Upstreamereignishandler weiterleiten, um das Ereignis anzupassen, zu dem die Nachricht gehört.
Hinweis
Derzeit unterstützt der Web PubSub-Dienst nur proto3.
Berechtigungen
Ein PubSub-WebSocket-Client kann nur dann auf anderen Clients veröffentlichen, wenn er dazu autorisiert ist. Die dem Client zugewiesenen roles
bestimmen die Berechtigungen, die dem Client gewährt werden:
Role | Berechtigung |
---|---|
Nicht angegeben | Der Client kann Ereignisanforderungen senden. |
webpubsub.joinLeaveGroup |
Der Client kann einer beliebigen Gruppe beitreten/diese verlassen. |
webpubsub.sendToGroup |
Der Client kann Nachrichten in einer beliebigen Gruppe veröffentlichen. |
webpubsub.joinLeaveGroup.<group> |
Der Client kann der Gruppe <group> beitreten/diese verlassen. |
webpubsub.sendToGroup.<group> |
Der Client kann Nachrichten in der Gruppe <group> veröffentlichen. |
Der Server kann dynamisch Clientberechtigungen über REST-APIs oder Server-SDKs erteilen oder widerrufen.
Requests
Alle Anforderungsnachrichten entsprechen dem folgenden protobuf-Format:
syntax = "proto3";
import "google/protobuf/any.proto";
message UpstreamMessage {
oneof message {
SendToGroupMessage send_to_group_message = 1;
EventMessage event_message = 5;
JoinGroupMessage join_group_message = 6;
LeaveGroupMessage leave_group_message = 7;
SequenceAckMessage sequence_ack_message = 8;
PingMessage ping_message = 9;
}
message SendToGroupMessage {
string group = 1;
optional uint64 ack_id = 2;
MessageData data = 3;
}
message EventMessage {
string event = 1;
MessageData data = 2;
optional uint64 ack_id = 3;
}
message JoinGroupMessage {
string group = 1;
optional uint64 ack_id = 2;
}
message LeaveGroupMessage {
string group = 1;
optional uint64 ack_id = 2;
}
message PingMessage {
}
}
message MessageData {
oneof data {
string text_data = 1;
bytes binary_data = 2;
google.protobuf.Any protobuf_data = 3;
}
}
Gruppen beitreten
Format:
Legen Sie join_group_message.group
auf den Gruppennamen fest.
ackId
ist die Identität jeder Anforderung und sollte eindeutig sein. Der Dienst sendet eine ack-Antwortnachricht, um den Prozess über das Ergebnis der Anforderung zu informieren. Weitere Informationen finden Sie unter AckId- und Ack-Antwort.
Gruppen verlassen
Format:
Legen Sie leave_group_message.group
auf den Gruppennamen fest.
ackId
ist die Identität jeder Anforderung und sollte eindeutig sein. Der Dienst sendet eine ack-Antwortnachricht, um den Prozess über das Ergebnis der Anforderung zu informieren. Weitere Informationen finden Sie unter AckId- und Ack-Antwort.
Veröffentlichen von Nachrichten
Format:
ackId
: Die eindeutige Identität jeder Anforderung. Der Dienst sendet eine ack-Antwortnachricht, um den Prozess über das Ergebnis der Anforderung zu informieren. Weitere Informationen finden Sie unter AckId- und Ack-Antwort.dataType
: Das Datenformat, das je nachdata
inMessageData
protobuf
,text
oderbinary
sein kann. Die empfangenden Clients könnendataType
verwenden, um den Inhalt ordnungsgemäß zu verarbeiten.protobuf
: Wenn Siesend_to_group_message.data.protobuf_data
festlegen, entspricht der implizitedataType
protobuf
.protobuf_data
kann dem Nachrichtentyp Beliebig entsprechen. Alle anderen Clients erhalten protobuf-codierte Binärdateien, die vom protobuf-SDK deserialisiert werden können. Clients, die nur textbasierten Inhalt unterstützen (z. B.json.webpubsub.azure.v1
), erhalten eine Base64-codierte Binärdatei.text
: Wenn Siesend_to_group_message.data.text_data
festlegen, entspricht der implizitedataType
text
.text_data
sollte eine Zeichenfolge sein. Alle Clients mit anderen Protokollen erhalten eine UTF-8-codierte Zeichenfolge.binary
: Wenn Siesend_to_group_message.data.binary_data
festlegen, entspricht der implizitedataType
binary
.binary_data
sollte ein Bytearray sein. Alle Clients mit anderen Protokollen erhalten eine unformatierte Binärdatei ohne protobuf-Codierung. Clients, die nur textbasierten Inhalt unterstützen (z. B.json.webpubsub.azure.v1
), erhalten eine Base64-codierte Binärdatei.
Fall 1: Veröffentlichen von Textdaten
Legen Sie send_to_group_message.group
auf group
und send_to_group_message.data.text_data
auf "text data"
fest.
Der protobuf-Unterprotokollclient in der Gruppe
group
empfängt den Binärframe und kann die DownstreamMessage zum Deserialisieren verwenden.Die JSON-Unterprotokollclients in
group
empfangen:{ "type": "message", "from": "group", "group": "group", "dataType" : "text", "data" : "text data" }
Die einfachen WebSocket-Clients in
group
empfangen die Zeichenfolgetext data
.
Fall 2: Veröffentlichen von protobuf-Daten
Angenommen, Sie haben eine benutzerdefinierte Nachricht empfangen:
message MyMessage {
int32 value = 1;
}
Legen Sie send_to_group_message.group
auf group
und send_to_group_message.data.protobuf_data
auf Any.pack(MyMessage)
mit value = 1
fest.
Die protobuf-Unterprotokollclients in
group
empfangen den binären Frame und können DownstreamMessage zum Deserialisieren verwenden.Der Unterprotokollclient in
group
empfängt:{ "type": "message", "from": "group", "group": "G", "dataType" : "protobuf", "data" : "Ci90eXBlLmdvb2dsZWFwaXMuY29tL2F6dXJlLndlYnB1YnN1Yi5UZXN0TWVzc2FnZRICCAE=" // Base64-encoded bytes }
Hinweis
Bei den Daten handelt es sich um eine Base64-codierte, deserialisierbare protobuf-Binärdatei.
Sie können die folgende Protobuf-Definition verwenden und sie mit Any.unpack()
deserialisieren:
syntax = "proto3";
message MyMessage {
int32 value = 1;
}
Die einfachen WebSocket-Clients in
group
empfangen den binären Frame:# Show in hexadecimal 0A 2F 74 79 70 65 2E 67 6F 6F 67 6C 65 61 70 69 73 2E 63 6F 6D 2F 61 7A 75 72 65 2E 77 65 62 70 75 62 73 75 62 2E 54 65 73 74 4D 65 73 73 61 67 65 12 02 08 01
Fall 3: Veröffentlichen von Binärdaten
Legen Sie send_to_group_message.group
auf group
und send_to_group_message.data.binary_data
auf [1, 2, 3]
fest.
Der protobuf-Unterprotokollclient in der Gruppe
group
empfängt den Binärframe und kann die DownstreamMessage zum Deserialisieren verwenden.Der JSON-Unterprotokollclient in der Gruppe
group
empfängt Folgendes:{ "type": "message", "from": "group", "group": "group", "dataType" : "binary", "data" : "AQID", // Base64-encoded [1,2,3] }
Da der JSON-Unterprotokollclient nur textbasiertes Messaging unterstützt, ist die Binärdatei immer Base64-codiert.
Die einfachen WebSocket-Clients in
group
empfangen die binären Daten im binären Frame:# Show in hexadecimal 01 02 03
Versenden von benutzerdefinierten Ereignissen
Es gibt einen impliziten dataType
, der in Abhängigkeit von dem von Ihnen festgelegten dataType
entweder protobuf
, text
oder binary
sein kann. Die Empfängerclients können den dataType
nutzen, um den Inhalt ordnungsgemäß zu verarbeiten.
protobuf
: Wenn Sieevent_message.data.protobuf_data
festlegen, entspricht der implizitedataType
protobuf
. Der Wertprotobuf_data
kann ein beliebiger unterstützter protobuf-Typ sein. Der Ereignishandler empfängt die protobuf-codierten Binärdateien, die von jedem protobuf-SDK deserialisiert werden können.text
: Wenn Sieevent_message.data.text_data
festlegen, entspricht der implizitedataType
text
. Der Werttext_data
sollte eine Zeichenfolge sein. Der Ereignishandler empfängt eine UTF-8-codierte Zeichenfolge.binary
: Wenn Sieevent_message.data.binary_data
festlegen, entspricht der implizitedataType
binary
. Der Wertbinary_data
sollte ein Bytearray sein. Der Ereignishandler empfängt den unformatierten Binärframe.
Fall 1: Senden eines Ereignisses mit Textdaten
Setzen Sie event_message.data.text_data
auf "text data"
.
Der Upstreamereignishandler empfängt eine Anforderung ähnlich der folgenden:
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>
text data
Content-Type
für die CloudEvents-HTTP-Anforderung ist text/plain
, mit dataType
=text
.
Fall 2: Senden eines Ereignisses mit protobuf-Daten
Angenommen, Sie haben die folgende Nachricht von einer Kundin oder einem Kunden erhalten:
message MyMessage {
int32 value = 1;
}
Legen Sie event_message.data.protobuf_data
auf any.pack(MyMessage)
mit value = 1
fest.
Der Upstreamereignishandler empfängt eine Anforderung, die der folgenden ähnelt:
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>
// Just show in hexadecimal; read it as binary
0A 2F 74 79 70 65 2E 67 6F 6F 67 6C 65 61 70 69 73 2E 63 6F 6D 2F 61 7A 75 72 65 2E 77 65 62 70 75 62 73 75 62 2E 54 65 73 74 4D 65 73 73 61 67 65 12 02 08 01
Content-Type
für die CloudEvents-HTTP-Anforderung ist application/x-protobuf
, mit dataType
=protobuf
.
Die Daten sind eine gültige Protobuf-Binärdatei. Sie können proto
und any.unpack()
wie folgt für die Deserialisierung verwenden:
syntax = "proto3";
message MyMessage {
int32 value = 1;
}
Fall 3: Senden eines Ereignisses mit Binärdaten
Setzen Sie send_to_group_message.binary_data
auf [1, 2, 3]
.
Der Upstreamereignishandler empfängt eine Anforderung ähnlich der folgenden:
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>
// Just show in hexadecimal; you need to read it as binary
01 02 03
Für dataType
=binary
ist der Content-Type
für die CloudEvents-HTTP-Anforderung application/octet-stream
. Der WebSocket-Frame kann entweder im text
-Format für Textnachrichtframes oder UTF-8-codierten Binärdateien für binary
-Nachrichtframes vorliegen.
Der Dienst lehnt den Client ab, wenn die Nachricht nicht dem vorgeschriebenen Format entspricht.
Ping
Der Client kann PingMessage
an den Dienst senden, um den Web PubSub-Dienst zu aktivieren, damit die Aktivität des Clients erkannt werden kann.
Antworten
Alle Antwortnachrichten entsprechen dem folgenden protobuf-Format:
message DownstreamMessage {
oneof message {
AckMessage ack_message = 1;
DataMessage data_message = 2;
SystemMessage system_message = 3;
PongMessage pong_message = 4;
}
message AckMessage {
uint64 ack_id = 1;
bool success = 2;
optional ErrorMessage error = 3;
message ErrorMessage {
string name = 1;
string message = 2;
}
}
message DataMessage {
string from = 1;
optional string group = 2;
MessageData data = 3;
}
message SystemMessage {
oneof message {
ConnectedMessage connected_message = 1;
DisconnectedMessage disconnected_message = 2;
}
message ConnectedMessage {
string connection_id = 1;
string user_id = 2;
}
message DisconnectedMessage {
string reason = 2;
}
}
message PongMessage {
}
}
Vom Client empfangene Nachrichten können einen der folgenden Typen aufweisen: ack
, message
, system
oder pong
.
Ack-Antwort
Wenn die Anforderung ackId
enthält, gibt der Dienst eine Ack-Antwort für diese Anforderung zurück. Die Clientimplementierung sollte diesen Ack-Mechanismus verarbeiten, einschließlich:
- Warten auf die Ack-Antwort für einen
async
await
-Vorgang - Timeoutüberprüfung, wenn eine Ack-Antwort innerhalb eines bestimmten Zeitraums nicht empfangen wird
Die Clientimplementierung sollte immer zuerst überprüfen, ob der success
-Status true
oder false
entspricht. Wenn der success
-Status false
entspricht, kann der Client Fehlerdetails aus der error
-Eigenschaft lesen.
Reaktion auf die Nachricht
Clients können Nachrichten empfangen, die von einer Gruppe veröffentlicht wurden, der der Client beigetreten ist. Alternativ können sie Nachrichten von der Serververwaltungsrolle empfangen, wenn der Server Nachrichten an einen bestimmten Client oder bestimmte Benutzer*innen sendet.
In den folgenden Szenarios erhalten Sie immer eine DownstreamMessage.DataMessage
-Nachricht:
- Wenn die Nachricht von einer Gruppe stammt, wird für
from
group
angegeben. Wenn die Nachricht vom Server stammt, wird fürfrom
server
angegeben. - Wenn die Nachricht von einer Gruppe stammt, ist
group
der Gruppenname.
Der dataType
von Sender*innen verursacht, dass eine der folgenden Nachrichten gesendet wird:
- Wenn der
dataType
text
lautet, verwenden Siemessage_response_message.data.text_data
. - Wenn der
dataType
binary
lautet, verwenden Siemessage_response_message.data.binary_data
. - Wenn der
dataType
protobuf
lautet, verwenden Siemessage_response_message.data.protobuf_data
. - Wenn der
dataType
json
lautet, verwenden Siemessage_response_message.data.text_data
, und der Inhalt ist eine serialisierte JSON-Zeichenfolge.
Systemantwort
Der Web PubSub-Dienst kann auch systembezogene Antworten an den Client senden.
Verbunden
Wenn der Client eine Verbindung mit dem Dienst herstellt, erhalten Sie eine DownstreamMessage.SystemMessage.ConnectedMessage
-Nachricht.
Getrennt
Wenn der Server die Verbindung schließt oder der Dienst den Client ablehnt, erhalten Sie eine DownstreamMessage.SystemMessage.DisconnectedMessage
-Nachricht.
Pong-Antwort
Der Web PubSub-Dienst sendet PongMessage
an den Client, wenn er PingMessage
vom Client empfängt.
Nächste Schritte
Erstellen Sie mithilfe dieser Ressourcen Ihre eigene Anwendung: