280 likes | 295 Vues
Learn about client-side AJAX with JavaScript, Websockets, and MQTT for IoT. Explore examples and hands-on exercises.
E N D
95-733 Internet of ThingsWeek Three Carnegie Mellon Heinz College
Week Three • Learning objectives: • Understand client side AJAX using JavaScript • Introduce client side and server side Websockets • Introduce Websockets and MQTT for IOT Carnegie Mellon Heinz College
Recall the example from IBM Shopping Cart See article by Philip McCarthy on Ajax at: http://www.ibm.com/developerworks/library/j-ajax1/ Last week we looked at the server side code. This week, we will look at the Javascript executing in the browser. Carnegie Mellon Heinz College
Main Features Axis1.js (1) /* * Returns an new XMLHttpRequest object, or false if the browser * doesn't support it */ function newXMLHttpRequest() { var xmlreq = false; // Create XMLHttpRequest object in non-Microsoft browsers if (window.XMLHttpRequest) { xmlreq = new XMLHttpRequest(); } Carnegie Mellon Heinz College
Main Features Axis1.js (2) else if (window.ActiveXObject) { try { // Try to create XMLHttpRequest in later versions of Internet Explorer xmlreq = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e1) { // Failed to create required ActiveXObject try { // Try version supported by older versions of Internet Explorer xmlreq = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e2) { // Unable to create an XMLHttpRequest by any means xmlreq = false; } } } Carnegie Mellon Heinz College
Main Features Axis1.js (3) /* Returns a function that waits for the specified XMLHttpRequest to complete, then passes it XML response to the given handler function. req - The XMLHttpRequest whose state is changing responseXmlHandler - Function to pass the XML response to */ function getReadyStateHandler(req, responseXmlHandler) { Carnegie Mellon Heinz College
Main Features Axis1.js (4) // Return an anonymous function that listens to the // XMLHttpRequest instance return function () { // If the request's status is "complete" if (req.readyState == 4) { // Check that we received a successful response from the server if (req.status == 200) { // Pass the XML payload of the response to the handler // function. responseXmlHandler(req.responseXML); } else { // An HTTP problem has occurred alert("HTTP error "+req.status+": "+req.statusText); }}}} Carnegie Mellon Heinz College
Main Features Cart.js (1) // Timestamp of cart that page was last updated with var lastCartUpdate = 0; // Adds the specified item to the shopping cart, via Ajax call // itemCode - product code of the item to add function addToCart(itemCode) { var req = newXMLHttpRequest(); req.onreadystatechange = getReadyStateHandler(req, updateCart); req.open("POST", "cart.do", true); req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); req.send("action=add&item="+itemCode); } Establish handler and pack up and send the request. Carnegie Mellon Heinz College
Main Features Cart.js (2) /* * Update shopping-cart area of page to reflect contents of cart * described in XML document. */ function updateCart(cartXML) { var cart = cartXML.getElementsByTagName("cart")[0]; var generated = cart.getAttribute("generated"); if (generated > lastCartUpdate) { lastCartUpdate = generated; var contents = document.getElementById("contents"); contents.innerHTML = ""; Carnegie Mellon Heinz College
Main Features Cart.js (3) var items = cart.getElementsByTagName("item"); for (var I = 0 ; I < items.length ; I++) { var item = items[I]; var name = item.getElementsByTagName("name")[0].firstChild.nodeValue; var quantity = item.getElementsByTagName("quantity")[0].firstChild.nodeValue; var listItem = document.createElement("li"); listItem.appendChild(document.createTextNode(name+" x "+quantity)); contents.appendChild(listItem); } } document.getElementById("total").innerHTML = cart.getAttribute("total"); } Carnegie Mellon Heinz College
Shopping Cart Interaction post addToCart(itemCode) XML XMLHTTPRequest UpdateCart reads XML writes HTML Anonymous handler - Executed on state change. - req.responseXML points to the root of the XML - calls updateCart HTML Button Carnegie Mellon Heinz College
Main Features Cart.js (4) The handler is reading data with the following format: <?xml version="1.0"?> <cart generated="1200367057873" total="$19.99"> <item code="str001"> <name>String</name> <quantity>1</quantity> </item> </cart> Carnegie Mellon Heinz College
XML Or JSON ? (1) <Person firstName="John" lastName="Smith"> <Address> <streetAddress>21 2nd Street</streetAddress> <city>New York</city> <state>NY</state> <postalCode>10021</postalCode> </Address> <phoneNumber type="home"> 212 555-1234 </phoneNumber> <phoneNumber type="fax"> 646 555-4567 </phoneNumber> </Person> From Wikipedia.org Carnegie Mellon Heinz College
XML Or JSON ? (2) { "firstName": "John", "lastName": "Smith", "address": { "streetAddress": "21 2nd Street", "city": "New York", "state": "NY", "postalCode": "10021" }, "phoneNumbers": [ { "type": "home", "number": "212 555-1234" }, { "type": "fax", "number": "646 555-4567" } ] } If this text is in the variable coolText, then we can create a JavaScript object with the line of code: var x = eval("(" + coolText + ")"); and access the data with x.phoneNumbers[0]. Better to use JSON.parse(text) and JSON.stringify(obj). From Wikipedia.org Carnegie Mellon Heinz College
Which To Use? Both formats are textual and are coarse grained. JSON has some advantages over XML: JSON messages are smaller and therefore faster. No namespaces JSON is simpler and simple is good. JSON has become very popular XML has some advantages over JSON: Namespaces Languages adopted by many industries XSLT can be used to transform a response into an appropriate format. XML Signature and XML Encryption not available for JSON. Carnegie Mellon Heinz College
jQuery AJAX Example <!DOCTYPE html> <html> <head> <script src="jquery.js"></script> <script> $(document).ready(function(){ $("button").click(function(){ $("div").load('test1.txt'); }); }); </script> </head> <body> <div><h2>Let AJAX change this text</h2></div> <button>Change Content</button> </body> </html> The syntax is: $(selector).action() A $ sign to define/access jQuery A (selector) to "query (or find)" HTML elements A jQuery action() to be performed on the element(s) Document ready before running jQuery. http://www.w3schools.com/jquery/tryit.asp?filename=tryjquery_ajax_load Carnegie Mellon Heinz College
Dojo Ajax Example dojo.io.bind ( { url : “getCityState.php?zip=“ + zip, load: function( type, data, evt ) { var place = data.split(‘, ’); if(dojo.byID(“city”).value = “” dojo.byID(“city”).value = place[0]; if(dojo.byID(“state”).value = “” dojo.byID(“state”).value = place[1]; }, error: function(type, data, evt ) { alert(“Error in request, returned data:”+data); }, method: “GET”, mimetype: “text/plain” } ); Note the use of JS object to describe an AJAX call. From Pg. 422 Of Sebesta Carnegie Mellon Heinz College
Web Sockets Javascript API defined by W3C – Available on many browsers. Java client side API and server side API - see JSR 356 part of JEE 7 From Oracle Carnegie Mellon Heinz College
Web Sockets Lifecycle Events The typical lifecycle event of a WebSocket interaction goes as follows: One peer (a client) initiates the connection by sending an HTTP handshake request. The other peer (the server) replies with a handshake response. The connection is established. From now on, the connection is completely symmetrical. Both peers send and receive messages. One of the peers closes the connection. Most of the WebSocket lifecycle events can be mapped to Java methods, both in the annotation-driven and interface-driven approaches. Note that Web Sockets don’t describe the conversation that will take place. This is left to the layer above the web socket layer. From Oracle Carnegie Mellon Heinz College
Client side Web Sockets (1) // Establish the socket in Javascript: // Open a new WebSocket connection (ws), use wss for secure // connections over SSL. var wsUri = "ws://" + document.location.host + document.location.pathname + "whiteboardendpoint"; var websocket = new WebSocket(wsUri); Carnegie Mellon Heinz College
Client side Web Sockets (2) // Prepare to send and receive data. // A callback function is invoked for each new message from // the server websocket.onmessage = function(evt) { onMessage(evt) }; function onMessage(evt) { // Called for us when a message drawImageText(evt.data); // arrives. } function sendText(json) { // We call this when we want. websocket.send(json); } Carnegie Mellon Heinz College
Server side Web Sockets in Java (1) // The Decode is used for messages arriving from the peer. // The Encoder is used for messages being sent to the peer. @ServerEndpoint(value="/whiteboardendpoint", encoders = {FigureEncoder.class}, decoders = {FigureDecoder.class}) public class MyWhiteboard { // create a synchronized (thread safe) set of sessions in a hashset // names this collection peers private static Set<Session> peers = Collections.synchronizedSet(new HashSet<Session>()); Carnegie Mellon Heinz College
Server side Web Sockets in Java (2) // when a message arrives from the decoder, call the peers @OnMessage public void broadcastFigure(Figure figure, Session session) throws IOException, EncodeException { System.out.println("broadcastFigure: " + figure); // for each peer in the peers set of sessions for (Session peer : peers) { if (!peer.equals(session)) { // this is not being sent back to the caller peer.getBasicRemote().sendObject(figure); } } } // when sendObject is called, the Encoder is executed. Carnegie Mellon Heinz College
Decoder Goes on Arrival public class FigureDecoder implements Decoder.Text<Figure> { @Overridepublic Figure decode(String string) throws DecodeException { System.out.println("decoding: " + string); JsonObject jsonObject = Json.createReader( new StringReader(string)).readObject();return new Figure(jsonObject); } Decode a message and create a Java object. The Java object involved is of type Figure. So, from Text we get a Figure. Carnegie Mellon Heinz College
Encoder Goes Before Sending to Peer public class FigureEncoder implements Encoder.Text<Figure> { @Overridepublic String encode(Figure figure) throws EncodeException { System.out.println("Encoding ");return figure.getJson().toString(); } Encode a Java object. The Java object involved is of type Figure. So, from Figure we encode to Text. Carnegie Mellon Heinz College
Sending JSON data // Microsoft example: Send text to all users through the server function sendText() { // Construct a msg object containing the data the server // needs to process the message from the chat client. var msg = { type: "message", text: document.getElementById("text").value, id: clientID, date: Date.now() }; // Send the msg object as a JSON-formatted string. exampleSocket.send(JSON.stringify(msg)); // Blank the text input element, ready to receive the next line of text // from the user. document.getElementById("text").value = ""; } Carnegie Mellon Heinz College
WebSockets using JEE A message arrives from a peer – it needs to be decoded into a Java object. Then, it may be processed by the Java code. A message is being sent to a peer. It needs to be encoded before being placed on the wire. Image from http://www.mastertheboss.com/javaee/websockets/websockets-using-encoders-and-decoders Carnegie Mellon Heinz College
Web Sockets and IoT device MQTT Broker subscriber publish device MQ Telemetry Transport (MQTT) telemetry = remote measurements. MQTT runs on top of TCP. Can be carried by web sockets for, e.g., real time dashboards. MQTT is an established publish subscribe messaging protocol for intermittent networks. With MQTT over WebSockets, a browser can become an MQTT device – subscribing to or publishing messages. MQTT-SN for sensor networks. No TCP or IP. Can use e.g. ZigBee or BlueTooth. Carnegie Mellon Heinz College