使用 aws iot 从 aws lambda 向主题发布 mqtt 消息

Publish mqtt message to topic from aws lambda using aws iot

我需要使用 aws iot 通过 mqtt 协议从 aws lambda 发布数据。我用 node.js 代码创建了一个 lambda 函数。像这样

exports.handler = (event, context, callback) => {

    var awsIot = require('aws-iot-device-sdk');

    var device = awsIot.device({
        keyPath: 'samplepath/test.pem.key',
        certPath: 'samplepath/test.crt',
        caPath: 'samplepath',
        clientId: 'sampleId',
        region: 'us-east-1'
    });

    device
        .on('connect', function () {
            console.log('connected');
            device.publish('test_topic', JSON.stringify({ "test_name": "hello", "test_value": 1001 }));
            console.log('published successfully');
            callback(null, 'item added');
        });
}

我在订阅者上收到了 mqtt 消息。但是 lambda 会产生这样的错误消息

Task timed out after 10.00 seconds 

我使用了 context.succeed() 而不是回调,lambda 已正确退出。我无法在订阅者上收到任何消息。

在这两种情况下,控制台都会正确打印 已成功发布 消息。

我的发布代码有什么问题?

I understand my lambda function is timing out when connecting to AWS IoT. About the sdk we are using, the aws-iot-device-sdk is designed to use inside of an embedded device. When we are using a Lambda function or trying to publish in a computer, the best practice is use the aws-sdk. Using the aws-sdk we don't need to use the certificates to publish in the AWS IoT, we just use the AWS credentials to do this. Also, with aws-sdk we can do administrative tasks in the IoT, we can create a thing, create a certificate, etc.

Coming to my code, the reason the function does not end and times out is because the callback must be waiting for an asynchronous call to finish execution, which I assume is being help up by the connection being maintained from the function to IoT. The reason context.succeed() exited properly but we did not get any messages must be because context.succeed does not wait for our async calls to finish execution.

确保在发布消息后断开与设备的连接,否则 Lambda 将在连接保持活动状态时等待(请参阅 http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html,查找 callbackWaitsForEmptyEventLoop)。

完成后要断开连接,只需将 callback(null, 'item added'); 更改为

device.end((err) => { callback(err, "item added"); });