【问题标题】:Can I use an AWS lambda to act as a client of WebSocket (AWS IoT stack)?我可以使用 AWS lambda 作为 WebSocket(AWS IoT 堆栈)的客户端吗?
【发布时间】:2020-03-14 09:08:27
【问题描述】:

我正在尝试连接到已部署的 AWS IoT 堆栈

const AWS = require('aws-sdk');
const iotData = new AWS.IotData({ endpoint: MYENDPOINT });

exports.handler = async (event) => {
try {
   const request = event;
   console.log(request);

    const params = {
        topic: common.topicOut,
        payload: 'MYPAYLOAD'
    }
    console.log("endpoint:",iotData.endpoint,"params:",params);
    iotData.publish(params, (err,res) => {
        if (err) throw err;
        return { statusCode: 200, body: res };
    })


} catch (e) {
   console.error(e);
   return { statusCode: 400, body: 'error, see lambda console' };
}
};

通常一切都“编译”(没有错误),但后来我没有收到任何回应。缩小问题范围,我发现我正在尝试使用 https REST 端点,但 MYENDPOINT 仅支持 wss

我知道https://aws.amazon.com/es/blogs/compute/announcing-websocket-apis-in-amazon-api-gateway/,但那是为了让 lambdas 作为 wscat 客户端的“服务器”。我也读过somediscouragingpostshere,但我更愿意仔细检查你们中是否有人已经找到了使用 AWS-Lambda 的解决方案

如果没有,我将开始使用this workaround,但我无法控制 wss 端点,所以我必须自己制作一个并建议对方在他们这边为我做更改(而且我根本无法控制)

非常感谢您的经历(即使它们是关于“不要走这条路”的提示)。

更新: 我有一个基于控制台的测试客户端,它能够通过 awsIot.device 连接到端点并提供 keyPath、certPath、caPath 和 clientId。

可能是因为权限问题,我收到了静默错误吗?当我尝试在没有证书的情况下使用 awsIot.device 时,它​​会以 Error: No "keyPath" or "privateKey" option supplied. 失败,所以我无法检查是否在控制台上我会收到相同的(静默)错误

UPDATE2:关注https://docs.aws.amazon.com/iot/latest/developerguide/http.html 我可以

$ curl --tlsv1.2 --cacert ./certificates/Amazon_Root_CA_1.pem --cert ./certificates/MYCRT --key ./certificates/MYKEY -X POST -d"PAYLOAD" "https://XXX.iot.REGION.amazonaws.com:8443/topics/MYTOPIC?qos=0"

它有效。因此,我比以前更加确信,如果我能够将证书添加到请求中,这将起作用

UPDATE3:我目前没有为此使用任何 AWS,只是创建了一个模仿上述 curl 调用的 https 请求

【问题讨论】:

    标签: javascript amazon-web-services websocket aws-lambda aws-iot


    【解决方案1】:

    我尝试以 async-await 风格编写。它按测试工作。请确保 Role 和 Endpoint 正确。

    var AWS = require('aws-sdk');
    
    const iotdata = new AWS.IotData({ endpoint: 'XXXXXXXXXX.iot.YYYYYYYYYYY.amazonaws.com' });
    
    exports.handler = async(event) => {
        try {
            const params = {
                topic: 'smartHomeTest',
                payload: 'Hello there',
                qos: 0
            };
    
            const data = await iotdata.publish(params).promise();
    
            console.log(data);
            const response = {
                statusCode: 200,
                body: JSON.stringify(data)
            };
            return response;
        }
        catch (e) {
            console.error(e);
            return { statusCode: 400, body: 'error, see lambda console' };
        }
    }
    

    【讨论】:

    • 谢谢!现在有一个变化,我可以在控制台上看到一个 ForbiddenException,所以比以前更好:)
    • 谢谢,我在问题的 UPDATE1 之前解决了这个问题。现在我会做一个 UPDATE2
    【解决方案2】:

    您的解决方案不起作用,因为您的 Lambda 函数没有被任何东西调用。它只是某处 AWS Lambda 服务器上的一个 zip 文件,等待调用触发 AWS 运行它。因此,Lambda 函数无法创建 websocket 连接并保持打开状态以侦听消息。

    您似乎错过了这样一个事实,即 AWS IoT 服务具有在收到事件时调用 AWS Lambda 函数的内置原生支持。您需要在 AWS IoT 服务中定义一个 Lambda 函数作为事件目标,它会自动调用您的函数,并将 MQTT 消息作为函数的event 参数传递。

    【讨论】:

    • 我忘了提到到目前为止,我只是在我的 aws 控制台 lambda 中使用 Test 按钮,并且我的传感器在我调用它之前一直处于睡眠状态,所以我不能等到传感器发送一些东西(它不会)。谢谢,如果我能够从其他 lambda ping 传感器,我会尝试使用您的解决方案来获取数据
    • 现在我可以唤醒传感器,我正在使用您关于使用 IoT 触发“响应流”的 lambda 的建议
    猜你喜欢
    • 1970-01-01
    • 2018-03-20
    • 2018-07-15
    • 1970-01-01
    • 2017-09-02
    • 2019-04-06
    • 2022-11-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多