Я смотрю на поддержку веб-сокетов AWS API Gateway, объявленную относительно недавно -
https://aws.amazon.com/blogs/compute/announcing-websocket-apis-in-amazon-api-gateway/
У них есть пример сервера чата -
https://github.com/aws-samples/simple-websockets-chat-app/blob/master/sendmessage/app.js
, который у меня запущен, очень хорошо.
Если вы отправляете сообщение, sendmessage
Lambda передает это сообщение всем подключенным пользователям через следующее -
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: MIT-0
const AWS = require('aws-sdk');
const ddb = new AWS.DynamoDB.DocumentClient({ apiVersion: '2012-08-10' });
const { TABLE_NAME } = process.env;
exports.handler = async (event, context) => {
let connectionData;
try {
connectionData = await ddb.scan({ TableName: TABLE_NAME, ProjectionExpression: 'connectionId' }).promise();
} catch (e) {
return { statusCode: 500, body: e.stack };
}
const apigwManagementApi = new AWS.ApiGatewayManagementApi({
apiVersion: '2018-11-29',
endpoint: event.requestContext.domainName + '/' + event.requestContext.stage
});
const postData = JSON.parse(event.body).data;
const postCalls = connectionData.Items.map(async ({ connectionId }) => {
try {
await apigwManagementApi.postToConnection({ ConnectionId: connectionId, Data: postData }).promise();
} catch (e) {
if (e.statusCode === 410) {
console.log(`Found stale connection, deleting ${connectionId}`);
await ddb.delete({ TableName: TABLE_NAME, Key: { connectionId } }).promise();
} else {
throw e;
}
}
});
try {
await Promise.all(postCalls);
} catch (e) {
return { statusCode: 500, body: e.stack };
}
return { statusCode: 200, body: 'Data sent.' };
};
Теперь, к сожалению (к счастью ??), у меня есть фон Python / Erlang, а не Javascript / nodejs. Таким образом, я могу видеть, что некоторые из этих действий делают, а именно перебирают соединения в таблице DynamoDB и отправляют ответ каждому. Кроме того, выглядит так, как будто он работает асинхронно, с использованием ключевых слов async
и await
, которые, я полагаю, являются Обещаниями. Но я не могу быть уверенным , это действует асинхронно, что меня беспокоит ... если у меня есть одна лямбда, которая перебирает большое количество соединений и делает синхронные вызовы, это не сработает.
Итак, особенно в отношении этой части кода,
const postCalls = connectionData.Items.map(async ({ connectionId }) => {
try {
await apigwManagementApi.postToConnection({ ConnectionId: connectionId, Data: postData }).promise();
} catch (e) {
if (e.statusCode === 410) {
console.log(`Found stale connection, deleting ${connectionId}`);
await ddb.delete({ TableName: TABLE_NAME, Key: { connectionId } }).promise();
} else {
throw e;
}
}
});
Могу ли я быть уверен, что это отправка postData
всем соединениям в полностью асинхронном режиме? Нужно ли мне беспокоиться о том, что одна лямбда может передавать сообщения тысячам клиентов?