クライアントは、標準の WebSocket プロトコルを使用して Azure Web PubSub に接続します。
サービス エンドポイント
Web PubSub サービスには、クライアントが接続する 2 種類のエンドポイントが用意されています。
/client/hubs/{hub}/client/?hub={hub}
{hub} は、さまざまなアプリケーションの分離として機能する必須パラメーターです。 パスまたはクエリのいずれかで設定できます。
認可
クライアントからサービスへの接続には、JSON Web トークン (JWT) が使用されます。 トークンは、/client/?hub={hub}&access_token={token} のようにクエリ文字列、または Authorization のように Authorization: Bearer {token} ヘッダーに含めることができます。
一般的な承認ワークフローを次に示します。
- クライアントはアプリケーションサーバーと交渉します。 アプリケーション サーバーには承認ミドルウェアが含まれています。ここでクライアントの要求が処理され、クライアントがサービスに接続できるように JWT に署名されます。
- アプリケーション サーバーからクライアントに対して JWT とサービス URL が返されます。
- クライアントは、URL と、アプリケーション サーバーから返された JWT を使用して、Web PubSub サービスへの接続を試みます。
サポートされているクレーム
JWT 内で特別な要求を指定して、アクセス トークンを生成するときにクライアント接続のプロパティを構成することもできます。
| 説明 | 要求の種類 | クレームの値 | メモ |
|---|---|---|---|
クライアント接続用のuserId |
sub |
そのユーザーID | 許可される sub 要求は 1 つだけです。 |
| トークンの有効期間 | exp |
有効期限 |
exp (expiration time) クレームは、トークンが受け入れられて処理されるべきではない期限を指定します。その期限を過ぎた場合、それ以降は、そのトークンを処理することはできません。 |
| 最初にクライアント接続に与えられているアクセス許可 | role |
アクセス許可で定義されているロール値 | クライアントに複数のアクセス許可がある場合は、複数の role 要求を指定します。 |
| クライアント接続が Azure Web PubSub に接続した際に参加する初期グループ | webpubsub.group |
参加するグループ | クライアントが複数のグループに参加する場合は、複数の webpubsub.group 要求を指定します。 |
アクセス トークンにカスタム要求を追加することもできます。これらの値は、接続のアップストリームリクエストのボディ内のclaimsプロパティとして保持されます。
サーバー SDK には、クライアントのアクセス トークンを生成するための API が提供されています。
シンプル WebSocket クライアント
シンプル WebSocket クライアントとは、その名前が示すように、単純な WebSocket 接続です。 これにも独自のカスタム サブプロトコルを使用できます。
たとえば、JavaScript では、次のようなコードを使用して簡単な WebSocket クライアントを作成できます。
// simple WebSocket client1
var client1 = new WebSocket('wss://test.webpubsub.azure.com/client/hubs/hub1');
// simple WebSocket client2 with some custom subprotocol
var client2 = new WebSocket('wss://test.webpubsub.azure.com/client/hubs/hub1', 'custom.subprotocol')
シンプル WebSocket クライアントには、sendEvent と sendToGroupの 2 つのモードがあります。 このモードは、接続が確立されたときに決定され、後で変更することはできません。
sendEvent は、シンプル WebSocket クライアントの既定モードです。
sendEvent モードの場合、クライアントが送信したすべての WebSocket フレームが message イベントであると見なされます。 ユーザーは、イベント ハンドラーやイベント リスナーを構成して、これらのmessageイベントを処理できます。
// Every data frame is considered as a `message` event
var client3 = new WebSocket('wss://test.webpubsub.azure.com/client/hubs/hub1');
// Or explicitly set the mode
var client4 = new WebSocket('wss://test.webpubsub.azure.com/client/hubs/hub1?webpubsub_mode=sendEvent');
sendToGroup モードの場合、クライアントが送信したすべての WebSocket フレームが、特定のグループに発行するメッセージであると見なされます。
group は、このモードで必要なクエリ パラメーターであり、使用できる値は 1 つのみです。 この接続には、ターゲット グループにメッセージを送信するための対応するアクセス許可も必要です。 これに対して webpubsub.sendToGroup.<group> ロールと webpubsub.sendToGroup ロールの両方が機能します。
たとえば、JavaScript では、次のコードを使用して、sendToGroup を使用した group=group1 モードでシンプル WebSocket クライアントを作成できます。
var client5 = new WebSocket('wss://test.webpubsub.azure.com/client/hubs/hub1?webpubsub_mode=sendToGroup&group=group1');
PubSub WebSocket クライアント
PubSub WebSocket クライアントは、Azure Web PubSub サービスによって定義されたサブプロトコルを使用する WebSocket クライアントです。
json.webpubsub.azure.v1protobuf.webpubsub.azure.v1
PubSub WebSocket クライアントでは、アクセス許可がある場合、サービスでサポートされているサブプロトコルを使用してメッセージをグループに直接発行できます。
json.webpubsub.azure.v1 サブプロトコル
JSON サブプロトコルの詳細をこちらで確認してください。
PubSub WebSocket クライアントの作成
var pubsubClient = new WebSocket('wss://test.webpubsub.azure.com/client/hubs/hub1', 'json.webpubsub.azure.v1');
クライアントから直接グループに参加する
let ackId = 0;
pubsubClient.send(
JSON.stringify({
type: 'joinGroup',
group: 'group1',
ackId: ++ackId
}));
クライアントから直接グループにメッセージを送信する
let ackId = 0;
pubsubClient.send(
JSON.stringify({
type: 'sendToGroup',
group: 'group1',
ackId: ++ackId,
dataType: "json",
data: {
"hello": "world"
}
}));
protobuf.webpubsub.azure.v1 サブプロトコル
プロトコル バッファー (protobuf) は、言語的にもプラットフォーム的にも中立なバイナリベースのプロトコルであり、バイナリ データの送信が簡単になります。 protobuf には、Java、Python、Objective-C、C#、C++ などの多くの言語のクライアントを生成するためのツールが用意されています。 Protobuf の詳細を表示。
たとえば、JavaScript では、次のコードを使用して、protobuf サブプロトコルを使用する PubSub WebSocket クライアントを作成できます。
// PubSub WebSocket client
var pubsub = new WebSocket('wss://test.webpubsub.azure.com/client/hubs/hub1', 'protobuf.webpubsub.azure.v1');
protobuf サブプロトコルの詳細をこちらで確認してください。
AckId と確認応答
PubSub WebSocket クライアントでは、ackId、joinGroup、leaveGroup、sendToGroup の各メッセージの event プロパティをサポートしています。
ackId を使用する場合、要求が処理されたら確認応答メッセージを受け取ることができます。 "ファイア アンド フォーゲット" のシナリオでは、ackId を省略することを選択できます。 この記事では、ackId を指定する場合としない場合の動作の違いについて説明します。
ackId を指定しない場合の動作
ackId が指定されていない場合、"ファイア アンド フォーゲット" です。 メッセージの仲介時にエラーが発生した場合でも、通知を受け取る手段はありません。
ackId を指定する場合の動作
べき等発行
ackId は uint64 番号であり、同じ接続 ID を持つクライアント内で一意である必要があります。 Web PubSub サービスは ackId を記録し、同じ ackId を含むメッセージを同じメッセージとして扱います。 サービスは同じメッセージを複数回仲介することを拒否しますが、これは、再試行時にメッセージの重複を避けるために役立ちます。 たとえば、ackId=5 のメッセージを送信したクライアントが ackId=5 の確認応答を受信できない場合、クライアントは再試行し、同じメッセージを再び送信します。 場合によっては、メッセージは既にブローカー化されており、何らかの理由で確認応答が失われることもあります。 サービスは再試行を拒否し、 Duplicate 理由とともに確認応答を返します。
確認応答
Web PubSub サービスは、ackId を持つ要求ごとに確認応答を送信します。
形式:
{
"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>"
}
}
ackIdは要求を関連付けます。successはブール値であり、要求がサービスによって正常に処理されたかどうかを示します。falseの場合、クライアントではerrorを確認する必要があります。errorが存在するのは、successがfalseであり、異なるnameのための異なるロジックがクライアントに必要な場合だけです。 将来、種類としてはnameが増える可能性があることを想定する必要があります。-
Forbidden: クライアントには要求に対するアクセス許可がありません。 必要なロールをクライアントに追加する必要があります。 -
InternalServerError: 何らかの内部エラーがサービスで発生しました。 再試行が必要です。 -
Duplicate: 同じackIdを持つメッセージがサービスによって既に処理されています。
-
アクセス許可
以前の PubSub WebSocket クライアントの説明でお気づきかもしれませんが、クライアントから他のクライアントに発行できるのは、その処理が "承認されている" 場合に限定されます。 クライアントのアクセス許可は、接続されているとき、または接続の有効期間中に付与できます。
| 役割 | 許可 |
|---|---|
| 指定なし | クライアントは、イベント要求を送信できます。 |
webpubsub.joinLeaveGroup |
クライアントは、どのグループについても、参加または脱退が可能です。 |
webpubsub.sendToGroup |
クライアントは、どのグループにもメッセージを発行できます。 |
webpubsub.joinLeaveGroup.<group> |
クライアントは、グループ <group> について、参加または脱退が可能です。 |
webpubsub.sendToGroup.<group> |
クライアントはグループ <group> にメッセージを発行できます。 |
webpubsub.joinLeaveGroups.<pattern> |
クライアントは、名前が <pattern> と一致するすべてのグループに参加または脱退できます ( ワイルドカード グループの役割パターンを参照)。 |
webpubsub.sendToGroups.<pattern> |
クライアントは、名前が <pattern> と一致する任意のグループにメッセージを発行できます ( ワイルドカード グループの役割パターンを参照)。 |
クライアントのアクセス許可は、複数の方法で付与できます。
1. アクセス トークン生成時にクライアントにロールを割り当てる
クライアントは JWT を使用してサービスに接続できます。 トークンのペイロードには、クライアントの role などの情報を伝達できます。 クライアントに JWT に署名するときに、クライアント固有のロールを付与することで、クライアントにアクセス許可を付与できます。
たとえば、 group1 および group2にメッセージを送信するアクセス許可を持つ JWT に署名してみましょう。
let token = await serviceClient.getClientAccessToken({
roles: [ "webpubsub.sendToGroup.group1", "webpubsub.sendToGroup.group2" ]
});
2. connect イベント ハンドラーを使用してクライアントにロールを割り当てる
クライアントのロールは、connect イベント ハンドラーの登録時にも設定できます。アップストリーム イベント ハンドラーは、roles イベントを処理するときにクライアントの connect を Web PubSub サービスに返すことができます。
たとえば、JavaScript で、そのような処理を実行するように handleConnect イベントを構成できます。
let handler = new WebPubSubEventHandler("hub1", {
handleConnect: (req, res) => {
// auth the connection and set the userId of the connection
res.success({
roles: [ "webpubsub.sendToGroup.group1", "webpubsub.sendToGroup.group2" ]
});
},
});
3. 実行中に REST API またはサーバー SDK を使用してクライアントにロールを割り当てる
let service = new WebPubSubServiceClient("<your_connection_string>", "test-hub");
await service.grantPermission("<connection_id>", "joinLeaveGroup", { targetName: "group1" });
注
REST API またはサーバー SDK を使用したワイルドカード ロール ( webpubsub.sendToGroups.<pattern> など) の割り当てはまだサポートされていません。 この機能は、今後の更新プログラムでサポートされる予定です。
次のステップ
これらのリソースを使用して、独自のアプリケーションの構築を開始します。