如何在 Amazon AWS Lambda 函数中发布到 MQTT 主题?
Posted
技术标签:
【中文标题】如何在 Amazon AWS Lambda 函数中发布到 MQTT 主题?【英文标题】:How can I publish to a MQTT topic in a Amazon AWS Lambda function? 【发布时间】:2016-06-14 11:08:35 【问题描述】:我想要一个简单的命令,就像我在 bash 中使用的那样,在 AWS Lambda 函数内向 MQTT 上的主题发布一些内容。沿着: mosquitto_pub -h my.server.com -t "light/set" -m "on"
背景:我想用 Alexa 打开和关闭一盏灯。 Alexa 可以启动一个 Lambda 函数,在这个 Lambda 函数内部我想启动一个 MQTT 发布,因为灯可以监听 MQTT 主题并对那里的消息做出反应。(也许有更简单的解决方案,但我们处于复杂的(大学)网络,这使得许多其他方法更加困难)
【问题讨论】:
请接受以下答案之一,以便其他人知道您认为哪个有用。 【参考方案1】:如果您使用的是 Python,我可以使用我的处理程序函数中的以下内容获取 AWS Lambda 函数以将消息发布到 AWS IoT:
import boto3
import json
client = boto3.client('iot-data', region_name='us-east-1')
# Change topic, qos and payload
response = client.publish(
topic='$aws/things/pi/shadow/update',
qos=1,
payload=json.dumps("foo":"bar")
)
您还需要确保角色(在您的 Lambda 函数配置中)附加了一个策略以允许访问 IoT 发布函数。在 IAM -> 角色下,您可以将内联策略添加到您的 Lambda 函数角色中,例如:
"Version": "2016-6-25",
"Statement": [
"Effect": "Allow",
"Action": [
"iot:Publish"
],
"Resource": [
"*"
]
]
【讨论】:
感谢您的帮助罗伊。最后我们使用了 Ponte,通过一个 http 请求从 AWS lambda 中退出,该请求被发送到 ponte,然后将其传输到 mqtt 并将其发送到灯。 @xtra 这也是我的问题,在 javascript 中,我们需要端点很烦人,而在 Python 中则不需要。你知道如何在不通过端点的情况下在 JS 中做到这一点吗?【参考方案2】:AWS SDK 有两个类可用于 IoT:Iot 和 IotData。 IotData.publish 是您正在寻找的方法。看起来 Iot 对象用于处理事物,而 IotData 用于处理 MQTT 和阴影。这应该在 MQTT 和 shadows 的文档中直接引用,但事实并非如此。
此服务(IotData)也可用in the CLI。
【讨论】:
感谢您的回答。通过从 bash 发布一个事件,它让我走上了正轨:aws iot-data publish --cli-input-json '"topic":"myTopic", "qos": 0, "payload": "\"myKey\": 54321, \"myOtherKey\": 12345"'
。 Payload 的键必须用双引号括起来并用反斜杠转义。【参考方案3】:
如果您使用的是 Node.js,这将起作用 -
var AWS = require('aws-sdk');
var iotdata = new AWS.IotData( endpoint: '*****************.iot.us-east-1.amazonaws.com' );
exports.handler = async(event) =>
console.log("Event => " + JSON.stringify(event));
var params =
topic: "MyTopic",
payload: JSON.stringify(event),
qos: 0
;
return iotdata.publish(params, function(err, data)
if (err)
console.log("ERROR => " + JSON.stringify(err));
else
console.log("Success");
).promise();
;
记得给这个 lambda 函数使用的角色添加 iot:publish 权限。
【讨论】:
为什么我们需要在JS中指定端点,而在python中我们只能简单地传递区域? @MohammedNoureldin 我们可以在同一个区域有多个端点。 哦,我不知道,我需要检查这怎么可能。或者你能告诉我这怎么可能?或者要搜索的关键字是什么?因为我在快速搜索中找不到这个。但显然 Python boto3 可以在不指定的情况下获取“默认”端点? @MohammedNoureldin 我对 Python boto3 没有任何经验,因此无法提供帮助。【参考方案4】:上一篇关于 nodeJS 的帖子为我发送了 2 次消息。 更正在这里
var mqttParams =
topic: topicName,
payload: JSON.stringify(event),
qos: 1
;
const request = iotdata.publish(mqttParams);
request
.on('success', () => console.log("Success"))
.on('error', () => console.log("Error"))
return new Promise(() => request.send());
【讨论】:
传奇。我一直在为双重消息而苦苦挣扎。【参考方案5】:如果你使用 Node.js,你需要安装 mqtt 库。以下步骤可帮助您在 AWS Lambda 上下载和安装 mqtt 库。
Download and install Node.js and npm 在您的 PC 上。
Download MQTT library for node.js.
在安装了 Node.js 的 nodejs 目录下解压。 (在 Windows 10 x64 中,nodejs 目录为C:\Program Files\nodejs
)
创建一个文件夹来存储 mqtt 安装的文件。例如,D:\lambda_function
。
以管理员身份运行命令提示符,将目录更改为 nodejs 目录。
安装mqtt库到D:\lambda_function
。
C:\Program Files\nodejs>npm install --prefix "D:\lambda_function” mqtt
Here's a similar project.
【讨论】:
【参考方案6】:这是一个使用 async
await
的简单 JavaScript 代码:
const AWS = require("aws-sdk");
exports.handler = async event =>
try
const iotData = new AWS.IotData( endpoint: "IOT_SERVICE_ID-ats.iot.eu-central-1.amazonaws.com" );
const params =
topic: 'some/topic',
payload: JSON.stringify( var1: "val1" )
result = await iotData.publish(params).promise();
console.log(result);
return statusCode: 200, body: `IoT message published.` ;
catch (e)
console.error(e);
return statusCode: 500, body: `IoT message could not be published.` ;
;
不要忘记给这个 lambda 提供发布到这个 IoT 主题所需的 iot:publish 权限。
【讨论】:
以上是关于如何在 Amazon AWS Lambda 函数中发布到 MQTT 主题?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 AWS Lambda 中使用 Node.js 列出我的所有 Amazon EC2 实例?
如何使用Lambda从Amazon AWS中提取和转换单个dynamodb元素
如何在 Lambda 函数中使用 AWS.CloudFront.Signer