Making an HTTPs request on AWS ApiGatewayV2 websocket connection to Respond, or Delete it

rod*_*ito 5 amazon-web-services node.js aws-lambda aws-api-gateway serverless-framework

UPDATE

This issue is partially resolved, the problem now lies in authenticating the ApiGateway request. I am unsure of how to acquire the necessary tokens to send with the request so that it is valid, because this is a [serverless-framework] service so I can't use the AWS Console to copy paste the tokens into the request's json data. Moreover, I wouldn't know what json key they'd have to be under anyways. So I guess this question has changed considerably in scope.


I need to respond/delete an active websocket connection established through AWS ApiGatewayV2, in a Lambda. How do I use node js to send a POST request that ApiGateway can understand?

I saw on the websocket support announcement video that you could issue an HTTP POST request to respond to a websocket, and DELETE request to disconnect a websocket. Full table from the video transcribed here:

Connection URL
https://abcdef.execute-api.us-west-1.amazonaws.com/env/@connections/connectionId

Operation  Action
POST       Sends a message from the Server to connected WS Client
GET        Gets the latest connection status of the connected WS Client
DELETE     Disconnect the connected client from the WS connection
Run Code Online (Sandbox Code Playgroud)

(this is not documented anywhere else, AFAIK)

Seeing as the AWS SDK does not provide a deleteConnection method on ApiGatewayManagementApi, I need to be able to issue requests directly to the ApiGateway anyways.

const connect = async (event, context) => {
  const connection_id = event.requestContext.connectionId;
  const host = event.requestContext.domainName;
  const path = '/' + event.requestContext.stage + '/@connections/';
  const json = JSON.stringify({data: "hello world!"});

  console.log("send to " + host + path + connection_id + ":\n" + json);

  await new Promise((resolve, reject) => {
    const options = {
      host: host,
      port: '443',
      path: path + connection_id,
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Content-Length': Buffer.byteLength(json)
      }
    };
    const req = https.request(
      options,
      (res) => {
        res.on('data', (data) => {
          console.error(data.toString());
        });
        res.on('end', () => {
          console.error("request finished");
          resolve();
        });
        res.on('error', (error) => {
          console.error(error, error.stack);
          reject();
        });
      }
    );
    req.write(json);
    req.end();
  });
  return success;
};
Run Code Online (Sandbox Code Playgroud)

When I use wscat to test it out, this code results in the console.log showing up in CloudWatch:

send to ********.execute-api.us-east-2.amazonaws.com/dev/@connections/*************:
{
    "data": "hello world!"
}

...

{
    "message": "Missing Authentication Token"
}

...

request finished
Run Code Online (Sandbox Code Playgroud)

And wscat says:

connected (press CTRL+C to quit)
>
Run Code Online (Sandbox Code Playgroud)

但不会打印hello world!或类似内容。

编辑

我不见了

res.on('data', (data) => {
  console.error(data.toString());
});
Run Code Online (Sandbox Code Playgroud)

在响应处理程序中,这很糟糕。但是,这仍然不起作用。

Cen*_*nul 3

你可能在这里遗漏了两件事。

  1. 您需要根据此处的文档向 API 网关发出 IAM 签名请求:在后端服务中使用 @connections 命令
  2. 您需要根据此处的文档授予此 lambda 权限才能调用 API 网关:使用 IAM 授权

我希望这有帮助!