web-dev-qa-db-ja.com

AWS API Gateway WebSockets - ConnectionIDはどこですか?

ここで説明されているように、$ CONNECT ROUTEにカスタム承認者を持つAWS API Gateway WebSocketを設定しています。

https://docs.aws.amazon.com/apigateway/latest/developeruder/apigateway-websocket-api-route-keys-connect-disconnect.html

私の質問は、ConnectionID、つまり識別子が後で接続されているクライアントにブロードキャストするために使用できる方法をどうやっていますか?

8
Big Endian

質問では、どのタイプのバックエンドが使用されているかを指定しません。 AWS API GatewayのAWSドキュメントは、Lambda関数に向かって対応しています。

ビッグエンディアンによる答えを試みる、私はいくつかの問題を見つけました - 私のCakePHPバックエンドは引用済みJSONボディを復号しません。私は解決策を見つけました、しかし、彼の答えを実施するために必要な他の多くのステップがありましたので、ここでは:

HTTPプロキシを使用してルートキーを作成し、次のようにリクエストテンプレートを設定します(非常にスパースドキュメントも)。

  • ルート選択式:$ Request.Body.action.
  • ルートキー:購読する
    [。]これは{"action"というすべての要求を意味します。 "subscribe"}はここでルートします

  • 統合要求の種類:http.

  • HTTPプロキシの統合:オフ - ヘッダーまたは認証を通過する
  • HTTPメソッド:投稿

そして、ハードパートの場合:リクエストテンプレートを設定します。このテンプレートを使用するようなすべての「購読」要求を求めて、これを行うことができる唯一の方法は、Template Selection式をRoute Selection式:$ Request.Body.actionと同じに設定し、「購読する」 "。

これは、APIがこのテンプレートを適用するためにしなければならないのと同じコンテンツのための二重テストになることが終わっています - そして誰かがこれをより良い方法を持っているなら、コメントしてください。

そして最後のステップは、 'subscribe'の "Generate Template"としてこれを入力することです。

{"connectionId": "$context.connectionId", "body": $input.body}
 _

私の場合、私の体はJSONで、$ input.bodyは引用符で囲まれていませんでした - Body JSONはテンプレートによって拡張されます。ボディがただの文字列である場合は、テンプレートは

{"connectionId": "$context.connectionId", "body": "$input.body"}
 _

しかし、ルーティングがJSONのアクションキーを含むボディを必要とするため、ルーティングはここに入りません。

1
Francois Stark

統合要求にコンテンツを追加するには、リクエストテンプレートを使用する必要があります。

  1. ルートのHTTPプロキシ統合をオフにします。 (それ以外の要求を変更することはできません。)
  2. 変更を保存してください。 (リクエストテンプレートセクションは、そうするまで表示されません。)
  3. テンプレートの選択式を設定します。これは、着信要求オブジェクトから値を調べるために使用されます。 (着信要求をすべて一致させる場合は、\$defaultと入力してください。スラッシュに注意してください。フルドキュメント ここ 。)
  4. テンプレートキーを設定してください。これは、テンプレート選択式によって選択された値と比較されます。一致すると、テンプレートが使用されます。 (着信要求をすべて一致させたい場合は、$defaultと入力してください。スラッシュがないことに注意してください。)
  5. テンプレートキーをクリックしてテンプレートエディタを開きます。これが、統合エンドポイントに送信されるテンプレートをリクエストの本文として入力する場所です。たとえば、接続IDと着信クエリパラメータを統合エンドポイントに転送する場合は、次のようにします。
{
    "myConnectionIdProperty": "$context.connectionId",
    "myQueryParams": $input.params()
}

テンプレート式で利用可能な変数のマニュアルを見つけることができます こちら

$requestは、テンプレートの選択式では、テンプレート自体で有効な変数ではありません。代わりに$inputを使用してください。)

1
Ben Grabow

ConnectionIDをコンテキスト変数から取得できます。 WebSocket APIの使用可能な変数については、 https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-websocket-api-mapping-template-reference.html

Lambda関数では、Event.RequestContextを介してコンテキスト変数にアクセスできます。

0
Jaewoo Ahn

Francois Starkに感謝します。

私自身の実験を通して、私は$ request.body.ackeActionの特定の値を一致させる必要性を避けることができます。$既定のルートと次の形式を使用して。

  • テンプレートの選択式:\ $ default < - そのスラッシュが重要です
  • テンプレートキー:\ $ default < - もう一度スラッシュ
  • テンプレートを生成します
_{"connectionId": "$context.connectionId", "body": $input.body}
_

この設定では、HTTPエンドポイントは、単一のルートを使用して 'Action'のすべての値のボディデータとしてConnectionIDを取得する必要があります。

さらに、_$connect_と_$disconnect_ routesに接続されているため、リクエストテンプレートの形式は同じですが、これらのイベントにはボディデータがないため、ボディを省略することができます。

  • テンプレートの選択式:\ $ default < - そのスラッシュが重要です
  • テンプレートキー:\ $ default < - もう一度スラッシュ
  • テンプレートを生成します
_{"connectionId": "$context.connectionId"}
_

この設定では、HTTPエンドポイントは$ CONNECTと$ DISCONNECTイベントのBODYデータとしてConnectionIDを取得する必要があります。

0
MikeGuz

Event.RequestContextからConnectionIDを取得できます。

exports.handler = async (event) => {
const data = event['body'];
const connectionId = event['requestContext']['connectionId'];};
 _
0
Asha Joshi