Azure Web PubSub でサポートされる Protobuf WebSocket サブプロトコル
このドキュメントでは、サブプロトコル protobuf.webpubsub.azure.v1
について説明します。
クライアントがこのサブプロトコルを使用している場合、送信データ フレームと受信データ フレームの両方がプロトコル バッファー (protobuf) ペイロードである必要があります。
概要
サブプロトコル protobuf.webpubsub.azure.v1
を使用すると、クライアントでは、上流サーバーへのラウンド トリップではなく、直接の発行またはサブスクライブ (PubSub) を行うことができます。 protobuf.webpubsub.azure.v1
サブプロトコルを持つ WebSocket 接続を、PubSub WebSocket クライアントと呼びます。
たとえば、JavaScript では、次のコードを使用して、protobuf サブプロトコルを使用する PubSub WebSocket クライアントを作成できます。
// PubSub WebSocket client
var pubsub = new WebSocket('wss://test.webpubsub.azure.com/client/hubs/hub1', 'protobuf.webpubsub.azure.v1');
シンプルな WebSocket クライアントの場合、サーバーにはクライアントからイベントを処理するために必要なロールがあります。 シンプルな WebSocket 接続では、メッセージを送信するときには必ず message
イベントをトリガーします。また、常にサーバー側に依存して、メッセージを処理したり他の操作を行ったりします。 protobuf.webpubsub.azure.v1
サブプロトコルを使用することで、許可されているクライアントは、参加要求を使用してグループに参加し、発行要求を直接使用してグループにメッセージを発行できます。 クライアントは、イベント要求を使用して、メッセージが属するイベントをカスタマイズすることで、さまざまな上流イベント ハンドラにメッセージをルーティングすることもできます。
Note
現在、Web PubSub サービスは proto3 のみをサポートしています。
アクセス許可
PubSub WebSocket クライアントは、許可されている場合にのみ他のクライアントに発行できます。 クライアントに割り当てられた roles
によって、そのクライアントに付与されるアクセス許可が決まります。
役割 | アクセス許可 |
---|---|
指定なし | クライアントは、イベント要求を送信できます。 |
webpubsub.joinLeaveGroup |
クライアントは、どのグループについても、参加と脱退が可能です。 |
webpubsub.sendToGroup |
クライアントは、どのグループにもメッセージを発行できます。 |
webpubsub.joinLeaveGroup.<group> |
クライアントはグループ <group> について、参加と脱退が可能です。 |
webpubsub.sendToGroup.<group> |
クライアントはグループ <group> にメッセージを発行できます。 |
REST API またはサーバー SDK を使用して、サーバーからクライアントのアクセス許可を動的に付与または取り消すことができます。
要求
すべての要求メッセージは、次の 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;
}
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;
}
}
グループに参加する
形式:
join_group_message.group
をグループ名に設定します。
ackId
は各要求の ID で、一意である必要があります。 要求の処理結果を通知するために、サービスから確認応答メッセージが送信されます。 詳細については、AckId と確認応答に関するページを参照してください。
グループを脱退する
形式:
leave_group_message.group
をグループ名に設定します。
ackId
は各要求の ID で、一意である必要があります。 要求の処理結果を通知するために、サービスから確認応答メッセージが送信されます。 詳細については、AckId と確認応答に関するページを参照してください。
メッセージを発行する
形式:
ackId
: 各要求の一意の ID。 要求の処理結果を通知するために、サービスから確認応答メッセージが送信されます。 詳細については、AckId と確認応答に関するページを参照してください。dataType
:MessageData
のdata
に応じて、protobuf
、text
、またはbinary
であるデータ形式。 受信側のクライアントは、dataType
を使用してコンテンツを正しく処理できます。protobuf
:send_to_group_message.data.protobuf_data
を設定した場合、暗黙的なdataType
はprotobuf
です。protobuf_data
は、任意のメッセージ型にすることができます。 他のすべてのクライアントは protobuf でエンコードされたバイナリを受け取り、protobuf SDK によって逆シリアル化できます。 テキスト ベースのコンテンツのみをサポートするクライアント (例:json.webpubsub.azure.v1
) は、Base64 でエンコードされたバイナリを受け取ります。text
:send_to_group_message.data.text_data
を設定した場合、暗黙的なdataType
はtext
です。text_data
は文字列である必要があります。 他のプロトコルを使用するすべてのクライアントは、UTF-8 でエンコードされた文字列を受け取ります。binary
:send_to_group_message.data.binary_data
を設定した場合、暗黙的なdataType
はbinary
です。binary_data
はバイト配列である必要があります。 他のプロトコルを使用するすべてのクライアントは、protobuf エンコードされていない未加工のバイナリを受け取ります。 テキスト ベースのコンテンツのみをサポートするクライアント (例:json.webpubsub.azure.v1
) は、Base64 でエンコードされたバイナリを受け取ります。
ケース 1: テキスト データを発行する
send_to_group_message.group
を group
に設定し、send_to_group_message.data.text_data
を "text data"
に設定します。
グループ
group
内の protobuf サブプロトコル クライアントはバイナリ フレームを受け取り、DownstreamMessage を使用して逆シリアル化できます。group
の JSON サブプロトコル クライアントは、以下を受け取ります。{ "type": "message", "from": "group", "group": "group", "dataType" : "text", "data" : "text data" }
group
のシンプル WebSocket クライアントは、文字列text data
を受け取ります。
ケース 2: protobuf データを発行する
カスタム メッセージがある場合を想定します。
message MyMessage {
int32 value = 1;
}
send_to_group_message.group
を group
に、send_to_group_message.data.protobuf_data
を Any.pack(MyMessage)
に設定し、value = 1
を指定します。
group
内の protobuf サブプロトコル クライアントはバイナリ フレームを受け取り、DownstreamMessage を使用して逆シリアル化できます。group
内のサブプロトコル クライアントは以下を受け取ります。{ "type": "message", "from": "group", "group": "G", "dataType" : "protobuf", "data" : "Ci90eXBlLmdvb2dsZWFwaXMuY29tL2F6dXJlLndlYnB1YnN1Yi5UZXN0TWVzc2FnZRICCAE=" // Base64-encoded bytes }
Note
データは、Base64 でエンコードされた逆シリアル化可能な protobuf バイナリです。
次の protobuf 定義を使用し、Any.unpack()
を使用して逆シリアル化できます。
syntax = "proto3";
message MyMessage {
int32 value = 1;
}
group
のシンプル WebSocket クライアントは、バイナリー データを受け取ります。# 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
ケース 3: バイナリ データを発行する
send_to_group_message.group
を group
に設定し、send_to_group_message.data.binary_data
を [1, 2, 3]
に設定します。
グループ
group
内の protobuf サブプロトコル クライアントはバイナリ フレームを受け取り、DownstreamMessage を使用して逆シリアル化できます。グループ
group
内の JSON サブプロトコル クライアントは以下を受け取ります。{ "type": "message", "from": "group", "group": "group", "dataType" : "binary", "data" : "AQID", // Base64-encoded [1,2,3] }
JSON サブプロトコル クライアントはテキスト ベースのメッセージングのみをサポートします。バイナリは常に Base64 でエンコードされます。
group
のシンプル WebSocket クライアントは、次のバイナリ フレームのバイナリ データを受け取ります。# Show in hexadecimal 01 02 03
カスタム イベントを送信する
暗黙的なdataType
があり、これは設定した dataType
に基づいて、protobuf
、text
、または binary
のいずれかにすることができます。 受信側クライアントは dataType
を利用して、コンテンツを正しく処理できます。
protobuf
:event_message.data.protobuf_data
を設定した場合、暗黙的なdataType
はprotobuf
です。protobuf_data
の値は、サポートされている任意の protobuf 型を指定できます。 イベント ハンドラーは protobuf でエンコードされたバイナリを受け取り、任意の protobuf SDK によって逆シリアル化できます。text
:event_message.data.text_data
を設定した場合、暗黙的なdataType
はtext
です。text_data
の値は、文字列である必要があります。 イベント ハンドラーは、UTF-8 でエンコードされた文字列を受け取ります。binary
:event_message.data.binary_data
を設定した場合、暗黙的なdataType
はbinary
です。binary_data
の値はバイト配列である必要があります。 イベント ハンドラーは、生のバイナリ フレームを受け取ります。
ケース 1: テキスト データを含むイベントを送信する
event_message.data.text_data
を "text data"
に設定します。
アップストリーム イベント ハンドラーは、次に似た要求を受け取ります。
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
dataType
=text
の場合、CloudEvents HTTP 要求の Content-Type
は text/plain
になります。
ケース 2: protobuf データを含むイベントを送信する
次の顧客メッセージを受信したとします。
message MyMessage {
int32 value = 1;
}
event_message.data.protobuf_data
を any.pack(MyMessage)
に設定し、value = 1
を指定します。
アップストリーム イベント ハンドラーは、次に似た要求を受け取ります。
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
dataType
=protobuf
の場合、CloudEvents HTTP 要求の Content-Type
は application/x-protobuf
になります。
データは有効な protobuf バイナリです。 次の proto
および any.unpack()
を使用して、逆シリアル化できます。
syntax = "proto3";
message MyMessage {
int32 value = 1;
}
ケース 3: バイナリ データを含むイベントを送信する
send_to_group_message.binary_data
を [1, 2, 3]
に設定します。
アップストリーム イベント ハンドラーは、次に似た要求を受け取ります。
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
dataType
=binary
の場合、CloudEvents HTTP 要求の Content-Type
は application/octet-stream
です。 WebSocket フレームは、テキスト メッセージ フレームの場合の text
形式であるか、binary
メッセージ フレームの場合の UTF8 でエンコードされたバイナリです。
メッセージが、記述された形式と一致していない場合、サービスによってクライアントが拒否されます。
応答
すべての応答メッセージは、次の protobuf 形式に従います。
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;
}
}
}
クライアントによって受信されるメッセージは、ack
、message
、system
の 3 つのタイプのいずれかになります。
確認応答
要求に ackId
が含まれている場合、サービスからは、この要求に対する確認応答が返されます。 クライアント実装では、次を含むこの ACK メカニズムを処理する必要があります。
async
await
操作の ACK 応答を待機する。- 一定の期間中に ACK 応答が受信されていない場合にタイムアウト チェックを行う。
クライアント実装では必ず、success
の状態が true
または false
のどちらであるかを最初に確認する必要があります。 success
の状態が false
の場合、クライアントは error
プロパティからエラーの詳細を読み取れます。
メッセージ応答
クライアントは、クライアントが参加しているグループから発行されたメッセージを受信できます。 または、サーバーが特定のクライアントまたは特定のユーザーにメッセージを送信するときに、サーバー管理ロールからメッセージを受信できます。
次のシナリオでは、常に DownstreamMessage.DataMessage
メッセージが表示されます。
- メッセージがグループからのものである場合、
from
はgroup
です。 メッセージがサーバーからのものである場合、from
はserver
です。 - メッセージがグループからのものである場合、
group
はグループ名です。
送信者の dataType
は、次のいずれかのメッセージを送信します。
dataType
がtext
の場合、message_response_message.data.text_data
を使用します。dataType
がbinary
の場合、message_response_message.data.binary_data
を使用します。dataType
がprotobuf
の場合、message_response_message.data.protobuf_data
を使用します。dataType
がjson
の場合、message_response_message.data.text_data
を使用します。また、コンテンツはシリアル化された JSON 文字列です。
システム応答
Web PubSub サービスでは、システム関連の応答をクライアントに送信することもできます。
接続済み
クライアントがサービスに接続すると、DownstreamMessage.SystemMessage.ConnectedMessage
メッセージが表示されます。
Disconnected
サーバーによって接続が閉じられるとき、またはサービスによってクライアントが拒否されるとき、DownstreamMessage.SystemMessage.DisconnectedMessage
メッセージを受け取ります。
次のステップ
これらのリソースを使用して、独自のアプリケーションの構築を開始します。