crossws icon indicating copy to clipboard operation
crossws copied to clipboard

AWS Lambda support

Open pi0 opened this issue 1 year ago • 2 comments

Resources found:

  • https://docs.aws.amazon.com/apigateway/latest/developerguide/websocket-api-chat-app.html
  • https://docs.aws.amazon.com/apigateway/latest/developerguide/samples/ws-chat-app-starter.zip
connect handler
const { DynamoDBClient } = require("@aws-sdk/client-dynamodb");
const { DynamoDBDocumentClient, PutCommand } = require("@aws-sdk/lib-dynamodb");
exports.handler = async function (event) {
  const client = new DynamoDBClient({});
  const docClient = DynamoDBDocumentClient.from(client);
  const command = new PutCommand({
    TableName: process.env.TABLE_NAME,
    Item: {
      connectionId: event.requestContext.connectionId,
    },
  });

  try {
    await docClient.send(command);
  } catch (err) {
    console.log(err);
    return {
      statusCode: 500,
    };
  }
  return {
    statusCode: 200,
  };
};
disconnect handler
const { DynamoDBClient } = require("@aws-sdk/client-dynamodb");
const {
  DynamoDBDocumentClient,
  DeleteCommand,
} = require("@aws-sdk/lib-dynamodb");
exports.handler = async function (event) {
  const client = new DynamoDBClient({});
  const docClient = DynamoDBDocumentClient.from(client);
  const command = new DeleteCommand({
    TableName: process.env.TABLE_NAME,
    Key: {
      connectionId: event.requestContext.connectionId,
    },
  });

  try {
    await docClient.send(command);
  } catch (err) {
    console.log(err);
    return {
      statusCode: 500,
    };
  }
  return {
    statusCode: 200,
  };
};

send message handler
const { DynamoDBClient } = require("@aws-sdk/client-dynamodb");
const {
  DynamoDBDocumentClient,
  ScanCommand,
} = require("@aws-sdk/lib-dynamodb");
const {
  ApiGatewayManagementApiClient,
  PostToConnectionCommand,
} = require("@aws-sdk/client-apigatewaymanagementapi");
exports.handler = async function (event) {
  const client = new DynamoDBClient({});
  const docClient = DynamoDBDocumentClient.from(client);
  const ddbcommand = new ScanCommand({
    TableName: process.env.TABLE_NAME,
  });

  let connections;
  try {
    connections = await docClient.send(ddbcommand);
  } catch (err) {
    console.log(err);
    return {
      statusCode: 500,
    };
  }

  const callbackAPI = new ApiGatewayManagementApiClient({
    apiVersion: "2018-11-29",
    endpoint:
      "https://" +
      event.requestContext.domainName +
      "/" +
      event.requestContext.stage,
  });

  const message = JSON.parse(event.body).message;

  const sendMessages = connections.Items.map(async ({ connectionId }) => {
    if (connectionId !== event.requestContext.connectionId) {
      try {
        await callbackAPI.send(
          new PostToConnectionCommand({
            ConnectionId: connectionId,
            Data: message,
          })
        );
      } catch (e) {
        console.log(e);
      }
    }
  });

  try {
    await Promise.all(sendMessages);
  } catch (e) {
    console.log(e);
    return {
      statusCode: 500,
    };
  }

  return { statusCode: 200 };
};

default handler
const {
  ApiGatewayManagementApiClient,
  PostToConnectionCommand,
  GetConnectionCommand,
} = require("@aws-sdk/client-apigatewaymanagementapi");
exports.handler = async function (event) {
  let connectionInfo;
  let connectionId = event.requestContext.connectionId;

  const callbackAPI = new ApiGatewayManagementApiClient({
    apiVersion: "2018-11-29",
    endpoint:
      "https://" +
      event.requestContext.domainName +
      "/" +
      event.requestContext.stage,
  });

  try {
    connectionInfo = await callbackAPI.send(
      new GetConnectionCommand({
        ConnectionId: event.requestContext.connectionId,
      })
    );
  } catch (e) {
    console.log(e);
  }

  connectionInfo.connectionID = connectionId;

  await callbackAPI.send(
    new PostToConnectionCommand({
      ConnectionId: event.requestContext.connectionId,
      Data:
        "Use the sendmessage route to send a message. Your info:" +
        JSON.stringify(connectionInfo),
    })
  );
  return {
    statusCode: 200,
  };
};

pi0 avatar Nov 08 '24 09:11 pi0

AWS released another serverless websockets product (AppSync Events) at the end of October (last month)

blog: https://aws.amazon.com/blogs/mobile/announcing-aws-appsync-events-serverless-websocket-apis/

docs: https://docs.aws.amazon.com/appsync/latest/eventapi/event-api-welcome.html

I'm not sure it's suitable here but thought I'd share the news.

o-az avatar Nov 09 '24 12:11 o-az

Ah thanks yes i was looking for that.

pi0 avatar Nov 11 '24 11:11 pi0