【问题标题】:Possible to subscribe to aws IOT topic in lambda?可以在 lambda 中订阅 aws IOT 主题吗?
【发布时间】:2017-12-31 18:12:07
【问题描述】:

新手问题。找不到以前的答案。

我想用 Alexa 构建一个简单的泵控制器。希望 Alexa 报告泵状态。

最简单的方法是 Alexa -> lambda -> publish_to_Iot。然后,或者可能就在发布之前,订阅另一个主题,本地控制器将发布将通过 Alexa 传回的泵状态。

据我所知,不可能从 Lambda 订阅主题...这在 lambda 函数的上下文中实际上是有意义的。

具体问题是,lambda 函数可以订阅 IoT 主题吗?

是的,我知道 IoT 阴影,希望避免一些复杂性。

【问题讨论】:

  • 这个问题不适合 StackOverFlow,请阅读如何在 SOF 中编写一个好的 questuin。您必须向我们展示您的尝试以及您的问题到底出在哪里。
  • 我更新了一个具体问题。但我还没有尝试任何东西。在开始之前希望能得到一些建议。我想这是违反规则的。

标签: amazon-web-services lambda iot subscribe


【解决方案1】:

实际上可以做到这一点,只是不是非常直观。 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"
});

但在 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');   
});

这种方法的一个缺陷是 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;
};

【讨论】:

  • 在一个模棱两可的问题上写得很好
【解决方案2】:

您可以使用 rules 触发 Lambda 函数以响应匹配的过滤器(过滤器将匹配主题)。

【讨论】:

  • 感谢您的评论,但我认为这不起作用。
  • 抱歉,还在学习如何使用堆栈溢出...据我所知,唤醒 Alexa 的唯一方法是通过唤醒词。您无法通过一些随机 lambda 函数唤醒 Alexa。整个事情需要在 Alexa 启动的 lambda 函数的上下文中运行,例如:Alexa wake word -> lambda -> iot-publish -> iot-subscribe -> (same) lambda -> return to Alexa
  • 哦,您希望触发功能从 IoT 主题发布、订阅和接收?我以为你在寻找 Alexa -> lambda -> 发布 -> lambda。这可能不适合物联网。您可能会查看 DynamoDB 或 SQS 来回传递数据。你可以为主题订阅一个 lambda 函数,但这会比需要的更脆弱,尤其是在规模上。
【解决方案3】:

您正在寻找的答案是将通知从设备发送到 Alexa。示例:“Hi >, Motor pump > is Running”基于泵的实际状态。这更像是一个通知功能,请在 Alexa 语音服务上查看此link,这将帮助您做同样的事情。希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2017-11-28
    • 2018-08-23
    • 2019-01-30
    • 1970-01-01
    • 2016-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多