big*_*big 4 lambda subscribe amazon-web-services iot
新手问题。找不到以前的答案。
我想用 Alexa 构建一个简单的泵控制器。希望 Alexa 报告泵状态。
最简单的方法是 Alexa -> lambda -> publish_to_Iot。然后,或者可能就在发布之前,订阅另一个主题,本地控制器将向该主题发布将通过 Alexa 传回的泵状态。
就我所知,不可能从 Lambda 订阅主题……这在 lambda 函数的上下文中实际上是有意义的。
具体问题是,lambda 函数可以订阅 IoT 主题吗?
是的,我知道物联网阴影,希望避免一些复杂性。
实际上可以做到这一点,只是不是非常直观。AWS-SDK 没有订阅方法,因此您需要使用 aws-iot-device-sdk。该库通常需要证书和许多其他配置信息。
var device = awsIot.jobs({
keyPath: "./42fc9544f6-private.pem.key",
certPath: "./42fc9544f6-certificate.pem.crt",
caPath: "./AmazonRootCA1.pem",
clientId: "clientPolicy", // name of the policy
host: "your-endpoint.iot.us-east-1.amazonaws.com"
});
Run Code Online (Sandbox Code Playgroud)
但在 lambda 中使用客户端证书没有意义。lambda 已经在 IAM 用户下运行,所以您应该能够利用它吧?事实证明你可以,但需要一点挖掘。aws-iot-device-sdk.js 库将从 Lambda 中的环境变量(process.env.AWS_ACCESS_KEY_ID、process.env.AWS_SECRET_ACCESS_KEY)中读取凭证。但是你必须使用 wss 协议。
var awsIot = require('aws-iot-device-sdk');
device = awsIot.jobs({
host: 'a1jcq6m7bg94jb-ats.iot.us-east-1.amazonaws.com',
protocol: 'wss'});
device
.on('connect', function() {
console.log('connected. subscribing to topic...');
device.subscribe(topic);
console.log('subscribed to topic');
});
Run Code Online (Sandbox Code Playgroud)
这种方法的缺陷之一是 Lambda 中存在自然延迟,当然还有额外的延迟来建立与主题的连接。这确实会减慢速度。一个很好的模式是让 lambda 侦听特定于该 Lambda 实例的主题(例如 lambda/some-uuid/response),然后当您向设备发布消息时,您可以要求它对该主题做出响应. 好处是只要 Lambda 函数启动并运行,主题就会存在。如果交通拥堵或保持温暖,那可能需要几个小时。使用此模型,建立连接和订阅主题没有延迟。在我的测试中,这非常快且延迟低。
这就是我处理订阅的方式。
var subscriber = null;
const lambdaUUID = uuidv4();
const topic = 'lambda/' + lambdaUUID + '/response';
device.on('message', function(topic, payload) {
console.log('incoming message on topic' + topic);
if ( subscriber ) {
console.log('calling subscriber');
subscriber(topic, payload);
} else {
console.log("no subscriber");
}
});
exports.handler = async function(event, context) {
console.log("EVENT: \n" + JSON.stringify(event, null, 2));
var deviceRequest = {"some":"stuff", callback: topic};
const promise = new Promise(function(resolve, reject) {
subscriber = function(topic, payload ) {
console.log('subscriber called, resolving promise...');
resolve("SUCCESS " + payload);
};
});
device.publish('things/THING1234/incoming', JSON.stringify(deviceRequest,null,''), { qos:0 }, function(err, data) {
console.log("publishing message to device",err,data);
});
return promise;
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3073 次 |
| 最近记录: |