如何插入 mysql,然后 return JSON 返回到 websocket 客户端,使用 AWS Lambda 节点函数

How to insert into mysql, then return JSON back to websocket client, using AWS Lambda node function

我有一个使用 $connect 的 AWS WebSocket API,它调用 Lambda 函数将 connectionId 字符串插入数据库。

如果使用 DynamoDB,我会使用这样的过程:

const AWS = require('aws-sdk');
const ddb = new AWS.DynamoDB.DocumentClient({ apiVersion: '2012-08-10', region: process.env.AWS_REGION });

exports.handler = async event => {
  const putParams = {
    TableName: process.env.TABLE_NAME,
    Item: {
      connectionId: event.requestContext.connectionId
    }
  };
  try {
    await ddb.put(putParams).promise();
  } catch (err) {
    return { statusCode: 500, body: 'Failed to connect: ' + JSON.stringify(err) };
  }

  return { statusCode: 200, body: 'Connected.' };
};

这是经过验证的工作。但是,我的任务是使用 MySQL 而不是 Dynamo。我已经在 Lambda 中部署了 NodeJs mysql 包(并验证工作正常),并且 mysql 配置变量设置在 config.json 文件中。

当我尝试 return 将 json 返回到我的 websocket 客户端时,我收到了 502 错误和此 CloudWatch 错误消息:“由于配置错误导致执行失败:格式错误的 Lambda 代理响应”以及“转换前的端点响应主体:null”

我需要将下面的代码更改为:

a) 在MySQLtable中插入一行,然后 b) return JSON 字符串返回到我的 websocket 客户端

var mysql = require('mysql');
var config = require('./config.json');

var pool  = mysql.createPool({
    host     : config.dbhost,
    user     : config.dbuser,
    password : config.dbpassword,
    database : config.dbname
}); 

exports.handler = async event => {
    pool.getConnection(function(err, connection) {
        if (err) {
            return { statusCode: 500, body: 'Failed to connect: ' + JSON.stringify(err) };
        }
        else {
            connection.query("insert into " + process.env.TABLE_NAME + " (`connectionId`) values (?)", [event.requestContext.connectionId], function(e, r) {
                if (e) { 
                    return { statusCode: 500, body: 'Failed to add connection id: ' + JSON.stringify(e) };
                }
                else {
                    return { statusCode: 200, body: 'Connected.' };
                }
            });
        }
    });
}

经过进一步研究和反复试验,我发现以下代码有效:

var mysql = require('mysql');
var config = require('./config.json');

var pool  = mysql.createPool({
    host     : config.dbhost,
    user     : config.dbuser,
    password : config.dbpassword,
    database : config.dbname
});

exports.handler = function(event, context, callback) {
    pool.getConnection(function(err, connection) {
      
    context.callbackWaitsForEmptyEventLoop = false;
      
    if ( err ) {
        callback(null, {
            statusCode: 500,
            body: "Failed to connect: " + JSON.stringify(err)
        });
    }    
       
    let qry = "insert into " + process.env.TABLE_NAME + " (`connectionId`) values (?)";
      
    connection.query(qry, 
      [event.requestContext.connectionId], 
      
      function(err, r) {
            connection.release();
                
            callback(null, {
                statusCode: err ? 500 : 200,
                body: err ? "Failed to connect: " + JSON.stringify(err) : "Connected"
            }); 
        });
    });
};