Interaction patterns and protocols:
Request/Response
Outline
Request-Response
HTTP Polling
Example
Continuous HTTP Polling
Example
Shortcomings of Request-Response
Physical/Virtual Mashups
Example: Yahoo Weather service, HTML, JavaScript, Node.js
2
An example of HTTP Polling
http://localhost:8686/temperature
Temperature
URL to request the server Sensor
response
Your HTTP Client Raspberry PI
Application
http://localhost:8686 Light
Sensor
http://localhost:8686/light
Server
(implemented using Node.js)
3
Code is available as httpserver.js
Code Walkthrough
var http = require("http"); Creating an HTTP
var port = 8686;
server using node.js
function randomInt (low, high) { is easy
return Math.floor(Math.random() * (high - low) + low);
}
http.createServer(function(req , res){
console.log('New incoming client request for ' + req.url);
res.writeHeader(200, {'Content-Type': 'application/json'});
switch(req.url) {
case '/temperature': Returning data in JSON format
res.write('{"temperature" :' + randomInt(1, 40) + '}');
break;
case '/light':
res.write('{"light" :' + randomInt(1, 100) + '}');
break;
default :
res.write('{"Temperature Sensor" : "/temperature"}');
res.write('{"Light Sensor" : "/light" }');
break;
}
res.end();
}).listen(8686);
console.log('Server listening on http://localhost:' + port);
4
Code is available as httpserver.js
Code Walkthrough
var http = require("http");
var port = 8686;
function randomInt (low, high) {
return Math.floor(Math.random() * (high - low) + low);
}
http.createServer(function(req , res){
console.log('New incoming client request for ' + req.url);
res.writeHeader(200, {'Content-Type': 'application/json'});
switch(req.url) {
case '/temperature':
res.write('{"temperature" :' + randomInt(1, 40) + '}');
break; Accessing temperature
value from URL
case '/light': http://localhost:8686/temperature
res.write('{"light" :' + randomInt(1, 100) + '}');
break;
default :
res.write('{"Temperature Sensor" : "/temperature"}');
Wrapping data into JSON and
res.write('{"Light Sensor" : "/light" }'); sending response back
break;
}
res.end();
}).listen(8686);
console.log('Server listening on http://localhost:' + port);
Architecture : Polling sever continuously &
displaying readings on browser
http://localhost:8686/temperature
Polling the
server with URL
Response as JSON Temperature
Sensor
Your HTTP Client Raspberry PI
Application http://localhost:8686/temperature
Server
(implemented using Node.js)
6
Code is available as pollingserver.js
Code walkthrough : Server
var http = require('http'); var fs = require('fs'); var port = 8686;
function randomInt(low, high) {
return Math.floor(Math.random() * (high - low) + low);
}
function send404Response(response){
response.writeHead(404,{"Content-Type": "text/plain" }); Return the Error response
response.write("Error 404: Page not found"); in case of invalid request
response.end();
}
http.createServer(function(req, res) {
console.log('New incoming client request for ' + req.url);
res.writeHeader(200, { 'Content-Type' : 'application/json'});
switch (req.url) {
case '/temperature':
res.write('{"value" :' + randomInt(1, 40) + '}');
res.end(); break;
default: Client request for data
send404Response(res); would server here
}
}).listen(port); console.log('Server listening on http://localhost:' + port);
7
Code is available as pollingclient.html
Code walkthrough: client Google Library for Line chart
$(document).ready(function () {
var maxDataPoints = 10;
var chart = new google.visualization.LineChart($('#chart')[0]);
var data = google.visualization.arrayToDataTable([
['Time', 'Temperature'],
[getTime(), 0]
]);
var options = {
title: 'Temperature',
hAxis: {title: 'Time', titleTextStyle: {color: '#333'}},
vAxis: {title: 'TempValue', minValue: 0, titleTextStyle: {color: '#333'}},
};
function addDataPoint(dataPoint) {
… … …
chart.draw(data, options);
}
function getTime() { … }}
function doPoll() {
$.getJSON('http://localhost:8686/temperature',
function (result) {
addDataPoint(result);
setTimeout(doPoll, 1000);
}); }
doPoll();
});
8 Polling to server every 1 second
Basic Polling
Client Raspberry PI Sensor
Request
Response
Event
Delay
Request
Response
Request
Response
9
Shortcomings with HTTP Polling
The problems are associated with:
Scale: The polling generates a great number of HTTP calls and
a great part of these calls are void. Since reducing the number
of HTTP calls are void. Since the reducing the number of HTTP
calls to the minimum is key in scaling the web applications, this
model does not scale well when the number of clients
increases.
Battery: A large amount of HTTP calls is a problem for a
battery-powered devices, where only the strict data should be
sent.
10
How about the server inform a client whenever
there is a change?
11
Physical-virtual Mashup
Mashup is an application that gets data from various
sources, processes it and combines it to create a new application.
Our demo example demonstrates the following:
• Take local temperature data from Yahoo! Weather Server.
• Fetch temperature data from simulated temperature sensor.
• Compare the both temperature and publish the result to the LCD screen
attached to PI that has been exposed as web service.
12
Code is available as physicalvirtualclient.html, physicalvirtualserver.js
Architecture
1
Yahoo Weather
Service
Request to local 2
temperature sensor
3 http://localhost:8686/temperature
JSON response
Your HTTP Client Temperature
Raspberry PI Sensor
Application
Send the temperature difference to an
4 LCD screen
5 http://devices.webofthings.io/pi/actuators/display/content
LCD
13 http://devices.webofthings.io/camera/sensors/picture/
Camera
Code is available as physicalvirtualclient.html, physicalvirtualserver.js
Code walkthrough
$(document).ready(function () {
var rootUrl = 'http://devices.webofthings.io';
function mashup(name, location) {//#A
$.getJSON(prepareYahooWeatherUrl(location), function (yahooResult) {
1
var localTemp = yahooResult.query.results.channel.item.condition.temp;
console.log('Local @ ' + location + ': ' + localTemp);
$.getJSON('http://localhost:8686/temperature’, function (piResult) {
2 var piTemp = piResult.temperature;
console.log('Pi @ London: ' + piTemp);
publishMessage(prepareMessage(name, location, localTemp, piTemp));
});
});
}
function prepareYahooWeatherUrl(location) { 1
return "https://query.yahooapis.com/v1/public/yql?q=select item from
weather.forecast where woeid in (select woeid from geo.places(1) where text='" + location +
"') and u='c'&format=json";
}
mashup(‘IoTCouse', ‘Tokyo, Japan');
14
});
Code is available as physicalvirtualclient.html, physicalvirtualserver.js
Code walkthrough
$(document).ready(function () {
var rootUrl = 'http://devices.webofthings.io';
function mashup(name, location)
publishMessage(prepareMessage(name, location, localTemp, piTemp));
});
});
}
function prepareMessage(name, location, localTemp, piTemp) {
var diff = localTemp - piTemp;
var qualifier = ' > '; 3
if (diff < 0) {
qualifier = ' < ';
}
var result = name + '@' + location + qualifier + Math.abs(diff);
return result;
}
mashup(‘IoT Course', ‘Tokyo, Japan');
});
15
Code is available as physicalvirtualclient.html, physicalvirtualserver.js
Code walkthrough
$(document).ready(function () {
var rootUrl = 'http://devices.webofthings.io';
function publishMessage(message) {
var payload = {"value": message};
$.ajax(rootUrl + '/pi/actuators/display/content', {
data: JSON.stringify(payload),
contentType: 'application/json',
type: 'POST', 4
success: function (data) {
$('#message').html('Published: ' + message);
console.log('Will take a picture in ' + ++data.displayInSeconds + ' seconds...');
setTimeout(function () {takePicture();
}, data.displayInSeconds * 1000); }
});
}
function takePicture() {
$.ajax({
type: 'GET',
url: rootUrl + '/camera/sensors/picture/',
dataType: 'json',
success: function (data) { 5
console.log(data);
$('#camImg').attr('src', data.value);
},
error: function (err) {
console.log(err);
}
});
}
16
mashup(‘IoT Course', ‘Tokyo, Japan');
});
Questions??
17 Image credit to slide : Internet of Things, we are social