JSON WebSocket サブプロトコル json.reliable.webpubsub.azure.v1
を使用すると、アップストリーム サーバーへのラウンド トリップなしで、高い信頼性を持ちながら、サービスを介してクライアント間で直接メッセージの発行やサブスクライブを交換できます。
このドキュメントでは、サブプロトコル json.reliable.webpubsub.azure.v1
について説明します。
ネットワークの問題が断続的に発生し、それによって WebSocket クライアント接続が切断されると、メッセージが失われる可能性があります。 Pub/Sub システムでは、パブリッシャーはサブスクライバーから分離されているため、サブスクライバー側で発生した接続の切断やメッセージの損失を検出できない場合があります。
断続的なネットワークの問題を克服し、信頼性の高いメッセージ配信を維持するには、Azure WebPubSub json.reliable.webpubsub.azure.v1
サブプロトコルを使用して "信頼性の高い PubSub WebSocket クライアント" を作成します。
"信頼性の高い PubSub WebSocket クライアント" を使用すると、次のことができます。
- 断続的な問題が発生しているネットワーク接続を回復する。
- メッセージ損失から回復する。
- 参加要求を使用してグループに参加する。
- 脱退要求を使用してグループから脱退する。
- 発行要求を使用してグループに直接メッセージを発行する。
- イベント要求を使用してアップストリームのイベント ハンドラーに直接メッセージをルーティングする。
"信頼性の高い PubSub WebSocket クライアント" は、例えば次のような JavaScript コードを使用して作成できます。
var pubsub = new WebSocket('wss://test.webpubsub.azure.com/client/hubs/hub1', 'json.reliable.webpubsub.azure.v1');
パブリッシャー クライアントとサブスクライバー クライアントを再接続し、メッセージの信頼性を確保する方法については、信頼性のあるクライアントを作成する方法に関するページを参照してください。
クライアントでこのサブプロトコルが使用されている場合、送信データ フレームと受信データ フレームの両方に JSON ペイロードが含まれている必要があります。
アクセス許可
PubSub WebSocket クライアントは、許可されている場合にのみ他のクライアントに発行できます。 クライアントに割り当てられた roles
によって、そのクライアントに付与されるアクセス許可が決まります。
役割 | アクセス許可 |
---|---|
指定なし | クライアントは、イベント要求を送信できます。 |
webpubsub.joinLeaveGroup |
クライアントは、どのグループについても、参加と脱退が可能です。 |
webpubsub.sendToGroup |
クライアントは、どのグループにもメッセージを発行できます。 |
webpubsub.joinLeaveGroup.<group> |
クライアントはグループ <group> について、参加と脱退が可能です。 |
webpubsub.sendToGroup.<group> |
クライアントはグループ <group> にメッセージを発行できます。 |
REST API またはサーバー SDK を使用して、サーバーからクライアントのアクセス許可を動的に付与または取り消すことができます。
要求
グループに参加する
形式:
{
"type": "joinGroup",
"group": "<group_name>",
"ackId" : 1
}
-
ackId
は各要求の ID で、一意である必要があります。 要求の処理結果を通知するために、サービスから確認応答メッセージが送信されます。 詳細については、「AckId と確認応答」を参照してください。
グループを脱退する
形式:
{
"type": "leaveGroup",
"group": "<group_name>",
"ackId" : 1
}
-
ackId
は各要求の ID で、一意である必要があります。 要求の処理結果を通知するために、サービスから確認応答メッセージが送信されます。 詳細については、「AckId と確認応答」を参照してください。
メッセージを発行する
形式:
{
"type": "sendToGroup",
"group": "<group_name>",
"ackId" : 1,
"noEcho": true|false,
"dataType" : "json|text|binary",
"data": {}, // data can be string or valid json token depending on the dataType
}
-
ackId
は各要求の ID で、一意である必要があります。 要求の処理結果を通知するために、サービスから確認応答メッセージが送信されます。 詳細については、「AckId と確認応答」を参照してください。 -
noEcho
はオプションです。 true に設定した場合、このメッセージは同じ接続にエコーバックされません。 設定しない場合の既定値は false です。 -
dataType
は、json
、text
、binary
の次のいずれかに設定できます。-
json
:data
は JSON でサポートされているどの型でもよく、そのままで発行されます。dataType
が指定されていない場合は、既定でjson
になります。 -
text
:data
は文字列形式である必要があり、文字列データが発行されます。 -
binary
:data
は base64 形式である必要があり、バイナリ データが発行されます。
-
ケース 1: テキスト データを発行する:
{
"type": "sendToGroup",
"group": "<group_name>",
"dataType" : "text",
"data": "text data",
"ackId": 1
}
-
<group_name>
のサブプロトコル クライアントは、以下を受け取ります。
{
"type": "message",
"from": "group",
"group": "<group_name>",
"dataType" : "text",
"data" : "text data"
}
-
<group_name>
のシンプル WebSocket クライアントは、文字列text data
を受け取ります。
ケース 2: JSON データを発行する:
{
"type": "sendToGroup",
"group": "<group_name>",
"dataType" : "json",
"data": {
"hello": "world"
}
}
-
<group_name>
のサブプロトコル クライアントは、以下を受け取ります。
{
"type": "message",
"from": "group",
"group": "<group_name>",
"dataType" : "json",
"data" : {
"hello": "world"
}
}
-
<group_name>
のシンプル WebSocket クライアントは、シリアル化された文字列{"hello": "world"}
を受け取ります。
ケース 3: バイナリ データを発行する:
{
"type": "sendToGroup",
"group": "<group_name>",
"dataType" : "binary",
"data": "<base64_binary>",
"ackId": 1
}
-
<group_name>
のサブプロトコル クライアントは、以下を受け取ります。
{
"type": "message",
"from": "group",
"group": "<group_name>",
"dataType" : "binary",
"data" : "<base64_binary>",
}
-
<group_name>
のシンプル WebSocket クライアントは、バイナリ フレームの バイナリ データを受け取ります。
カスタム イベントを送信する
形式:
{
"type": "event",
"event": "<event_name>",
"ackId": 1,
"dataType" : "json|text|binary",
"data": {}, // data can be string or valid json token depending on the dataType
}
-
ackId
は各要求の ID で、一意である必要があります。 要求の処理結果を通知するために、サービスから確認応答メッセージが送信されます。 詳細については、「AckId と確認応答」を参照してください。
dataType
には、text
、binary
、json
のいずれかを指定できます。
-
json
: データは JSON でサポートされているどの型でもよく、そのままで発行されます。既定値はjson
です。 -
text
: データは文字列形式である必要があり、文字列データが発行されます。 -
binary
: データは base64 形式である必要があり、バイナリ データが発行されます。
ケース 1: テキスト データを含むイベントを送信する:
{
"type": "event",
"event": "<event_name>",
"ackId": 1,
"dataType" : "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: JSON データを含むイベントを送信する:
{
"type": "event",
"event": "<event_name>",
"ackId": 1,
"dataType" : "json",
"data": {
"hello": "world"
},
}
アップストリーム イベント ハンドラーは、次のようなデータを受信します。
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>
{
"hello": "world"
}
dataType
が json
の場合、CloudEvents HTTP 要求の Content-Type
は application/json
になります
ケース 3: バイナリ データでイベントを送信する:
{
"type": "event",
"event": "<event_name>",
"ackId": 1,
"dataType" : "binary",
"data": "base64_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>
binary
dataType
が binary
の場合、CloudEvents HTTP 要求の Content-Type
は application/octet-stream
になります。 WebSocket フレームは、テキスト メッセージ フレームの場合の text
形式であるか、binary
メッセージ フレームの場合の UTF8 でエンコードされたバイナリです。
メッセージが、記述された形式と一致していない場合、Web PubSub サービスによってクライアントが拒否されます。
ping
形式:
{
"type": "ping",
}
クライアントは ping
メッセージをサービスに送信して、Web PubSub サービスがクライアントの稼働状態を検出できるようにすることができます。
シーケンス ACK
形式:
{
"type": "sequenceAck",
"sequenceId": "<sequenceId>",
}
信頼性の高い PubSub WebSocket クライアントは、サービスからメッセージを受信した後にシーケンス ACK メッセージを送信する必要があります。 詳細については、信頼性の高いクライアントを作成する方法に関するページを参照してください。
-
sequenceId
は、受信したメッセージからの増分値 (uint64 の数値) です。
応答
クライアントは、複数の種類のメッセージ (ack
、message
、system
、pong
) を受信する可能性があります。 種類が message
であるメッセージには、sequenceId
プロパティがあります。 クライアントは、メッセージを受信した後で、シーケンス ACK をサービスに送信する必要があります。
確認応答
要求に ackId
が含まれている場合、サービスからは、この要求に対する確認応答が返されます。 クライアント実装では、async
await
操作を使用して確認応答を待機したり、一定時間内に確認応答を受信しない場合に備えてタイムアウト ハンドラーを指定したりしておくなどして、この確認メカニズムの処理を行う必要があります。
形式:
{
"type": "ack",
"ackId": 1, // The ack id for the request to ack
"success": false, // true or false
"error": {
"name": "Forbidden|InternalServerError|Duplicate",
"message": "<error_detail>"
}
}
クライアント実装では必ず、最初に success
が true
であるか false
であるかを調べる必要があります。
success
が false
である場合にのみ、クライアントは error
からの読み取りを行います。
メッセージ応答
クライアントで受信できるメッセージは、そのクライアントが参加したグループから発行されたか、特定のクライアントまたは特定のユーザーにメッセージを送信できる、サーバー管理ロールで運用しているサーバーから発行されたものです。
グループからの応答メッセージ:
{ "sequenceId": 1, "type": "message", "from": "group", "group": "<group_name>", "dataType": "json|text|binary", "data" : {} // The data format is based on the dataType "fromUserId": "abc" }
サーバーからの応答メッセージ:
{ "sequenceId": 1, "type": "message", "from": "server", "dataType": "json|text|binary", "data" : {} // The data format is based on the dataType }
ケース 1: Content-Type
=text/plain
と指定した REST API を介した、データ Hello World
の接続への送信
シンプル WebSocket クライアントは、データ
Hello World
が含まれる、WebSocket テキスト フレームを受信します。PubSub WebSocket クライアントは、メッセージ JSON で受け取ります。
{ "sequenceId": 1, "type": "message", "from": "server", "dataType" : "text", "data": "Hello World", }
ケース 2: Content-Type
=application/json
と指定した REST API を介した、データ { "Hello" : "World"}
の接続への送信
シンプル WebSocket クライアントは、文字列化されたデータ
{ "Hello" : "World"}
が含まれる、WebSocket テキスト フレームを受け取ります。PubSub WebSocket クライアントは、メッセージ JSON で受け取ります。
{ "sequenceId": 1, "type": "message", "from": "server", "dataType" : "json", "data": { "Hello": "World" } }
REST API で application/json
コンテンツ タイプを使用して文字列 Hello World
を送信する場合、シンプル WebSocket クライアントが受け取るのは、"
でラップされた "Hello World"
という JSON 文字列です。
ケース 3: Content-Type
=application/octet-stream
と指定した REST API を介した、バイナリ データの接続への送信
シンプル WebSocket クライアントが受け取るのは、バイナリ データが含まれる、WebSocket バイナリ フレームです。
PubSub WebSocket クライアントは、メッセージ JSON で受け取ります。
{ "sequenceId": 1, "type": "message", "from": "server", "dataType" : "binary", "data": "<base64_binary>" }
システム応答
Web PubSub サービスからは、システム関連の応答をクライアントに送信することができます。
pong 応答
Web PubSub サービスは、クライアントから ping
メッセージを受信すると、pong
メッセージをクライアントに送信します。
形式:
{
"type": "pong",
}
接続済み
クライアント接続要求への応答:
{
"type": "system",
"event": "connected",
"userId": "user1",
"connectionId": "abcdefghijklmnop",
"reconnectionToken": "<token>"
}
connectionId
と reconnectionToken
は再接続に使用されます。 次の再接続用 URI を使用して接続要求を行ってください。
wss://<service-endpoint>/client/hubs/<hub>?awps_connection_id=<connectionId>&awps_reconnection_token=<reconnectionToken>
詳細については、「接続の回復」を参照してください
Disconnected
サーバーによって接続が閉じられるとき、またはサービスによってクライアント接続が拒否されるときの応答:
{
"type": "system",
"event": "disconnected",
"message": "reason"
}
次のステップ
これらのリソースを使用して、独自のアプリケーションの構築を開始します。