在AWS ApiGatewayV2 websocket连接上发出HTTP请求以响应或删除它

时间:2019-03-28 04:58:56

标签: node.js amazon-web-services aws-lambda aws-api-gateway serverless-framework

更新

此问题已部分解决,现在的问题在于验证ApiGateway请求。我不确定如何获取与请求一起发送的必要令牌,以使其有效,因为这是一项[serverless-framework]服务,因此我无法使用AWS控制台将令牌复制粘贴到请求的json数据中。而且,无论如何我都不知道他们必须使用什么json键。所以我想这个问题的范围已经发生了很大变化。


我需要响应/删除通过Lambda中的AWS ApiGatewayV2建立的活动Websocket连接。如何使用节点js发送ApiGateway可以理解的POST请求?

我在the websocket support announcement video上看到,您可以发出HTTP POST请求以响应Websocket,并发出DELETE请求断开Websocket。视频全文记录在这里:

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

(这在其他任何地方都没有记录,AFAIK)

由于AWS SDK在ApiGatewayManagementApi上未提供deleteConnection方法,因此无论如何我都必须能够直接向ApiGateway发出请求。

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;
};

当我使用wscat对其进行测试时,此代码会导致console.log出现在CloudWatch中:

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

...

{
    "message": "Missing Authentication Token"
}

...

request finished

wscat说:

connected (press CTRL+C to quit)
>

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

编辑

我失踪了

res.on('data', (data) => {
  console.error(data.toString());
});
响应处理程序中的

,这很糟糕。但是,这仍然行不通。

1 个答案:

答案 0 :(得分:1)

您可能在这里错过了两件事。

  1. 您需要根据Use @connections Commands in Your Backend Service
  2. 上的文档向API网关发出IAM签名的请求。
  3. 您需要根据以下文档授予此lambda权限来调用API网关:Use IAM Authorization

我希望这会有所帮助!