Azure Web PubSub入門 ~ 使い方や料金を紹介
はじめに
この記事では、AzureのリアルタイムWeb通信サービスのAzure Web PubSubの基本的な使い方や料金について紹介します。
Azure WebPubSubとは
Azure WebPubSubは、Microsoft Azureクラウドプラットフォーム上で提供されるリアルタイムWeb通信サービスです。
WebSocketsを使用してクライアントとサーバー間の双方向通信を可能にし、リアルタイムのチャットアプリケーション、ライブアップデート、リアルタイムのデータフィードなどの機能を実装するのに適しています。
主な特徴
- 双方向通信: クライアントとサーバー間でリアルタイムの通信が可能。
- スケーラビリティ: 大量の同時接続をサポートし、ニーズに応じてスケールアップ・ダウン可能。
- セキュリティ: Azureのセキュリティと統合され、安全な通信を保証。
- 多様なプログラミング言語サポート: JavaScript, Python, C#, Javaなど多くの言語で利用可能。
利用シナリオ
- リアルタイムチャットアプリケーション
- ライブイベントのストリーミング
- ゲーム内リアルタイム通信
- IoTデバイスからのリアルタイムデータストリーミング
Web PubSubの内部構造
以下にAzure Web PubSubの内部構造の概念図を記載しました。
このセクションでは、Azure Web PubSub上で使用される用語について紹介します。
接続
接続はクライアントまたはクライアント接続とも呼ばれ、Web PubSubサービスに接続された個々のWebSocket接続を表す。
ユニット
Web PubSubサービスの容量やスケールを表す単位です。
ユニットは、同時に接続できるクライアントの数と、サービスの全体的なスループット(データ処理能力)を決定します。
1つのユニットは最大1,000の同時接続をサポートします。
各Web PubSubサービスは、1、2、5、10、20、50または100のユニットを持つことができる。
ハブ
ハブはクライアント接続の集まりを意味する論理的な概念とされています。
クライアントはハブに対して接続し、ハブにメッセージを送信します。
そのため、ハブはチャットアプリ用ハブやイベント通知用ハブなど、目的ごとに一つのハブを作成することで、
WebPubSubサービスに送信されるメッセージをカテゴリごとに分類することができます。
グループ
ハブに接続された接続のサブセットです。 クライアント接続をグループに追加したり、グループから削除したりすることができます。 グループに送信されたメッセージは、グループに接続されたすべてのクライアントに配信されます。
リアルタイムのチャットアプリケーションでは、ハブとグループは以下のように使用することができます。
- ハブ : チャットサービス全体のメッセージを管理
- グループ : 特定のチャットルーム
クライアントイベント
クライアント接続のライフサイクル中に作成されるイベント。
- サービスへの接続を試みるとき: connectイベント
- 成功したとき: connectedイベント
- メッセージを送信するとき: messageイベント
- 切断するとき: disconnectedイベント
サーバー
クライアントイベントを処理したり、クライアント接続を管理したり、グループにメッセージを公開したりすることができる。 イベントハンドラとイベントリスナーの両方がサーバー側とみなされる。
イベントハンドラ
特定のクライアントイベント発生時に実行する処理などを定義したもの。
イベントハンドラはハブに対して事前に登録および設定しておく必要があります。
イベントハンドラを設定しておくと、クライアントイベントの発生時に、
Web PubSub サービスは、CloudEvents HTTP プロトコルを使用して、Webhookで指定されたURLに対してクライアントイベントを配信します。
https://learn.microsoft.com/ja-jp/azure/azure-web-pubsub/concept-service-internals#event-handler
イベントリスナー(プレビュー)
クライアントイベントを監視する仕組みです。
イベントリスナーのエンドポイントとしては、Event Hubsがサポートされており、イベントリスナーを設定することで、Azure Event Hubsにイベントを通知することができます。
https://learn.microsoft.com/ja-jp/azure/azure-web-pubsub/concept-service-internals#event-listener
ユーザー
WebPubSubサービスに接続するための認証情報をもつもの。
メッセージ
WebSocket接続を通じて送信されるデータ。 1メッセージは送信トラフィックの2KBに該当する。 例えば、100KBのトラフィックは50メッセージとカウントされる。
送信メッセージは最大1MBです。
JSON WebSocket サブプロトコル
JSON WebSocket サブプロトコルは、WebSocket プロトコルの上で動作するカスタムのサブプロトコルです。
WebSocket プロトコル自体は、ウェブサーバーとクライアント間で双方向通信を確立するための技術ですが、そのメッセージ内容に関しては規定していません。
そのため、JSON WebSocket サブプロトコルは、JSON 形式でデータを交換するための規約を提供します。
サブプロトコルとは、ある通信プロトコルの中で、送信するデータの通信方式を定義したプロトコルのことです。
送信するメッセージが何を意味するのか、クライアントが特定の時点でどのようなメッセージを送信するのかなどメッセージの仕様などを定義します。
# メッセージ例
{
"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
}
JSONキー
json.webpubsub.azure.v1でメッセージに指定できるJSONキーとして以下のようなものがあります。
キー | 内容 | バリュー例 |
---|---|---|
type | クライアントが行うメッセージの種類を定義 | “sendToGroup”,“joinGroup”,“leaveGroup”,“event”,“ack”,“message” |
group | メッセージ送信先グループ名 | |
dataType | メッセージのデータ形式 | “text”,“json”,“binary” |
data | 送信するメッセージ内容 | |
noEcho | trueの場合、エコーバックされない。 既定値は false。 | true, false |
from | メッセージの送信元 | “system”,“group”,“server” |
event | イベントの名前 | “connected”,“disconnected” |
userId | ユーザID | |
ackId | 各リクエスト一意の識別子(uint64) |
roles
Websocketクライアントに対してrolesを設定すると、 joinGroup や sendToGroup などのアクションを実行するために必要な権限を付与できます。
役割 | アクセス許可 |
---|---|
指定なし | クライアントは、イベント要求を送信できます。 |
webpubsub.joinLeaveGroup | クライアントは、どのグループについても、参加と脱退が可能です。 |
webpubsub.sendToGroup | クライアントは、どのグループにもメッセージを発行できます。 |
webpubsub.joinLeaveGroup. | クライアントはグループ について、参加と脱退が可能です。 |
webpubsub.sendToGroup. | クライアントはグループ にメッセージを発行できます。 |
設定は以下のJavascriptコードなどを使って指定できます。
// PubSub WebSocket client
var pubsub = new WebSocket('wss://test.webpubsub.azure.com/client/hubs/hub1', 'json.webpubsub.azure.v1');
Azure Web PubSubのヘッダの例
項目 | 値 |
---|---|
date | [Thu, 28 Dec 2023 01:45:45 GMT] |
connection | [upgrade] |
upgrade | [websocket] |
sec-websocket-accept | [HsV035iQocuw25x6l2AFq6esp3k=] |
strict-transport-security | [max-age=15724800; includeSubDomains] |
Azure Web PubSubのメッセージ例
# Webpubsubに接続したことを示すメッセージ
{'type': 'system', 'event': 'connected', 'userId': None, 'connectionId': 'XjbF26qSUU5gc-i2YfKtrAdnNu0AK02'}
# Webpubsubへの応答メッセージ
{'type': 'ack', 'ackId': 1, 'success': True}
# グループgへのメッセージ送信
{'type': 'sendToGroup', 'group': 'g', 'ackId': 11, 'noEcho': True, 'dataType': 'json', 'data': '[]'}
Azure Web PubSubサービスの料金
価格レベル
Web PubSub サービスは以下の3つの価格レベルが存在します。
- Free レベル
- Standard レベル
- Premium レベル
これらのレベルは、コンカレント接続数、メッセージ数、許可される最大ユニット数で区別されます。
Free | Standard | Premium | |
---|---|---|---|
ユニットあたりのコンカレント接続数 | 20 | 1,000 | 1,000 |
1 ユニットあたりのメッセージ数 (日単位) | 20,000 | 無制限 | 無制限 |
最大ユニット数 | 1 | 100 | ※公式ページに記載なし |
SLA | 99.90% | 99.90% | 99.95% |
可用性ゾーン (プレビュー) | - | - | あり |
フル マネージド自動スケーリング | - | - | あり |
カスタマイズされたドメイン名 | - | - | あり |
https://azure.microsoft.com/ja-jp/pricing/details/web-pubsub/#pricing
- ※送信メッセージはレベルによらず、最大1MBです。
https://learn.microsoft.com/ja-jp/azure/azure-web-pubsub/concept-service-internals
料金
価格レベルによって、料金は異なります。
2023/12/24時点。
項目 | Free | Standard | Premium | 備考 |
---|---|---|---|---|
1ユニット当たりの料金[円/ユニット/日] | 無料 | 238.087 ※月額:7142.61 | 295.760 ※月額:8872.8 | |
1メッセージ数当たりの料金[円100万メッセージ] | 無料 | 147.880 | 147.880 | ※1メッセージは2KB |
※100万メッセージは約2GB | ||||
※最初の100万メッセージは無料 |
https://azure.microsoft.com/ja-jp/pricing/details/web-pubsub/#pricing
ユニットの課金料金
課金のためのユニット数は、ユニット数と使用時間(秒)に基づいてカウントされ、日次で課金。
例えば、1日の合計使用量が5ユニットで18時間、10ユニットで6時間の場合、課金用の合計ユニット数は、以下のようになります。
(5ユニット * 18時間 + 10ユニット * 6時間) / 24時間 = 6.25ユニット/日
メッセージの課金料金
メッセージは送信トラフィック(アウトバウンド)、受信トラフィック(アウトバウンド)の2種類が存在します。
- 送信トラフィック : Web PubSubサービスから送信されるメッセージ
- 受信トラフィック : Azure Web PubSubサービスに送信されるメッセージ
課金対象は、送信トラフィックのメッセージのみ。
例えば、1ユーザーがグループ内の10クライアントに4KBのデータをブロードキャストした場合、以下の2通信が発生すると考えられます。
- Web PubSubからイベントハンドラに設定されているURLへのデータ送信 :
4KB
- Web PubSubから10クライアントへのデータ配信 :
4KB * 10
課金対象のメッセージ容量は以下になります。
4KB + 4KB * 10 = 44KB
Azure Functions(Python)をWeb PubSubトリガーで起動する
以下の公式ドキュメントに記載されている手順をもとに、Web PubSubのハブにメッセージが送信された際に、Azure Functionsを起動させるトリガー設定を行う手順を紹介します。
ステップ 1: Azure Web PubSub サービスの作成
AzureポータルからAzure Web PubSubのリソースを作成します。
ステップ 2: Azure Functions環境を準備
AzureポータルからAzure Functions(Python)を作成します。
次に拡張機能のMicrosoft.Azure.WebJobs.Extensions.WebPubSubをインストールします。
以下のhost.jsonをFunctionsに適用すると拡張機能のMicrosoft.Azure.WebJobs.Extensions.WebPubSubがFunctionsにインストールされます。
{
"version": "2.0",
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[3.3.*, 4.0.0)"
}
}
ステップ 3: WebPubSubTrigger 関数を作成
WebPubSubTrigger用の関数を作成します。
WebPubSubTriggerは、テンプレートが用意されていないので、一旦、HttpTriggerのテンプレートで作成する必要があります。
ローカルPCで以下のfuncコマンドを実行します。
func new -n webpubsubtrigger -t HttpTrigger
functions.jsonに以下のように
{
"scriptFile": "__init__.py",
"bindings": [
{
"type": "WebPubSubTrigger",
"direction": "in",
"name": "request",
"hub": "simplechat",
"eventName": "message",
"eventType": "user"
}
]
}
ステップ4: ソースコードを記述
Web PubSubのメッセージ受信後にログに内容を出力する処理をソースコードに記述します。
webpubsubtrigger/init.pyに以下のコードを記述します。
import json
import logging
import azure.functions as func
def main(request):
logging.info(request)
logging.info(json.loads(request)["connectionContext"]["userId"])
logging.info('Python HTTP trigger function processed a request.')
requestには以下のようなJSONが格納されています。
{
"data": "hello,liang",
"dataType": "Text",
"connectionContext": {
"eventType": "User",
"eventName": "message",
"hub": "simplechat",
"connectionId": "hoge",
"userId": "alice",
"signature": "hoge",
"origin": "wps-001.webpubsub.azure.com",
"states": {},
"headers": {
"Connection": ["keep-alive"],
"Host": ["func-001.azurewebsites.net"],
"Max-Forwards": ["9"],
"traceparent": ["00-aa20591d97726e2fc6251da3d4f31482-090ee0a69e99d4ec-01"],
"ce-specversion": ["1.0"],
"ce-awpsversion": ["1.0"],
"ce-type": ["azure.webpubsub.user.message"],
"ce-source": ["/hubs/simplechat/client/dxkPoHFpDH4pnfO9FYEyywZm-QawK02"],
"ce-time": ["2023-12-24T06:41:40Z"],
"ce-connectionId": ["dxkPoHFpDH4pnfO9FYEyywZm-QawK02"],
"ce-hub": ["simplechat"],
"ce-eventName": ["message"],
"WebHook-Request-Origin": ["wps-001.webpubsub.azure.com"],
"ce-userId": ["alice"],
"ce-signature": ["hoge"],
"ce-id": ["3"],
"X-ARR-LOG-ID": ["def52427-9dc6-47a0-9665-6965851d737d"],
"CLIENT-IP": ["10.11.12.13:28468"],
"X-SITE-DEPLOYMENT-ID": ["func-001"],
"WAS-DEFAULT-HOSTNAME": ["func-001.azurewebsites.net"],
"X-Forwarded-Proto": ["https"],
"X-AppService-Proto": ["https"],
"X-ARR-SSL": ["2048|256|CN=Microsoft Azure TLS Issuing CA 01, O=Microsoft Corporation, C=US|CN=*.azurewebsites.net, O=Microsoft Corporation, L=Redmond, S=WA, C=US"],
"X-Forwarded-TlsVersion": ["1.3"],
"X-Forwarded-For": ["10.10.10.10:8064"],
"X-Original-URL": ["/runtime/webhooks/webpubsub?code=hoge"],
"X-WAWS-Unencoded-URL": ["/runtime/webhooks/webpubsub?code=hoge"],
"DISGUISED-HOST": ["func-001.azurewebsites.net"]
}
}
}
ステップ5: FunctionsにWeb PubSubの接続文字列を設定
作成したソースコードをAzure Function Appにデプロイします。
その後、Azure Functions のアプリケーション設定にWebPubSubConnectionString
という環境変更にWeb PubSubの接続文字列を設定します。
名前 | 値 |
---|---|
WebPubSubConnectionString | Web PubSubの接続文字列 |
ステップ6: Web PubSub イベントハンドラの設定
Web PubSubに送信されたリクエストをFunctionsに転送するために、関数のエンドポイントを設定します。
AzureポータルからFunctionsのメニューに移動し、以下のように画面遷移します。
App keys -> System keys -> webpubsub_extension
画面遷移後、webpubsub_extensionの値をコピーし、<APP_KEY>として控えておきます。
次にAzureポータルAzure Web PubSub のハブとイベントハンドラーの作成を行います。
名前 | 値 |
---|---|
ハブ名 | simplechat |
URL テンプレート | https://<FUNCTIONAPP_NAME>.azurewebsites.net/runtime/webhooks/webpubsub?code=<APP_KEY> |
ユーザーイベントパターン | * |
システムイベント | - (このサンプルでは設定不要) |
- ※ <FUNCTIONAPP_NAME> は設定する関数アプリの名前です
- ※ <APP_KEY> は前の手順でコピーしたwebpubsub_extensionの値です
ステップ7:動作確認
AzureWeb PubSubにはテストや検証のために一時的なURLを生成するためのシンプルなクライアントURLジェネレーターが用意されているので、 このツールを使って一時的なクライアントアクセスURLを取得します。
Azureポータルにアクセスし、Azure Web PubSubのリソースに移動、以下のように画面遷移します。
設定 -> キー -> クライアントURL Generator
その後、以下のジェネレーターに以下の設定を行います。
- ハブ名にsimplechatを設定
- ユーザIDをaliceに設定
- クライアントアクセスURLを生成してコピー
その後、以下のWebsocketクライアントツールをインストールします。
コピーしたURLをWebsocketクライアントツールに設定し、接続を開き、メッセージを送信します。
8. ステップ: ログの確認
AzureポータルでAzure Functionsの実行ログを確認し、Functionsが動作していることを確認します。