You are viewing an older revision! See the latest version
Websockets
Websocket Tutorial¶
As explained in this webpage, the Websocket protocol allows full-duplex, bi-directional communications between a server and clients.
To use Websocket communications, we need a server. We chose the Tornado Websocket server for our Internet of Things project. In this tutorial, I will present an example of how to get the Tornado Server running using websockets.....?
This tutorial is divided into two parts:
- A Hello World which uses Tornado
- A streaming example which uses Websocket4j.
1 - Hello World!¶
1.1 - Server side: Tornado¶
Warning
Tornado only runs on Unix-like platforms. If you are on Windows, choose another server.
Installation¶
- Download the sources, unpack and follow the readme. Example code:
$ wget http://github.com/downloads/facebook/tornado/tornado-2.0.tar.gz $ tar xvzf tornado-2.0.tar.gz $ cd tornado-2.0 $ python setup.py build $ sudo python setup.py install
For more information concerning the installation, you can go here
Code¶
You can find all the documentation you need here, but I will explain the main parts of the following basic Tornado Websocket server program.
The main idea is to define a class inherited from the WebSocketHandler class.
In this class, you can override the following methods:
- open
- on_message
- on_close
It's very simple; when a client and the server have performed the websocket handshake, the open method is called.
When a message is received from a client, the on_message method is called and if the connection is closed, the on_close method is called.
class WSHandler(tornado.websocket.WebSocketHandler): def open(self): print 'new connection' self.write_message("Hello World") def on_message(self, message): print 'message received %s' % message def on_close(self): print 'connection closed'
In our case:
- when a connection is opened, the server prints "new connection" and sends to the client "Hello World"
- when a message is received, the server prints this message
- when a connection is closed, the server prints"connection closed"
To complete the server program, we have to have at the beginning of the program an HTTPserver which will listen on a certain port.
application = tornado.web.Application([ (r'/ws', WSHandler), ]) if __name__ == "__main__": http_server = tornado.httpserver.HTTPServer(application) http_server.listen(8888) tornado.ioloop.IOLoop.instance().start()
An instance of tornado.web.Application is passed to the HTTPServer. When the server receives a request on the form:
var ws = new WebSocket("ws:localhost:8888/ws");, it will instantiate a WSHandler object. Note the "ws" at the end of the url. This will be useful for the client side implementation.
Finally, the whole program is:
import tornado.httpserver import tornado.websocket import tornado.ioloop import tornado.web class WSHandler(tornado.websocket.WebSocketHandler): def open(self): print 'new connection' self.write_message("Hello World") def on_message(self, message): print 'message received %s' % message def on_close(self): print 'connection closed' application = tornado.web.Application([ (r'/ws', WSHandler), ]) if __name__ == "__main__": http_server = tornado.httpserver.HTTPServer(application) http_server.listen(8888) tornado.ioloop.IOLoop.instance().start()
We save this in a /Documents/tornado as server.py for now.
1.2 - Client side¶
Warning
To follow this tutorial, you have to use a browser which supports websockets. I am using Chrome with no problems, and would recommend using it. If you have Firefox or Opera you will need to enable it. This is likely to be your problem if you are having one. You can do a test here to see if your browser supports websockets.
If you are not familiar with jQuery, it is recommended to get a basic understanding here). The main part of the simple Hello World:
$("#open").click(function(evt) { evt.preventDefault(); var host = $("#host").val(); var port = $("#port").val(); var uri = $("#uri").val(); ws = new WebSocket("ws://" + host + ":" + port + uri); ws.onmessage = function(evt) {alert("message received: " + evt.data)}; ws.onclose = function(evt) { alert("Connection close"); }; ws.onopen = function(evt) { $("#host").css("background", "#00ff00"); $("#port").css("background", "#00ff00"); $("#uri").css("background", "#00ff00"); }; });
- On this webpage, there are 3 fields: host, port and uri which have a red background at the beginning. You can see this at the bottom of this tutorial.
- When the user has filled these 3 fields, he can try to open a websocket connection by clicking the open button
As for the server, there are three methods: onopen, onmessage and onclose:
- If the connection is opened, we change the background of the 3 previous fields to green
- When we receive a message, we open a pop-up containing the message received
- When the connection is closed, we open a pop-up containing Connection close
Finally, the whole program for the client is:
<!doctype html> <html> <head> <title>WebSockets Hello World</title> <meta charset="utf-8" /> <style type="text/css"> body { text-align: center; min-width: 500px; } </style> <script src="http://code.jquery.com/jquery.min.js"></script> <script> $(document).ready(function () { var ws; $("#open").click(function(evt) { evt.preventDefault(); var host = $("#host").val(); var port = $("#port").val(); var uri = $("#uri").val(); ws = new WebSocket("ws://" + host + ":" + port + uri); ws.onmessage = function(evt) {alert("message received: " + evt.data)}; ws.onclose = function(evt) { alert("Connection close"); }; ws.onopen = function(evt) { $("#host").css("background", "#00ff00"); $("#port").css("background", "#00ff00"); $("#uri").css("background", "#00ff00"); }; }); }); </script> </head> <body> <h1>WebSockets Hello World</h1> <div> <label for="host">host:</label> <input type="text" id="host" value="localhost" style="background:#ff0000;"/><br /> <label for="port">port:</label> <input type="text" id="port" value="8888" style="background:#ff0000;"/><br /> <label for="uri">uri:</label> <input type="text" id="uri" value="/ws" style="background:#ff0000;"/><br /> <input type="submit" id="open" value="open" /> </div> </body> </html>
We save this as HelloWorld.html in the tornado directory.
1.3 - Demo¶
We start the server with the command:
$python server.py
And navigate to the Hello world test page.
Et Voilà! There is the pop-up on the client side containing Hello World and the backgrounds are green. On the server side, we see that a new connection has been opened.