Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use AWS IoT to send/receive messages to/from Web Browser

We are trying to use Amazon Web Services Internet of Things (AWS IoT) to send messages from/to a Web Browser (e.g: . Given that the AWS IoT supports JavaScript we expect that this is possible ...

We have searched at the AWS IoT Documentation but only found server-side examples (which expose AWS secrets/keys...)

Are there any good working examples or tutorials for using AWS IoT to send/receive messages via WebSockets/MQTT in the browser (e.g: authenticating with AWS Cognito)? Thanks!

like image 564
Jack Carlisle Avatar asked Feb 16 '16 17:02

Jack Carlisle


People also ask

Which protocol is used by AWS IoT core to send and receive the messages from the device?

AWS IoT Core uses TLS version 1.2 to encrypt all communication. Clients must also send the Server Name Indication (SNI) TLS extension .

How does Amazon Web Services used in IoT?

AWS IoT provides the cloud services that connect your IoT devices to other devices and AWS cloud services. AWS IoT provides device software that can help you integrate your IoT devices into AWS IoT-based solutions. If your devices can connect to AWS IoT, AWS IoT can connect them to the cloud services that AWS provides.

Which AWS IoT analytics component is used to collect messages and data from IoT devices?

Integrated with AWS IoT Core—AWS IoT Analytics is fully integrated with AWS IoT Core so it can receive messages from connected devices as they stream in.


Video Answer


3 Answers

Here's a sample that uses a cognito identity pool in JS to connect, publish and react to a subscription.

// Configure Cognito identity pool
AWS.config.region = 'us-east-1';
var credentials = new AWS.CognitoIdentityCredentials({
    IdentityPoolId: 'us-east-1:your identity pool guid',
});

// Getting AWS creds from Cognito is async, so we need to drive the rest of the mqtt client initialization in a callback
credentials.get(function(err) {
    if(err) {
        console.log(err);
        return;
    }
    var requestUrl = SigV4Utils.getSignedUrl('wss', 'data.iot.us-east-1.amazonaws.com', '/mqtt',
        'iotdevicegateway', 'us-east-1',
        credentials.accessKeyId, credentials.secretAccessKey, credentials.sessionToken);
    initClient(requestUrl);
});

function init() {
  // do setup stuff
}

// Connect the client, subscribe to the drawing topic, and publish a "hey I connected" message
function initClient(requestUrl) {
    var clientId = String(Math.random()).replace('.', '');
    var client = new Paho.MQTT.Client(requestUrl, clientId);
    var connectOptions = {
        onSuccess: function () {
            console.log('connected');

            // subscribe to the drawing
            client.subscribe("your/mqtt/topic");

            // publish a lifecycle event
            message = new Paho.MQTT.Message('{"id":"' + credentials.identityId + '"}');
            message.destinationName = 'your/mqtt/topic';
            console.log(message);
            client.send(message);
        },
        useSSL: true,
        timeout: 3,
        mqttVersion: 4,
        onFailure: function () {
            console.error('connect failed');
        }
    };
    client.connect(connectOptions);

    client.onMessageArrived = function (message) {

        try {
            console.log("msg arrived: " +  message.payloadString);
        } catch (e) {
            console.log("error! " + e);
        }

    };
}

Documentation for the credentials.get call, here

Remember to authorize your IAM role for subscribing / publishing as well. Here's a sample:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Connect"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "iot:Receive",
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "iot:Subscribe",
            "Resource": [
                "arn:aws:iot:us-east-1::your/mqtt/topic"
            ]
        },
        {
            "Effect": "Allow",
            "Action": "iot:Publish",
            "Resource": [
                "arn:aws:iot:us-east-1::your/mqtt/topic"
            ]
        }
    ]
}
like image 51
Kyle Roche Avatar answered Oct 06 '22 14:10

Kyle Roche


In case anyone else is looking for a solution: here's a tutorial that demonstrates via a simple chat app how to get real-time updates into a ReactJS front-end using Serverless and Websockets on AWS IOT. The source code of the tutorial is available on Github.

like image 2
Chris Avatar answered Oct 06 '22 13:10

Chris


It is hard to find good tutorials for integrating AWS IoT in browser.

Basically you need to have some authentication method (Facebook, Google, AWS Cognito, your own SSO service with SAML support) and then you need to do following steps:

  1. Configure Cognito User Pool or Federated Identity Pool with your authentication method.
  2. In browser you have to implement Extended Flow (https://aws.amazon.com/blogs/mobile/understanding-amazon-cognito-authentication-part-4-enhanced-flow/)
  3. You need to AttachPolicy in IoT for your user's Cognito identityId - it will be used as principal (it the same way as devices are using certificates).
  4. You need to create MQTT client using https://github.com/aws/aws-iot-device-sdk-js and providing your temporary accessKeyId, secretKey and sessionToken received from Extended Flow authentication.
like image 1
Maciej Dzikowicki Avatar answered Oct 06 '22 12:10

Maciej Dzikowicki