3 Answers
- Newest
- Most votes
- Most comments
0
I found the answer, change forEach loop to a for loop.
from:
items?.forEach(async (item) => {
await apigwManagementApi.postToConnection(params).promise()
});
to:
for (const item of items) {
await apigwManagementApi.postToConnection(params).promise()
}
I can't explain it, but it works, message are sent instantly to websocket.
answered 3 years ago
0
The issue is the way Node.js works. You are calling postToConnection, but what actually happens is that an event is added to the Node.js event loop. It is not performed immediately. You get to the end of the function and the run-time is frozen. At the point we do not handle the rest of the events until you invoke the function again. We then unfreeze the run-time and handle the next event.
To fix it, you should use await when calling postToConnection.
0
Hello @Uri, thank you for answering.
Unfortunately, this is already the case, I am already using async/await :
const AWS = require("aws-sdk");
const apigwManagementApi = new AWS.ApiGatewayManagementApi({
endpoint: process.env.WEBSOCKET_DOMAIN_NAME
});
const dynamo = new AWS.DynamoDB.DocumentClient({ region: process.env.AWS_REGION });
/**
* Send Websocket Message
*/
const websocketSendMessage = async (connectionId, data) => {
const params = {
ConnectionId: connectionId,
Data: JSON.stringify(data)
};
await apigwManagementApi.postToConnection(params).promise();
return;
};
/**
* Handler
*/
const handler = async (event) => {
const { userId, data } = event;
// Retrieve all connectionId of user from DynamoDB
let items;
const dynamoItem = await dynamo.scan({
TableName: process.env.DYNAMO_TABLE_NAME,
FilterExpression: "userId = :userId",
ExpressionAttributeValues: { ":userId": userId }
}).promise();
items = dynamoItem.Items;
// Send websocket message for each websocket client of user
items?.forEach(async (item) => {
await websocketSendMessage(item.connectionId, data);
});
return { statusCode: 200 };
};
answered 3 years ago
Relevant content
- AWS OFFICIALUpdated 3 months ago
