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

  • ※Azure Web PubSubは他のサービスと異なり、クォーター制限はAzureサービスのドキュメント一覧には記載されていません。

料金

価格レベルによって、料金は異なります。
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クライアントツールをインストールします。

https://chromewebstore.google.com/detail/simple-websocket-client/gobngblklhkgmjhbpbdlkglbhhlafjnh?hl=ja

コピーしたURLをWebsocketクライアントツールに設定し、接続を開き、メッセージを送信します。

8. ステップ: ログの確認

AzureポータルでAzure Functionsの実行ログを確認し、Functionsが動作していることを確認します。


参考