Skip to content

Instantly share code, notes, and snippets.

@kvnam
Last active July 11, 2020 07:50
Show Gist options
  • Save kvnam/771ea21d77c85ba50d74678757980a78 to your computer and use it in GitHub Desktop.
Save kvnam/771ea21d77c85ba50d74678757980a78 to your computer and use it in GitHub Desktop.
Connect lambda
const { initMongo, Connection } = require('./ConnectionSchema');
const AWS = require('aws-sdk');
require('./patch.js');
module.exports.handler = async(event, context) => {
await initMongo();
if (event.requestContext.routeKey === "$connect") {
//Save the connection ID in the database
// Set room to Default
let connectionObj = new Connection({ connection: { connectionId: event.requestContext.connectionId, room: "Default" } });
const saveConn = await connectionObj.save();
return {
statusCode: 200,
body: "Hello from Connect Lambda"
};
}
else if (event.requestContext.routeKey === "$disconnect") {
await deleteConnection(event.requestContext.connectionId);
}
else if (event.requestContext.routeKey === "$default") {
return {
statusCode: 200,
body: "Default path"
};
}
else if (event.requestContext.routeKey === "test") {
const body = JSON.parse(event.body);
const msgToAll = JSON.parse(body.rcmsg);
//Simply parse and forward the message sent to every connected user
await postMsgToAll(event, msgToAll, event.requestContext.connectionId);
return {
statusCode: 200,
body: JSON.stringify(body)
};
}else if(event.requestContext.routeKey === "useradd"){
//Add user information to MongoDB
let user = JSON.parse(event.body).rcmsg;
user = JSON.parse(user);
const userObj = new User(user);
// Make sure to include the connection ID
userObj.connectionId = event.requestContext.connectionId;
await userObj.save();
const msgToChat = {
type: "all",
msg: `${userObj.username} joined chat!`
};
//Send new user notification to all
await postMsgToAll(event, msgToChat, event.requestContext.connectionId);
//Send updated user list to all
const usersList = await getUsersList(user.room);
const listMsg = {
type: "userlist",
msg: usersList
};
await postMsgToAll(event, listMsg);
return {
statusCode: 200,
body: JSON.stringify(msgToChat)
};
}else if(event.requestContext.routeKey === "userlist"){
//When a list of user's is required for a room
// Helpful when we want to reconnect
const body = JSON.parse(event.body);
const usersList = await getUsersList(body.roomname);
return {
statusCode: 200,
body: JSON.stringify(usersList)
};
}
};
// Delete the connectionId sent in as arg
const deleteConnection = async (connectionId) => {
return new Promise( (resolve, reject) => {
Connection.deleteOne({ 'connection.connectionId': connectionId }, function(err) {
if (err){
// Log errors in CloudWatch
console.log(`Error deleting connection ${err.toString()}`);
reject()
}
resolve();
});
})
}
....
// POST request to our WebSocket APIGateway with connectionId and data parameters
const postMessage = async (connectionId, data, apigwManagementApi) => {
try{
await apigwManagementApi.postToConnection({
ConnectionId: connectionId,
Data: data
}).promise();
}catch(err){
console.log(`Error posting to API`);
console.log(err);
if(err.statusCode === 410){
// Delete all stale connections
console.log('Stale connection');
await deleteConnection(connectionId);
}
}
};
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
let db = null;
//Initialize connection to MongoDB
module.exports.initMongo = async () => {
return new Promise((resolve, reject) => {
// I set up environment variables for my lambda to allow easy change. This is useful
// since I stop / start my EC2 instance often.
// In my case MONGO_HOST is the private IP of my EC2 instance, since I'm using VPC peering
// to connect my Lambda (in the requester VPC) to my EC2 (in accepter VPC) with CIDR blocks
mongoose.connect(`mongodb://${process.env.MONGO_USER}:${process.env.MONGO_PWD}@${process.env.MONGO_HOST}:${process.env.MONGO_PORT}/${process.env.MONGO_DB}`, { useNewUrlParser: true }, function(err){
if(err){
console.log('Connecting error');
console.log(err);
reject()
}
db = mongoose.connection;
resolve(db);
});
})
}
const connectionSchema = new Schema({
connection: {
connectionId: String,
room: String // This will be used when our frontend app is set up
}
});
module.exports.Connection = mongoose.model('Connection', connectionSchema);
@mihristov
Copy link

Could you also show the postMsgToAll function?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment