Subprotokol WebSocket protobuf yang didukung Azure Web PubSub
Dokumen ini menjelaskan subprotokol protobuf.webpubsub.azure.v1
.
Ketika klien menggunakan subprotokol ini, baik frame data keluar dan masuk diharapkan menjadi payload buffer protokol (protobuf).
Gambaran Umum
Subprotokol protobuf.webpubsub.azure.v1
​​memberdayakan klien untuk melakukan penerbitan/berlangganan (PubSub) secara langsung alih-alih bolak-balik ke server upstream. Sambungan WebSocket dengan subprotokol protobuf.webpubsub.azure.v1
disebut klien WebSocket PubSub.
Misalnya, di JavaScript, Anda dapat membuat klien WebSocket PubSub dengan subprotokol protobuf dengan menggunakan:
// PubSub WebSocket client
var pubsub = new WebSocket('wss://test.webpubsub.azure.com/client/hubs/hub1', 'protobuf.webpubsub.azure.v1');
Untuk klien WebSocket sederhana, server harus memiliki peran untuk menangani peristiwa dari klien. Koneksi WebSocket sederhana selalu memicu acara message
saat koneksi mengirim pesan, dan selalu mengandalkan kemampuan server untuk memproses pesan dan melakukan operasi lain. Dengan bantuan subprotokol protobuf.webpubsub.azure.v1
, klien yang berwenang dapat bergabung dengan grup menggunakan permintaan bergabung dan menerbitkan pesan ke grup menggunakan permintaan penerbitan secara langsung. Klien juga dapat merutekan pesan ke penanganan aktivitas upstream yang berbeda dengan menggunakan permintaan pesan untuk menyesuaikan peristiwa tempat pesan tersebut berada.
Catatan
Saat ini, layanan Web PubSub hanya mendukung proto3.
Izin
Klien WebSocket PubSub hanya dapat menerbitkan ke klien lain saat diotorisasi. Yang roles
ditetapkan ke klien menentukan izin yang diberikan kepada klien:
Peran | Izin |
---|---|
Tidak ditentukan | Klien dapat mengirim permintaan peristiwa. |
webpubsub.joinLeaveGroup |
Klien dapat bergabung/meninggalkan grup mana pun. |
webpubsub.sendToGroup |
Klien dapat menerbitkan pesan ke grup mana pun. |
webpubsub.joinLeaveGroup.<group> |
Klien dapat bergabung/meninggalkan grup <group> . |
webpubsub.sendToGroup.<group> |
Klien dapat menerbitkan pesan ke grup <group> . |
Server dapat secara dinamis memberikan atau mencabut izin klien melalui REST API atau SDK server.
Permintaan
Semua pesan permintaan menggunakan format protobuf berikut:
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;
}
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 MessageData {
oneof data {
string text_data = 1;
bytes binary_data = 2;
google.protobuf.Any protobuf_data = 3;
}
}
Bergabung dengan grup
Format:
Atur join_group_message.group
ke nama grup.
ackId
adalah identitas dari setiap permintaan dan harus unik. Layanan mengirimkan pesan respons ack untuk memberi tahu hasil proses permintaan. Detail lebih lanjut dapat ditemukan di AckId dan Ack Response
Meninggalkan grup
Format:
Atur leave_group_message.group
ke nama grup.
ackId
adalah identitas dari setiap permintaan dan harus unik. Layanan mengirimkan pesan respons ack untuk memberi tahu hasil proses permintaan. Detail lebih lanjut dapat ditemukan di AckId dan Ack Response
Menerbitkan pesan
Format:
ackId
: Identitas unik dari setiap permintaan. Layanan mengirimkan pesan respons ack untuk memberi tahu hasil proses permintaan. Detail lebih lanjut dapat ditemukan di AckId dan Ack ResponsedataType
: Format data, yang dapat berupaprotobuf
,text
, ataubinary
tergantung padadata
diMessageData
. Klien penerima dapat menggunakandataType
untuk memproses konten dengan benar.protobuf
: Ketika Anda mengatursend_to_group_message.data.protobuf_data
, implisitnyadataType
adalahprotobuf
.protobuf_data
Bisa dari jenis pesan apa pun. Semua klien lain menerima biner yang dienkodekan protobuf, yang dapat dideserialisasi oleh SDK protobuf. Klien yang hanya mendukung konten berbasis teks (misalnya,json.webpubsub.azure.v1
) menerima biner yang dikodekan Base64.text
: Ketika Anda mengatursend_to_group_message.data.text_data
, implisitnyadataType
adalahtext
.text_data
Harus berupa string. Semua klien dengan protokol lain menerima string yang dikodekan UTF-8.binary
: Ketika Anda mengatursend_to_group_message.data.binary_data
, implisitnyadataType
adalahbinary
.binary_data
Harus berupa array byte. Semua klien dengan protokol lain menerima biner mentah tanpa pengkodean protobuf. Klien yang hanya mendukung konten berbasis teks (misalnya,json.webpubsub.azure.v1
) menerima biner yang dikodekan Base64.
Kasus 1: Menerbitkan data teks
Atur send_to_group_message.group
ke group
, dan atur send_to_group_message.data.text_data
ke "text data"
.
Klien subprotokol protobuf dalam grup
group
menerima bingkai biner dan dapat menggunakan DownstreamMessage untuk mendeserialisasi.Klien subprotokul JSON dalam
group
menerima:{ "type": "message", "from": "group", "group": "group", "dataType" : "text", "data" : "text data" }
Klien WebSocket sederhana dalam
group
stringtext data
penerimaan .
Kasus 2: Menerbitkan data protobuf
Mari kita asumsikan bahwa Anda memiliki pesan kustom:
message MyMessage {
int32 value = 1;
}
Atur send_to_group_message.group
ke group
dan send_to_group_message.data.protobuf_data
ke Any.pack(MyMessage)
dengan value = 1
.
Klien subprotokol protobuf dalam
group
menerima bingkai biner dan dapat menggunakan DownstreamMessage untuk mendeserialisasinya.Klien subprotokl dalam
group
menerima:{ "type": "message", "from": "group", "group": "G", "dataType" : "protobuf", "data" : "Ci90eXBlLmdvb2dsZWFwaXMuY29tL2F6dXJlLndlYnB1YnN1Yi5UZXN0TWVzc2FnZRICCAE=" // Base64-encoded bytes }
Catatan
Data adalah biner protobuf yang dikodekan base64, yang dapat dideserialisasi.
Anda dapat menggunakan definisi protobuf berikut dan menggunakan Any.unpack()
untuk mendeserialisasinya:
syntax = "proto3";
message MyMessage {
int32 value = 1;
}
Klien WebSocket sederhana dalam
group
menerima bingkai biner:# 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
Kasus 3: Menerbitkan data biner
Atur send_to_group_message.group
ke group
, dan atur send_to_group_message.data.binary_data
ke [1, 2, 3]
.
Klien subprotokol protobuf dalam grup
group
menerima bingkai biner dan dapat menggunakan DownstreamMessage untuk mendeserialisasi.Klien subprotokol JSON dalam grup
group
menerima:{ "type": "message", "from": "group", "group": "group", "dataType" : "binary", "data" : "AQID", // Base64-encoded [1,2,3] }
Karena klien subprotocol JSON hanya mendukung pesan berbasis teks, biner selalu dikodekan Base64.
Klien WebSocket sederhana dalam
group
menerima data biner dalam bingkai biner:# Show in hexadecimal 01 02 03
Kirim peristiwa kustom
Ada dataType
implisit, yang bisa berupa protobuf
, text
, atau binary
, bergantung pada dataType
yang Anda tetapkan. Klien penerima dapat menggunakan dataType
untuk menangani konten dengan benar.
protobuf
: Ketika Anda mengaturevent_message.data.protobuf_data
, implisitnyadataType
adalahprotobuf
. Nilainyaprotobuf_data
dapat berupa jenis protobuf yang didukung. Penanganan aktivitas menerima biner yang dienkodekan protobuf, yang dapat dideserialisasi oleh SDK protobuf apapun.text
: Ketika Anda mengaturevent_message.data.text_data
, implisitnyadataType
adalahtext
. Nilaitext_data
harus berupa string. Penanganan aktivitas menerima string yang dikodekan UTF-8.binary
: Ketika Anda mengaturevent_message.data.binary_data
, implisitnyadataType
adalahbinary
. Nilaibinary_data
harus berupa array byte. Penanganan aktivitas menerima bingkai biner mentah.
Kasus 1: Mengirim peristiwa dengan data teks
Atur event_message.data.text_data
ke "text data"
.
Penanganan aktivitas upstram menerima permintaan yang mirip dengan:
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
untuk permintaan HTTP CloudEvents adalah text/plain
, di mana=dataType
text
.
Kasus 2: Mengirim peristiwa dengan data protobuf
Asumsikan bahwa Anda telah menerima pesan pelanggan berikut:
message MyMessage {
int32 value = 1;
}
Atur event_message.data.protobuf_data
ke any.pack(MyMessage)
dengan value = 1
Penanganan aktivitas upstram menerima permintaan yang mirip dengan:
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
untuk permintaan HTTP CloudEvents adalah application/x-protobuf
, di mana=dataType
protobuf
.
Data adalah biner protobuf yang valid. Anda dapat menggunakan proto
dan any.unpack()
berikut untuk deserialisasi:
syntax = "proto3";
message MyMessage {
int32 value = 1;
}
Kasus 3: Mengirim peristiwa dengan data biner
Atur send_to_group_message.binary_data
ke [1, 2, 3]
.
Penanganan aktivitas upstram menerima permintaan yang mirip dengan:
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
Untuk dataType
=binary
, Content-Type
untuk permintaan HTTP CloudEvents adalah application/octet-stream
. Bingkai WebSocket dapat berupa format text
untuk bingkai pesan teks atau biner yang dikodekan UTF-8 untuk bingkai pesan binary
.
Layanan menolak klien jika pesan tidak sesuai dengan format yang ditentukan.
Respons
Semua pesan respons menggunakan format protobuf berikut:
message DownstreamMessage {
oneof message {
AckMessage ack_message = 1;
DataMessage data_message = 2;
SystemMessage system_message = 3;
}
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;
}
}
}
Pesan yang diterima oleh klien dapat berupa salah satu dari beberapa jenis: ack
, message
, atau system
.
Respons ack
Jika permintaan berisi ackId
, layanan akan mengembalikan respons ack untuk permintaan ini. Implementasi klien harus menangani mekanisme ack ini, termasuk:
- Menunggu respons ack untuk
async
await
operasi. - Melakukan pemeriksaan timeout ketika respons ack tidak diterima selama periode tertentu.
Implementasi klien harus selalu memeriksa terlebih dahulu untuk melihat apakah status success
adalah true
atau false
. Ketika status success
adalah false
, klien dapat membaca dari properti error
untuk melihat rincian kesalahan.
Respons pesan
Klien dapat menerima pesan yang dipublikasikan dari grup di mana klien tergabung. Atau mereka dapat menerima pesan dari peran manajemen server ketika server mengirim pesan ke klien tertentu atau pengguna tertentu.
Anda akan selalu mendapatkan pesan DownstreamMessage.DataMessage
dalam skenario berikut:
- Ketika pesan berasal dari grup,
from
adalahgroup
. Ketika pesan dari server,from
adalahserver
. - Ketika pesan berasal dari grup,
group
adalah nama grup.
dataType
pengirim akan menyebabkan salah satu pesan berikut dikirim:
- Jika
dataType
adalahtext
, gunakanmessage_response_message.data.text_data
. - Jika
dataType
adalahbinary
, gunakanmessage_response_message.data.binary_data
. - Jika
dataType
adalahprotobuf
, gunakanmessage_response_message.data.protobuf_data
. - Jika
dataType
adalahjson
, gunakanmessage_response_message.data.text_data
, dan kontennya adalah string JSON berseri.
Respons sistem
Layanan Web PubSub juga dapat mengirim respons terkait sistem ke klien.
Tersambung
Ketika klien terhubung ke layanan, Anda akan menerima pesan DownstreamMessage.SystemMessage.ConnectedMessage
.
Terputus
Ketika server menutup koneksi atau layanan menolak klien, Anda akan menerima pesan DownstreamMessage.SystemMessage.DisconnectedMessage
.
Langkah berikutnya
Gunakan sumber daya ini untuk mulai membangun aplikasi Anda sendiri: