Отправка HTTP-запроса на соединение веб-сокета AWS ApiGatewayV2 с ответом или удалением - PullRequest
5 голосов
/ 28 марта 2019

UPDATE

Эта проблема частично решена, теперь проблема заключается в аутентификации запроса ApiGateway. Я не уверен, как получить необходимые токены для отправки с запросом, чтобы он действовал, потому что это служба [serverless-framework], поэтому я не могу использовать консоль AWS для копирования и вставки токенов в данные json запроса , Более того, я бы не знал, под каким ключом json они должны быть в любом случае. Поэтому я думаю, что этот вопрос значительно изменился.


Мне нужно ответить / удалить активное соединение через веб-сокет, установленное через AWS ApiGatewayV2, в Lambda. Как использовать узел js для отправки POST запроса, который может понять ApiGateway?

Я видел на видео анонса поддержки веб-сокета , что вы можете отправить HTTP POST запрос на ответ на веб-сокет и DELETE запрос на отключение веб-сокета. Полная таблица с транскрибированным видео здесь:

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 не предоставляет метод deleteConnection для ApiGatewayManagementApi , мне все равно нужно иметь возможность отправлять запросы непосредственно на 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 Ответ

2 голосов
/ 28 марта 2019

Скорее всего, вам здесь не хватает двух вещей.

  1. Вам необходимо сделать IAM-подписанный запрос к шлюзу API в соответствии с документацией, расположенной здесь: Использование команд @connections в вашей серверной службе
  2. Вам нужно будет получить это лямбда-разрешение для вызова шлюза API согласно документации здесь: Использовать авторизацию IAM

Надеюсь, это поможет!

...