すべてのプロダクト
Search
ドキュメントセンター

Function Compute:WebSocketリクエストに応答する関数のHTTPトリガーの設定

最終更新日:Sep 09, 2024

Function Computeでは、WebSocketリクエストに応答する関数のHTTPトリガーを設定できます。 関数のHTTPトリガーを設定すると、関数はwebサーバーとして機能してWebSocketリクエストを処理し、呼び出し元に応答を返します。

前提条件

サービスが作成されていること。 詳しくは、「サービスの作成」をご参照ください。

ステップ1: 関数を作成する

  1. Function Computeコンソールにログインします。 左側のナビゲーションウィンドウで、[サービスと機能] をクリックします。

  2. 上部のナビゲーションバーで、リージョンを選択します。 [サービス] ページで、目的のサービスをクリックします。

  3. 関数ページで、関数の作成をクリックします。

  4. 関数の作成ページで、カスタムランタイムの使用を選択し、パラメーターを設定し、作成をクリックします。

    次の項目は、設定する必要があるパラメーターについて説明します。 リストされていない他のパラメーターについては、デフォルト値を保持します。 詳細については、「関数の作成」をご参照ください。

    • 関数名: 関数の名前を入力します。 例: websocket-demo

    • ハンドラータイプ: [HTTPハンドラー] を選択します。

    • ランタイム: ドロップダウンリストから [Node.js 14] を選択します。

ステップ2: コードの書き込みとデプロイ

  1. 関数の詳細ページで、コードタブをクリックし、コードエディターに関数コードを入力します。

    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のディレクトリ構造を次の図に示します。directory1

  2. WebIDEターミナルで、npmインストールwsコマンドを実行して依存関係をインストールします。

    依存関係がインストールされると、package-lock.jsonファイルが自動的に生成されます。 ディレクトリの構造を次の図に示します。dir2

  3. デプロイをクリックしてFunction Computeにコードをデプロイします。

ステップ3: 関数のテスト

  1. 関数の詳細ページで、トリガータブでトリガーのパブリックエンドポイントを表示およびコピーします。

    image.png

    説明

    HTTPトリガーの作成後、パブリックエンドポイントは変更されません。

  2. Postmanを使用して関数をテストします。 詳細については、「Postman」をご参照ください。

    1. PostmanでWebSocketリクエストを作成します。

      パブリックエンドポイントをPostmanにコピーし、Schemeパラメーターの値をHTTPSからWSSに変更します。

    2. ビジネス要件に基づいてParamsとHeadersを設定します。

    3. WebSocketに接続します。 接続が確立されたら、メッセージを送信できます。

    4. 送信するメッセージを入力し、関数がメッセージを受信するかどうかを確認します。

    5. 実行タイムアウト時間が経過すると、WebSocketへの接続は終了します。

    次の図は、テストプロセスを示しています。

    image.png

詳細情報

要求タイムアウト

Function Computeは、実行タイムアウト期間に関してWebSocketリクエストとHTTPリクエストを区別しません。 有効なWebSocket接続の期間が指定されたタイムアウト期間を超えると、WebSocket接続は強制的に終了し、クライアントはステータスコード1006を受け取ります。

キープアライブモードとタイムアウト時の再接続

WebSocket接続が確立された後、接続期間が指定されたタイムアウト期間を超えない限り、接続は存続し、Function Computeは既存のロジックを中断しません。 WebSocket接続が存続している特定の期間内にデータが送信されない場合、NAT Gatewayなどの中間ノードによって接続を閉じることができます。 この場合、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-billing

カスタムランタイム

カスタムコンテナランタイム

Python

Python

Node.js

Node.js

ゴラン

ゴラン

よくある質問

WebSocket関数を実行できないのはなぜですか?

  • 新しいトリガーのためにキャッシュを更新するのに必要な時間は約10秒です。 数秒待ってからもう一度やり直してください。

  • 関数の関数コードの依存関係が正しくインストールされているか確認します。 詳細については、「関数のサードパーティの依存関係のインストール」をご参照ください。

  • 関数がリッスンするポートとIPアドレスが正しいかどうかを確認します。 関数がリッスンするIPアドレスを0.0.0.0できます。 ただし、IPアドレスを127.0.0.1またはlocalhostにすることはできません。 カスタムリスニングポートを指定しない場合は、ポート9000が使用されます。

トラブルシューティング

WebSocketハンドシェイクが完了する前に、次のエラーが発生する可能性があります。

  • リクエストエラー: 特定の条件に一致しないリクエストが送信されると、リクエストエラーが発生します。 リクエストエラーが発生した場合、HTTPステータスコード4xxがレスポンスで返されます。

  • 関数エラー: 関数コードが無効な場合、関数エラーが発生します。 関数エラーが発生した場合、HTTPステータスコード5xxが返されます。

エラータイプ

X-Fc-エラータイプ

HTTPステータスコード

原因

課金可能

Request error

FcCommonError

400

リクエストがリクエストの制限を超えています。 詳細については、「概要」をご参照ください。

なし

FcCommonError

400

ID認証が必要な関数のリクエストには、日付または権限情報が含まれていません。

なし

FcCommonError

403

ID認証を必要とする関数のリクエストの署名が無効です。これは、認証情報が無効であることを示します。 日付情報は署名を計算するために使用され、署名は15分間のみ有効です。 アクセス認証が必要なHTTPトリガーを使用する場合、リクエストヘッダーの日付情報が15分を超えて生成されると、署名は無効になります。

なし

FcCommonError

403

リクエストは、HTTPトリガーで設定されていないリクエストメソッドを使用します。 WebSocket関数の場合、HTTPトリガーはGETメソッドをサポートする必要があります。 GETメソッドが設定されていない場合、エラーが報告されます。

なし

FcCommonError

404

WebSocketリクエストは、HTTPトリガーが設定されていない関数に送信されます。

なし

ユーザースロットル

FcCommonError

429

同時実行を減らすか、Function Computeチームに連絡して同時実行制限を増やすことができます。

なし

システムエラー

FcCommonError

500

Function Computeでシステムエラーが発生しました。 もう一度お試しください。

なし

システム調整

FcCommonError

503

Function Computeではシステムスロットリングが有効になっています。 指数バックオフモードで再試行できます。

なし

WebSocketハンドシェイクの完了後に発生するエラーは、関数コードが原因です。 トラブルシューティングのためにコードを確認したり、コードの実行中に生成されたログを表示したりできます。 詳細については、「関数呼び出しログの表示」をご参照ください。

関連ドキュメント

  • WebSocketには、ランタイム、タイムアウト期間、およびデータ送信に制限があります。 詳細については、「WebSocketの制限」をご参照ください。

  • HTTPトリガーは、同期および非同期呼び出しをサポートします。 詳細については、「呼び出しメソッド」をご参照ください。

  • Function Computeでは、オリジン間でHTTP関数を呼び出すことができます。 クロスオリジンリソース共有 (CORS) リクエストの処理方法については、「CORSリクエスト処理」をご参照ください。