Azure Web PubSub でサポートされる JSON WebSocket サブプロトコル

JSON WebSocket サブプロトコル json.webpubsub.azure.v1 を使用すると、アップストリーム サーバーへのラウンド トリップなしで、サービスを介してクライアント間でメッセージの発行やサブスクライブを交換できます。 json.webpubsub.azure.v1 サブプロトコルを使用して WebSocket 接続を、PubSub WebSocket クライアントと呼びます。

概要

シンプルな WebSocket 接続では、メッセージを送信するときには必ず message イベントをトリガーします。そしてサーバー側に依存して、メッセージを処理したり他の操作を行ったりします。

json.webpubsub.azure.v1 サブプロトコルを使用すると、次のことができる PubSub WebSocket クライアント を作成できます。

  • 参加要求を使用してグループに参加します。
  • 発行要求を使用してグループに直接メッセージを発行すします。
  • イベント要求を使用して異なったアップストリームのイベント ハンドラーにメッセージをルーティングします。

PubSub WebSocket クライアントは、例えば次のような JavaScript コードを使用して作成できます。

// PubSub WebSocket client
var pubsub = new WebSocket('wss://test.webpubsub.azure.com/client/hubs/hub1', 'json.webpubsub.azure.v1');

このドキュメントでは、サブプロトコル json.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 は、jsontextbinary の次のいずれかに設定できます。
    • 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 には、textbinaryjson のいずれかを指定できます。

  • 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

dataTypetext の場合、CloudEvents HTTP 要求の Content-Typetext/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"
}

dataTypejson の場合、CloudEvents HTTP 要求の Content-Typeapplication/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

dataTypebinary の場合、CloudEvents HTTP 要求の Content-Typeapplication/octet-stream になります。 WebSocket フレームは、テキスト メッセージ フレームの場合の text 形式であるか、binary メッセージ フレームの場合の UTF8 でエンコードされたバイナリです。

メッセージが、記述された形式と一致していない場合、Web PubSub サービスによってクライアントが拒否されます。

応答

クライアントによって受信されるメッセージ型は、次の通りです。

  • ack - ackId を含む要求への応答。
  • message - グループまたはサーバーからのメッセージ。
  • system - Web PubSub サービスからのメッセージ。

確認応答

クライアント要求に ackId が含まれている場合、サービスからは、この要求に対する確認応答が返されます。 クライアントは、ack 応答を asyncawait 操作で待機し、ack 応答が一定時間内に受信されない場合にタイムアウト操作を使用して、ack メカニズムを処理する必要があります。

形式:

{
    "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>"
    }
}

クライアント実装では必ず、最初に successtrue であるか false であるかを調べる必要があり、successfalse である場合にのみエラーを読み込みます。

メッセージ応答

クライアントで受信できるメッセージは、そのクライアントが参加したグループから発行されたか、特定のクライアントまたは特定のユーザーにメッセージを送信できる、サーバー管理ロールで運用しているサーバーから発行されたものです。

  1. メッセージがグループからのものの場合

    {
        "type": "message",
        "from": "group",
        "group": "<group_name>",
        "dataType": "json|text|binary",
        "data" : {} // The data format is based on the dataType
        "fromUserId": "abc"
    }
    
  2. メッセージがサーバーからのものの場合。

    {
        "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 クライアントは次を受信します。

    {
        "type": "message",
        "from": "server",
        "dataType" : "text",
        "data": "Hello World", 
    }
    

ケース 2: Content-Type=application/json と指定した REST API を介した、データ { "Hello" : "World"} の接続への送信

  • シンプル WebSocket クライアントは、文字列化されたデータ { "Hello" : "World"} が含まれる、WebSocket テキスト フレームを受信します。

  • PubSub WebSocket クライアントは次を受信します。

    {
        "type": "message",
        "from": "server",
        "dataType" : "json",
        "data": {
            "Hello": "World"
        }
    }
    

REST API が application/json コンテンツ タイプを使用して文字列 Hello World を送信している場合、シンプル WebSocket クライアントは JSON 文字列を受け取ります。これは、二重引用符 (") で文字列をラップしている "Hello World" です。

ケース 3: Content-Type=application/octet-stream と指定した REST API を介した、バイナリ データの接続への送信

  • シンプル WebSocket クライアントが受信するのは、バイナリ データが含まれる、WebSocket バイナリ フレームです。

  • PubSub WebSocket クライアントは次を受信します。

    {
        "type": "message",
        "from": "server",
        "dataType" : "binary",
        "data": "<base64_binary>"
    }
    

システム応答

Web PubSub サービスは、システム関連のメッセージをクライアントに送信します。

接続済み

クライアントが正常に接続したときにクライアントに送信されるメッセージ:

{
    "type": "system",
    "event": "connected",
    "userId": "user1",
    "connectionId": "abcdefghijklmnop",
}

Disconnected

サーバーによって接続が閉じられるとき、またはサービスによってクライアント接続が拒否されるときに、メッセージがクライアントに送信されます。

{
    "type": "system",
    "event": "disconnected",
    "message": "reason"
}

次のステップ

これらのリソースを使用して、独自のアプリケーションの構築を開始します。