【问题标题】:AWS IoT: Subscribe to Topic in BrowserAWS IoT:在浏览器中订阅主题
【发布时间】:2018-08-23 00:29:21
【问题描述】:

我目前正在使用 AWS 开发无服务器应用程序。

我想使用纯 JavaScript(无 Node.js、React、Angular 等)订阅主题

IoT 和 IoTData SDK 不支持“订​​阅主题”功能。

要实现这一点,我需要通过require('aws-iot-device') 实现aws-iot-device sdk(我不能在纯JS 中使用)。

不幸的是,此 SDK 仅适用于 Node.js 或 Browserify 等运行时。 那么如何才能从浏览器订阅主题呢?有没有办法将 SDK 实现为纯 JS?

提前致谢

【问题讨论】:

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


    【解决方案1】:

    您可以在浏览器中使用paho jsmqttjs。用于 javascript 的 aws-iot-device sdk 是 mqttjs 的包装器。

    【讨论】:

      【解决方案2】:

      这就是它的完成方式,效果很好:

      <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.11.2/moment.min.js" type="text/javascript"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/core-min.js" type="text/javascript"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/hmac-min.js" type="text/javascript"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/sha256-min.js" type="text/javascript"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.min.js" type="text/javascript"></script>
      

      将此库添加到您的 html 中。

       function SigV4Utils(){}
      
            SigV4Utils.sign = function(key, msg) {
                var hash = CryptoJS.HmacSHA256(msg, key);
                return hash.toString(CryptoJS.enc.Hex);
              };
      
              SigV4Utils.sha256 = function(msg) {
                var hash = CryptoJS.SHA256(msg);
                return hash.toString(CryptoJS.enc.Hex);
              };
      
              SigV4Utils.getSignatureKey = function(key, dateStamp, regionName, serviceName) {
                var kDate = CryptoJS.HmacSHA256(dateStamp, 'AWS4' + key);
                var kRegion = CryptoJS.HmacSHA256(regionName, kDate);
                var kService = CryptoJS.HmacSHA256(serviceName, kRegion);
                var kSigning = CryptoJS.HmacSHA256('aws4_request', kService);
                return kSigning;
              };
      
              function createEndpoint(regionName, awsIotEndpoint, accessKey, secretKey) {
                var time = moment.utc();
                var dateStamp = time.format('YYYYMMDD');
                var amzdate = dateStamp + 'T' + time.format('HHmmss') + 'Z';
                var service = 'iotdevicegateway';
                var region = regionName;
                var secretKey = secretKey;
                var accessKey = accessKey;
                var algorithm = 'AWS4-HMAC-SHA256';
                var method = 'GET';
                var canonicalUri = '/mqtt';
                var host = awsIotEndpoint;
                var credentialScope = dateStamp + '/' + region + '/' + service + '/' + 'aws4_request';
                var canonicalQuerystring = 'X-Amz-Algorithm=AWS4-HMAC-SHA256';
                canonicalQuerystring += '&X-Amz-Credential=' + encodeURIComponent(accessKey + '/' + credentialScope);
                canonicalQuerystring += '&X-Amz-Date=' + amzdate;
                canonicalQuerystring += '&X-Amz-SignedHeaders=host';
                var canonicalHeaders = 'host:' + host + '\n';
                var payloadHash = SigV4Utils.sha256('');
                var canonicalRequest = method + '\n' + canonicalUri + '\n' + canonicalQuerystring + '\n' + canonicalHeaders + '\nhost\n' + payloadHash;
                var stringToSign = algorithm + '\n' +  amzdate + '\n' +  credentialScope + '\n' +  SigV4Utils.sha256(canonicalRequest);
                var signingKey = SigV4Utils.getSignatureKey(secretKey, dateStamp, region, service);
                var signature = SigV4Utils.sign(signingKey, stringToSign);
                canonicalQuerystring += '&X-Amz-Signature=' + signature;
                canonicalQuerystring += '&X-Amz-Security-Token=' + encodeURIComponent(AWS.config.credentials.sessionToken);
                return 'wss://' + host + canonicalUri + '?' + canonicalQuerystring;
              }
              var endpoint = createEndpoint(
              'eu-central-1',  // YOUR REGION
              'xxxxxx.iot.eu-central-1.amazonaws.com', // YOUR IoT ENDPOINT  
              accesskey, // YOUR ACCESS KEY    
              secretkey); // YOUR SECRET ACCESS KEY   
      
              var clientId = Math.random().toString(36).substring(7);
              var client = new Paho.MQTT.Client(endpoint, clientId);
              var connectOptions = {
                useSSL: true,
                timeout: 3,
                mqttVersion: 4,
                onSuccess: subscribe
              };
              client.connect(connectOptions);
              client.onMessageArrived = onMessage;
              client.onConnectionLost = function(e) {
                 console.log(e) 
              };
      
      
              function subscribe() {
               client.subscribe("my/things/something");
               console.log("subscribed");
              }
      
              function onMessage(message) {
                var status = JSON.parse(message.payloadString);
              }
      

      使用此代码,您可以在纯客户端 JavaScript 中订阅 IoT 主题。不需要 Node.js、React.js 或类似的东西!

      【讨论】:

      • 客户端中有很多代码和(可以说)敏感信息,我会(事实上这就是我所做的)将签名代码移动到服务器端并查询返回签名的 API 端点网址。
      • 这一行需要一个变量 session_token。那是从哪里来的? canonicalQuerystring += '&X-Amz-Security-Token=' + encodeURIComponent(session_token);返回 '​​wss://' + 主机 + canonicalUri + '?' + canonicalQuerystring;
      • 嘿,我们将该行更改为 canonicalQuerystring += '&amp;X-Amz-Security-Token=' + encodeURIComponent(AWS.config.credentials.sessionToken); 如果您包含正确的 AWS 库,您应该可以默认调用 AWS.config.credentials.sessionToken。很抱歉回答得很晚......假期:D
      猜你喜欢
      • 2017-11-28
      • 1970-01-01
      • 2019-01-30
      • 1970-01-01
      • 1970-01-01
      • 2016-08-23
      • 1970-01-01
      • 1970-01-01
      • 2021-02-17
      相关资源
      最近更新 更多