Function Computeでは、WebSocketリクエストに応答する関数のHTTPトリガーを設定できます。 関数のHTTPトリガーを設定すると、関数はwebサーバーとして機能してWebSocketリクエストを処理し、呼び出し元に応答を返します。
始める前に
ステップ1: 関数を作成する
Function Computeコンソールにログインします。 左側のナビゲーションウィンドウで、[サービスと機能] をクリックします。
上部のナビゲーションバーで、リージョンを選択します。 [サービス] ページで、目的のサービスをクリックします。
関数ページで、関数の作成をクリックします。
関数の作成ページで、カスタムランタイムの使用を選択し、パラメーターを設定し、作成をクリックします。
次の項目は、設定する必要があるパラメーターについて説明します。 リストされていない他のパラメーターについては、デフォルト値を保持します。 詳細については、「関数の作成」をご参照ください。
関数名: 関数の名前を入力します。 例: websocket-demo
ハンドラータイプ: [HTTPハンドラー] を選択します。
ランタイム: ドロップダウンリストから [Node.js 14] を選択します。
ステップ2: コードの書き込みとデプロイ
関数の詳細ページで、コードタブをクリックし、コードエディターに関数コードを入力します。
Function ComputeコンソールのWebIDEの現在のディレクトリで、次のコードをindex.jsファイルにコピーします。 サンプルコード:
const WebSocket = require('ws'); const WebSocketServer = WebSocket.Server; const wss = new WebSocketServer({ host: "0.0.0.0", port: 9000, }); wss.on('connection', function (ws, req) { console.log(`[SERVER] connection()`); ws.on('message', function (message) { ws.send(`${message}`, (err) => { if (err) { console.log(`[SERVER] error: ${err}`); } }); }) });
説明WebSocketサーバーがリッスンするIPアドレスは
0.0.0.0
です。これは、使用可能なすべてのネットワークポートを示します。 IPアドレスとして127.0.0.1
またはlocalhost
を指定しないでください。WebSocketサーバーがリッスンするポート番号は、0から65535の範囲の整数です。 ほとんどの場合、ポート番号は1024より大きくなります。
port
パラメーターは、関数に指定した値に設定する必要があります。 デフォルトでは、値は9000
です。
WebIDEのディレクトリ構造を次の図に示します。
WebIDEターミナルで、
npmインストールws
コマンドを実行して依存関係をインストールします。依存関係がインストールされると、package-lock.jsonファイルが自動的に生成されます。 ディレクトリの構造を次の図に示します。
デプロイをクリックしてFunction Computeにコードをデプロイします。
ステップ3: 関数のテスト
関数の詳細ページで、トリガータブでトリガーのパブリックエンドポイントを表示およびコピーします。
説明HTTPトリガーの作成後、パブリックエンドポイントは変更されません。
Postmanを使用して関数をテストします。 詳細については、「Postman」をご参照ください。
PostmanでWebSocketリクエストを作成します。
パブリックエンドポイントをPostmanにコピーし、Schemeパラメーターの値をHTTPSからWebSocket Secure (WSS) に変更します。
ビジネス要件に基づいてParamsとHeadersを設定します。
WebSocketに接続します。 接続が確立されたら、メッセージを送信できます。
送信するメッセージを入力し、関数がメッセージを受信するかどうかを確認します。
実行タイムアウト時間が経過すると、WebSocketへの接続は終了します。
次の図は、テストプロセスを示しています。
(オプション) Postmanを使用してHTTPトリガーをテストするときにFCCommonErrorが発生した場合は、HTTPトリガーの認証方法を確認します。 アクセスを認証する必要がない場合は、テストを実行する前にHTTPトリガーの認証方法を [認証なし] に設定できます。
詳細情報
要求タイムアウト
Function Computeは、実行タイムアウト期間に関してWebSocketリクエストとHTTPリクエストを区別しません。 WebSocket接続が指定されたタイムアウト時間よりも長く続く場合、WebSocket接続は強制的に終了し、クライアントはステータスコード1006を受け取ります。
キープアライブモードとタイムアウト時の再接続
WebSocket接続が確立された後、接続期間が指定されたタイムアウト期間を超えない限り、接続状態は有効であり、Function Computeは既存のロジックを中断しません。 WebSocket接続が存続している期間内にデータが送信されない場合、クライアントの内部IPアドレスをパブリックIPアドレスにマッピングし、設定をルーティングするNATゲートウェイなどの中間ノードによって接続を無効にすることができます。 この場合、接続タイムアウト時間は固定されません。 タイムアウト期間内に送信されたデータがない場合、NATゲートウェイはWebSocket接続を切断してもよい。 接続を維持するか、WebSocketプロトコルで提供されるpingフレームとpongフレームを使用してWebSocket接続が利用可能かどうかを確認する必要がある場合があります。
Function Computeが提供する最大タイムアウト期間を超えるより長いタイムアウト期間が必要な場合、または実行中のアプリケーションの安定したロジックを維持する場合は、タイムアウトを処理するためにクライアントコードに再接続メカニズムを追加します。 上記のメカニズムは、Reconnecting-WebSocketライブラリまたはSocketIOライブラリを使用して実装できます。
セッションアフィニティ
Function Computeはステートレスです。 関数が同時に多数の同時リクエストを受信した場合、function Computeは、同じクライアントからのリクエストが同じコンテナーで処理されることを保証できません。 複数のコンテナインスタンス間でWebSocketリクエストのステータスを維持するには、Redis、Memcached、Apache Kafka、データベースなどの外部ストレージサービスを使用する必要がある場合があります。
たとえば、チャットルームアプリケーションの場合、Function Computeは、すべてのユーザーが同じ関数インスタンスに同時に接続されることを保証することはできません。 この場合、RedisのPub/Sub機能を使用して、チャットルームアプリケーションを構成できます。 ユーザーがチャットルームに参加すると、チャットルームが属するチャンネルにサブスクライブ (Sub) します。 ユーザー1が関数にメッセージを送信すると、関数はメッセージをRedisのチャットルームが属するチャネルに公開 (Pub) します。 これにより、チャットルーム内のすべてのユーザーがメッセージを受信できます。
課金方法
WebSocketリクエストとHTTPリクエストの課金方法は同じです。 WebSocketリクエストは、接続時間が長いHTTPリクエストと見なすことができます。 課金の詳細については、「課金の概要」をご参照ください。
インスタンスの同時実行性が1の関数の場合、課金はWebSocket接続が確立されると開始され、WebSocket接続が終了すると終了します。
インスタンスの同時実行性が1より大きい関数の場合、最初のWebSocket接続が確立されたときに課金が開始され、最後のWebSocket接続が終了したときに課金が終了します。 ある期間内に複数の接続が存在する場合、システムは1回だけ課金を実施します。
次の図では、関数のインスタンスの同時実行性は2です。 第1の要求はT1に到着し、T3で終了する。 第2の要求はT2に到着し、T4で終了する。 課金はT1から始まり、T4で終了する。 T2からT3まで、料金は一度だけ請求されます。
例
カスタムランタイム | カスタムコンテナランタイム |
よくある質問
追加情報
WebSocketには、ランタイム、タイムアウト期間、およびデータ送信に制限があります。 詳細については、「WebSocketの制限」をご参照ください。
HTTPトリガーは、同期および非同期呼び出しをサポートします。 詳細については、「呼び出しメソッド」をご参照ください。
Function Computeでは、オリジン間でHTTP関数を呼び出すことができます。 クロスオリジンリソース共有 (CORS) リクエストの処理方法については、「CORSリクエスト処理」をご参照ください。