简体   繁体   English

如果通过 mqtt 发布字节数组,则不会调用 AWS Lambda

[英]AWS Lambda is not invoked if byte array is published via mqtt

I have created a rule in AWS-iot to invoke a lambda with following query:我在 AWS-iot 中创建了一个规则来使用以下查询调用 lambda:

select * from 'my_topic'

This rule will invoke a below javascript lambda:此规则将调用以下 javascript lambda:

var AWS = require('aws-sdk');
var zlib = require('zlib');
var s3 = new AWS.S3();

        exports.handler = (event, context, callback) => {  
            console.log("hello:");
            var bucketName = "otonomobucket";
            var keyName = getKeyName("myData", Date.now());
            var content = event;
            //var content = JSON.stringify(event);

            console.log("event data:" + content);

            var params = { Bucket: bucketName, Key: keyName, Body: content };

            s3.putObject(params, function (err, data) {
                if (err)
                    console.log(err)
                else
                    console.log("Successfully saved object to " + bucketName + "/" + keyName);
            });
        };

        function getKeyName(folder, filename) {
            return folder + '/' + filename + ".txt";
        }

The lambda works perfectly if i publish any string to my_topic.如果我将任何字符串发布到 my_topic,则 lambda 会完美运行。 But the lambda is not working if i publish bytearray to my_topic.但是如果我将 bytearray 发布到 my_topic,则 lambda 不起作用。 CloudWatch is also not showing any logs. CloudWatch 也不显示任何日志。 How could i get the byte array into my lambda function.我怎样才能将字节数组放入我的 lambda 函数中。

The lambda can receive binary data as long as it is base64 encoded and in a JSON payload. lambda 可以接收二进制数据,只要它是 base64 编码的并且是 JSON 有效负载。 This can be done by changing the rule to:这可以通过将规则更改为:

SELECT encode(*, 'base64') AS data FROM 'my_topic'

The documentation on binary payloads in the SELECT clause indicates that SELECT * FROM 'a/b' should work. SELECT子句中关于二进制有效负载的文档表明SELECT * FROM 'a/b'应该可以工作。 But in my experience this only works for non-JSON payloads with some actions (eg writing to S3) and not with others (sending it to a lambda or Kinesis stream).但根据我的经验,这仅适用于具有某些操作(例如写入 S3)的非 JSON 有效负载,而不适用于其他操作(将其发送到 lambda 或 Kinesis 流)。

This appears to be an issue with how the lambda is invoked.这似乎是如何调用 lambda 的问题。

From https://forums.aws.amazon.com/thread.jspa?messageID=925603&#925603来自https://forums.aws.amazon.com/thread.jspa?messageID=925603&#925603

AWS Lambda only accepts JSON payloads [1] so the Lambda action will only work for json payloads. AWS Lambda 仅接受 JSON 有效负载 [1],因此 Lambda 操作仅适用于 json 有效负载。 This is a common problem and we recommend modifying your rule to base64 encode the binary into a json blob like so:这是一个常见问题,我们建议将您的规则修改为 base64 将二进制编码为 json blob,如下所示:

select encode(*, 'base64') as data from 'some/topic'选择 encode(*, 'base64') 作为来自 'some/topic' 的数据

Your Lambda function will then need to be modified to decode the 'data' key in the event body.然后需要修改您的 Lambda 函数以解码事件正文中的“数据”键。

[1] https://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html#API_Invoke_RequestBody [1] https://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html#API_Invoke_RequestBody

My hypothesis is that the lambda invocation uses the lambda REST API.我的假设是 lambda 调用使用 lambda REST API。 This requires a JSON payload in the request body as described in the link to the API_Invoke_RequestBody这需要请求正文中的 JSON 有效负载,如 API_Invoke_RequestBody 链接中所述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM