Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Questo documento descrive il sottoprotocolo protobuf.webpubsub.azure.v1.
Quando un client usa questo sottoprotocolo, è previsto che i frame di dati in uscita e in ingresso siano payload di buffer di protocollo (protobuf).
Panoramica
Subprotocol protobuf.webpubsub.azure.v1 consente al client di eseguire direttamente una sottoscrizione di pubblicazione (PubSub) anziché eseguire un round trip al server upstream. La connessione WebSocket con il protobuf.webpubsub.azure.v1 sottoprotocolo è denominata client WebSocket PubSocket.
In JavaScript, ad esempio, è possibile creare un client WebSocket PubSub con il sottoprotocolo protobuf usando:
// PubSub WebSocket client
var pubsub = new WebSocket('wss://test.webpubsub.azure.com/client/hubs/hub1', 'protobuf.webpubsub.azure.v1');
Per un semplice client WebSocket, il server ha il ruolo necessario per la gestione degli eventi dai client. Una semplice connessione WebSocket attiva sempre un message evento quando invia messaggi e si basa sempre sul lato server per elaborare i messaggi ed eseguire altre operazioni. Con l'aiuto del protobuf.webpubsub.azure.v1 sottoprotocolo, un client autorizzato può partecipare a un gruppo usando richieste di join e pubblicare messaggi in un gruppo usando direttamente le richieste di pubblicazione. Il client può anche instradare i messaggi a vari gestori eventi upstream usando richieste di eventi per personalizzare l'evento a cui appartiene il messaggio.
Nota
Attualmente, il servizio Web PubSub supporta solo proto3.
Autorizzazioni
Un client WebSocket PubSocket può pubblicare solo in altri client quando è autorizzato. L'oggetto roles assegnato al client determina le autorizzazioni concesse al client:
| Ruolo | Autorizzazione |
|---|---|
| Non specificato | Il client può inviare richieste di eventi. |
webpubsub.joinLeaveGroup |
Il client può unirsi o abbandonare qualsiasi gruppo. |
webpubsub.sendToGroup |
Il client può pubblicare messaggi in qualsiasi gruppo. |
webpubsub.joinLeaveGroup.<group> |
Il client può partecipare/lasciare il gruppo <group>. |
webpubsub.sendToGroup.<group> |
Il client può pubblicare messaggi nel gruppo <group>. |
webpubsub.joinLeaveGroups.<pattern> |
Il client può partecipare/lasciare qualsiasi gruppo il cui nome corrisponde <pattern> (vedere Modelli di ruolo del gruppo con caratteri jolly). |
webpubsub.sendToGroups.<pattern> |
Il client può pubblicare messaggi in qualsiasi gruppo i cui nomi corrispondono <pattern> (vedere Modelli di ruolo del gruppo con caratteri jolly). |
Il server può concedere o revocare in modo dinamico le autorizzazioni client tramite API REST o SDK del server.
Nota
I ruoli con caratteri jolly (ad esempio , webpubsub.sendToGroups.<pattern>) non sono ancora supportati nelle API REST o negli SDK del server durante il runtime.
Richieste
Tutti i messaggi di richiesta rispettano il seguente formato protobuf:
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;
StreamDataMessage stream_data_message = 13;
StreamEndMessage stream_end_message = 14;
}
message SendToGroupMessage {
string group = 1;
optional uint64 ack_id = 2;
MessageData data = 3;
optional bool no_echo = 4;
StreamStartInfo stream = 7;
}
message StreamStartInfo {
string stream_id = 1;
optional uint32 idle_timeout_ms = 2;
}
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 SequenceAckMessage {
uint64 sequence_id = 1;
}
message PingMessage {
}
message StreamDataMessage {
string stream_id = 1;
optional uint64 stream_sequence_id = 2;
MessageData data = 3;
}
message StreamEndMessage {
string stream_id = 1;
optional StreamEndError error = 2;
message StreamEndError {
optional string message = 1;
optional string user_error_code = 2;
}
}
}
message MessageData {
oneof data {
string text_data = 1;
bytes binary_data = 2;
google.protobuf.Any protobuf_data = 3;
}
}
Partecipare ai gruppi
Formato:
Impostare join_group_message.group sul nome del gruppo.
-
ackIdè l'identità di ogni richiesta e deve essere univoca. Il servizio invia un messaggio di risposta ack per notificare il risultato del processo della richiesta. Altri dettagli sono disponibili in AckId e Ack Response
Lasciare i gruppi
Formato:
Impostare leave_group_message.group sul nome del gruppo.
-
ackIdè l'identità di ogni richiesta e deve essere univoca. Il servizio invia un messaggio di risposta ack per notificare il risultato del processo della richiesta. Altri dettagli sono disponibili in AckId e Ack Response
Pubblicare messaggi
Formato:
ackId: identità univoca di ogni richiesta. Il servizio invia un messaggio di risposta ack per notificare il risultato del processo della richiesta. Altri dettagli sono disponibili in AckId e Ack ResponsedataType: formato di dati, che può essereprotobuf,textobinarya seconda didatainMessageData. I client riceventi possono usaredataTypeper elaborare correttamente il contenuto.protobuf: quando si impostasend_to_group_message.data.protobuf_data, l'implicitodataTypeèprotobuf.protobuf_datapuò essere di qualsiasi tipo di messaggio. Tutti gli altri client ricevono un file binario con codifica protobuf, che può essere deserializzato dall'SDK protobuf. I client che supportano solo il contenuto basato su testo ,ad esempio ,json.webpubsub.azure.v1ricevono un file binario con codifica Base64.text: quando si impostasend_to_group_message.data.text_data, l'implicitodataTypeètext.text_datadeve essere una stringa. Tutti i client con altri protocolli ricevono una stringa con codifica UTF-8.binary: quando si impostasend_to_group_message.data.binary_data, l'implicitodataTypeèbinary.binary_datadeve essere una matrice di byte. Tutti i client con altri protocolli ricevono un file binario non elaborato senza codifica protobuf. I client che supportano solo il contenuto basato su testo ,ad esempio ,json.webpubsub.azure.v1ricevono un file binario con codifica Base64.
Caso 1: Pubblicare dati di testo
Impostare send_to_group_message.group su groupe impostare su send_to_group_message.data.text_data"text data".
Il client subprotocol protobuf in gruppo
groupriceve il frame binario e può usare DownstreamMessage per deserializzarlo.I client del sottoprotocolo JSON in
groupricevono:{ "type": "message", "from": "group", "group": "group", "dataType" : "text", "data" : "text data" }I semplici client WebSocket nella
groupstringatext datadi ricezione.
Caso 2: Pubblicare dati protobuf
Si supponga di avere un messaggio personalizzato:
message MyMessage {
int32 value = 1;
}
Impostare su send_to_group_message.groupgroup e send_to_group_message.data.protobuf_data su Any.pack(MyMessage) con value = 1.
I client protobuf subprotocol in
groupricevono il frame binario e possono usare DownstreamMessage per deserializzarlo.Il client subprotocol in
groupriceve:{ "type": "message", "from": "group", "group": "G", "dataType" : "protobuf", "data" : "Ci90eXBlLmdvb2dsZWFwaXMuY29tL2F6dXJlLndlYnB1YnN1Yi5UZXN0TWVzc2FnZRICCAE=" // Base64-encoded bytes }Nota
I dati sono un file binario protobuf con codifica Base64 deserializeable.
È possibile usare la definizione protobuf seguente e usarla Any.unpack() per deserializzarla:
syntax = "proto3";
message MyMessage {
int32 value = 1;
}
I semplici client WebSocket in
groupricevono il frame binario:# 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
Caso 3: Pubblicare dati binari
Impostare send_to_group_message.group su groupe impostare su send_to_group_message.data.binary_data[1, 2, 3].
Il client subprotocol protobuf in gruppo
groupriceve il frame binario e può usare DownstreamMessage per deserializzarlo.Il client del sottoprotocolo JSON in gruppo
groupriceve:{ "type": "message", "from": "group", "group": "group", "dataType" : "binary", "data" : "AQID", // Base64-encoded [1,2,3] }Poiché il client di sottoprotocolo JSON supporta solo la messaggistica basata su testo, il file binario è sempre con codifica Base64.
I semplici client WebSocket in
groupricevono i dati binari nel frame binario:# Show in hexadecimal 01 02 03
Inizia a trasmettere messaggi
Per avviare un flusso di gruppo, imposta send_to_group_message.group il gruppo target e send_to_group_message.stream imposta il StreamStartInfo messaggio. Una richiesta di avvio di flusso non viene impostata send_to_group_message.data né send_to_group_message.ack_id.
-
send_to_group_message.stream.stream_idè l'identificatore del flusso logico. Deve essere una stringa non vuota e deve essere unica tra i flussi attivi sulla stessa connessione client. Si consiglia alle librerie client di generare un valore globalmente unico, come un GUID o un UUID. -
send_to_group_message.stream.idle_timeout_msè facoltativo. Se specificato, deve essere maggiore di0. Se omesso, il valore predefinito del servizio è300000millisecondo. Il valore è un timeout inattivo, non una durata totale del flusso di streaming. Invia dati del stream, invia un keep live, oppure termina lo stream prima che scada questo timeout, quando l'applicazione deve mantenere lo stream aperto. -
send_to_group_message.no_echoè facoltativo. Se impostato su true, i messaggi di stream non vengono richiamati alla stessa connessione. Se non è impostato, il valore predefinito è false.
Quando lo stream viene accettato, il client riceve una risposta di ack dello stream impostata expected_sequence_id a 1.
Invia dati in streaming
Per inviare dati di flusso, imposta stream_data_message.stream_id, stream_data_message.stream_sequence_id, e stream_data_message.data.
-
stream_data_message.stream_ididentifica un flusso attivo sulla stessa connessione client. -
stream_data_message.stream_sequence_idè un numero uint64 positivo. Il primo frammento di dati in un flusso usa1, e ogni frammento di dato successivo per lo stessostream_idaumenta esattamente1di . -
stream_data_message.datautilizza le stesseMessageDataregole di codifica di pubblicazione dei messaggi.
Per mantenere un flusso attivo senza consegnare dati agli abbonati, invia stream_data_message solo stream_id impostato.
Fine dei messaggi in streaming
Per terminare un stream, imposta stream_end_message.stream_id.
Per concludere un flusso con un errore definito dall'applicazione, si imposta stream_end_message.error.
-
stream_end_message.error.messageè un messaggio di errore opzionale leggibile dagli umani. -
stream_end_message.error.user_error_codeè un codice di errore opzionale definito dall'applicazione.
Quando lo stream è chiuso, l'editore riceve una risposta di stream closed.
Inviare eventi personalizzati
È presente un oggetto implicito dataType, che può essere protobuf, texto binary, a seconda dell'oggetto dataType impostato. I client ricevitori possono usare dataType per gestire correttamente il contenuto.
protobuf: quando si impostaevent_message.data.protobuf_data, l'implicitodataTypeèprotobuf. Ilprotobuf_datavalore può essere qualsiasi tipo protobuf supportato. Il gestore eventi riceve il file binario con codifica protobuf, che può essere deserializzato da qualsiasi SDK protobuf.text: quando si impostaevent_message.data.text_data, l'implicitodataTypeètext. Iltext_datavalore deve essere una stringa. Il gestore eventi riceve una stringa con codifica UTF-8.binary: quando si impostaevent_message.data.binary_data, l'implicitodataTypeèbinary. Ilbinary_datavalore deve essere una matrice di byte. Il gestore eventi riceve il frame binario non elaborato.
Caso 1: Inviare un evento con dati di testo
Impostare event_message.data.text_data su "text data".
Il gestore eventi upstream riceve una richiesta simile a:
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
Per Content-Type la richiesta HTTP CloudEvents è text/plain, dovedataType=text .
Caso 2: Inviare un evento con dati protobuf
Si supponga di aver ricevuto il seguente messaggio del cliente:
message MyMessage {
int32 value = 1;
}
Impostare event_message.data.protobuf_data su any.pack(MyMessage) con value = 1
Il gestore eventi upstream riceve una richiesta simile a:
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
Per Content-Type la richiesta HTTP CloudEvents è application/x-protobuf, dovedataType=protobuf .
I dati sono un file binario protobuf valido. È possibile usare quanto segue proto e any.unpack() per deserializzarlo:
syntax = "proto3";
message MyMessage {
int32 value = 1;
}
Caso 3: Inviare un evento con dati binari
Impostare send_to_group_message.binary_data su [1, 2, 3].
Il gestore eventi upstream riceve una richiesta simile a:
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
Per dataType=binary, per Content-Type la richiesta HTTP CloudEvents è application/octet-stream. Il frame WebSocket può essere in text formato per frame di messaggi di testo o file binari con codifica UTF-8 per binary i fotogrammi di messaggio.
Il servizio rifiuta il client se il messaggio non corrisponde al formato specificato.
Ping
Il client può inviare un oggetto PingMessage al servizio per consentire al servizio Web PubSub di rilevare la durata del client.
Risposte
Tutti i messaggi di risposta rispettano il seguente formato protobuf:
message DownstreamMessage {
oneof message {
AckMessage ack_message = 1;
DataMessage data_message = 2;
SystemMessage system_message = 3;
PongMessage pong_message = 4;
StreamAckMessage stream_ack_message = 6;
StreamNackMessage stream_nack_message = 7;
StreamClosedMessage stream_closed_message = 8;
}
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;
StreamInfo stream = 6;
}
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 {
}
message StreamAckMessage {
string stream_id = 1;
uint64 expected_sequence_id = 2;
}
message StreamNackMessage {
string stream_id = 1;
string name = 2;
string message = 3;
uint64 expected_sequence_id = 4;
}
message StreamClosedMessage {
string stream_id = 1;
optional StreamClosedError error = 2;
message StreamClosedError {
string name = 1;
string message = 2;
}
}
}
message StreamInfo {
string stream_id = 1;
uint64 stream_sequence_id = 2;
optional bool end_of_stream = 3;
optional StreamError error = 4;
message StreamError {
string name = 1;
string message = 2;
string user_error_code = 3;
}
}
I messaggi ricevuti dal client possono essere ack, message, system, pong, streamAck, streamNack, o streamClosed.
Risposta Ack
Se la richiesta contiene ackId, il servizio restituisce una risposta ack per questa richiesta. L'implementazione client deve gestire questo meccanismo ack, tra cui:
- In attesa della risposta ack per un'operazione
asyncawait. - Verifica del timeout quando la risposta ack non viene ricevuta durante un determinato periodo.
L'implementazione del client deve sempre controllare prima di tutto se lo success stato è true o false. Quando lo success stato è false, il client può leggere dalla proprietà per i dettagli dell'errore error .
Risposta al messaggio
I client possono ricevere messaggi pubblicati da un gruppo aggiunto al client. Oppure possono ricevere messaggi dal ruolo di gestione del server quando il server invia messaggi a un client specifico o a un utente specifico.
Verrà sempre visualizzato un DownstreamMessage.DataMessage messaggio negli scenari seguenti:
- Quando il messaggio proviene da un gruppo,
fromègroup. Quando il messaggio proviene dal server,fromèserver. - Quando il messaggio proviene da un gruppo,
groupè il nome del gruppo.
Il mittente causerà l'invio dataType di uno dei messaggi seguenti:
- Se
dataTypeètext, usaremessage_response_message.data.text_data. - Se
dataTypeèbinary, usaremessage_response_message.data.binary_data. - Se
dataTypeèprotobuf, usaremessage_response_message.data.protobuf_data. - Se
dataTypeèjson, usaremessage_response_message.data.text_datae il contenuto è una stringa JSON serializzata.
Quando un messaggio di gruppo appartiene a un flusso, DownstreamMessage.DataMessage.stream viene impostato.
-
stream.stream_idè l'identificatore logico del flusso. -
stream.stream_sequence_idè il numero di sequenza del messaggio nel flusso. -
stream.end_of_streamè facoltativo. Quando impostato sutrue, il messaggio è il messaggio terminale del flusso. -
stream.errorè opzionale ed è presente solo quando il flusso termina con un errore.user_error_codeè presente solo perUserError.
Risposta al flusso
Il servizio invia DownstreamMessage.StreamAckMessage per confermare i dati di flusso accettati e per segnalare il prossimo ID della sequenza di flusso che si aspetta.
-
stream_idè l'identificatore logico del flusso. -
expected_sequence_idè il prossimo ID di sequenza di flusso che il servizio si aspetta.
Risposta al nack del corso d'acqua
Il servizio invia DownstreamMessage.StreamNackMessage un errore di flusso riprovabile.
-
stream_idè l'identificatore logico del flusso. -
expected_sequence_idè il prossimo ID di sequenza di flusso che il servizio si aspetta. -
namepuò essereInvalidSequenceIdoTransientError. -
messagecontiene dettagli sull'errore.
Risposta chiusa del flusso
Il servizio viene inviato DownstreamMessage.StreamClosedMessage quando il flusso lato editore è chiuso.
-
stream_idè l'identificatore logico del flusso. -
errorviene omesso quando il flusso è chiuso normalmente. -
error.namepuò essereStreamNotFound,Forbidden,BadRequest,InternalServerError, oIdleTimeout. -
error.messagecontiene dettagli sull'errore.
Risposta di sistema
Il servizio Web PubSub può anche inviare risposte correlate al sistema al client.
Connesso
Quando il client si connette al servizio, viene visualizzato un DownstreamMessage.SystemMessage.ConnectedMessage messaggio.
Disconnesso
Quando il server chiude la connessione o il servizio rifiuta il client, viene visualizzato un DownstreamMessage.SystemMessage.DisconnectedMessage messaggio.
Risposta pong
Il servizio Web PubSub invia un oggetto PongMessage al client quando riceve un PingMessage oggetto dal client.
Passaggi successivi
Usare queste risorse per iniziare a compilare un'applicazione personalizzata: