Skip to content

Instantly share code, notes, and snippets.

@stesie
Created April 1, 2016 22:28
Show Gist options
  • Star 40 You must be signed in to star a gist
  • Fork 15 You must be signed in to fork a gist
  • Save stesie/dabc9236ef8fc4123609f9d81df6ccd8 to your computer and use it in GitHub Desktop.
Save stesie/dabc9236ef8fc4123609f9d81df6ccd8 to your computer and use it in GitHub Desktop.
AWS IoT-based serverless JS-Webapp Pub/Sub demo
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>AWS IoT Pub/Sub Demo</title>
</head>
<body>
<h1>AWS IoT Pub/Sub Demo</h1>
<form>
<button type="button" id="connect">connect!</button>
<div>
<label for="message">Message to send:</label>
<input type="text" id="message" value="Hello world!" />
<button type="button" id="send">send!</button>
</div>
</form>
<h2>Log Output</h2>
<ul id="the-log"></ul>
<script src="bundle.js"></script>
</body>
</html>
"use strict";
import v4 from 'aws-signature-v4';
import crypto from 'crypto';
import MqttClient from './node_modules/mqtt/lib/client';
import websocket from 'websocket-stream';
const AWS_ACCESS_KEY = 'AKIAJG2AAE7GEWVAVO4A';
const AWS_SECRET_ACCESS_KEY = '';
const AWS_IOT_ENDPOINT_HOST = 'A3XL158HTUQU5.iot.us-east-1.amazonaws.com';
const MQTT_TOPIC = '/test/iot-pubsub-demo';
var client;
addLogEntry('Hello World!');
document.getElementById('connect').addEventListener('click', () => {
client = new MqttClient(() => {
var url = v4.createPresignedURL(
'GET',
AWS_IOT_ENDPOINT_HOST.toLowerCase(),
'/mqtt',
'iotdevicegateway',
crypto.createHash('sha256').update('', 'utf8').digest('hex'),
{
'key': AWS_ACCESS_KEY,
'secret': AWS_SECRET_ACCESS_KEY,
'protocol': 'wss',
'expires': 15
}
);
addLogEntry('Connecting to URL: ' + url);
return websocket(url, [ 'mqttv3.1' ]);
});
client.on('connect', () => {
addLogEntry('Successfully connected to AWS IoT Broker! :-)');
client.subscribe(MQTT_TOPIC);
});
client.on('close', () => {
addLogEntry('Failed to connect :-(');
client.end(); // don't reconnect
client = undefined;
});
client.on('message', (topic, message) => {
addLogEntry('Incoming message: ' + message.toString());
});
});
document.getElementById('send').addEventListener('click', () => {
const message = document.getElementById('message').value;
addLogEntry('Outgoing message: ' + message);
client.publish(MQTT_TOPIC, message);
});
function addLogEntry(info) {
const newLogEntry = document.createElement('li');
newLogEntry.textContent = '[' + (new Date()).toTimeString().slice(0, 8) + '] ' + info;
const theLog = document.getElementById('the-log');
theLog.insertBefore(newLogEntry, theLog.firstChild);
}
{
"name": "iot-pubsub-demo",
"version": "0.0.1",
"description": "AWS IoT Pub/Sub Demo",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Stefan Siegl <stesie@brokenpipe.de>",
"license": "MIT",
"devDependencies": {
"babel-core": "^6.7.4",
"babel-loader": "^6.2.4",
"babel-preset-es2015": "^6.6.0",
"webpack": "^1.12.14",
"webpack-dev-server": "^1.14.1"
},
"dependencies": {
"aws-signature-v4": "^1.0.1",
"mqtt": "^1.7.4",
"websocket-stream": "^3.1.0"
}
}
var path = require('path');
module.exports = {
entry: './main.js',
output: {
path: __dirname,
filename: 'bundle.js'
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel-loader',
query: {
presets: ['es2015']
}
}
]
}
};
@rickyk586
Copy link

to get the client, you can just use:

import mqtt from 'mqtt';
let client = mqtt.connect(signedUrl);

no need for websocket-stream

also, instead of crypto.createHash('sha256').update('', 'utf8').digest('hex') you can just use 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'

@lakshmantgld
Copy link

I get 403 error. Precisely, this is the error am getting: WebSocket connection to 'wss://' failed: Error during WebSocket handshake: Unexpected response code: 403

@cloudle
Copy link

cloudle commented Mar 29, 2017

Same stuff for me, 403 error - anyone have updates?

@ruisalgado
Copy link

if you get a 403 you probably need to specify the region in the options hash passed to v4.createPresignedURL. It defaults to us-east-1.

@kimi75
Copy link

kimi75 commented May 11, 2018

+1

@rnukala
Copy link

rnukala commented May 25, 2018

thank you, this the only thing which worked for me

@jenishj-crest
Copy link

Getting error failed: Error during WebSocket handshake: Unexpected response code: 403

@sg-dev1512
Copy link

The reason for the 403 is a typo in main.js.

var url = v4.createPresignedURL(
'GET',
AWS_IOT_ENDPOINT_HOST.toLowerCase(),
'/mqtt',
'iotdevicegateway',
// ---> typo, the hash is computed inside createPresignedURL()
// this parameter should be whatever payload that we want to send with the http request; setting to empty ("") in this case
// crypto.createHash('sha256').update('', 'utf8').digest('hex'),
"",
{
'key': AWS_ACCESS_KEY,
'secret': AWS_SECRET_ACCESS_KEY,
'protocol': 'wss',
'expires': 15
}
);

@thiwanka-aux
Copy link

Getting error failed: Error during WebSocket handshake: Unexpected response code: 403

@dpalharini
Copy link

This type of authentication for IoT Core still working?

I could not make it connect properly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment