Create standalone WebSocket server using tornado (Python)

Zahid Mak
3 min readAug 5, 2020

How to create a standalone WebSocket server using python and JavaScript.

Updating data on the web without refreshing the page is ideal for many applications. Here are few examples

  1. Real-time data graphs
  2. Election results
  3. Baseball scoreboard
  4. Chat app

Let’s dive in to see how this can be achieved with just few lines of code.

Prerequisite : tornado webserver. Install using following command in the cmd line

pip install tornado

OR

easy_install tornado

Step 1 : Create tornado server (server.py) that accepts the WebSocket connections from frontend, maintains connections and sends message to the frontend when required.

from tornado import httpserver
import tornado.websocket
import tornado.ioloop
import tornado.web

clients = []
userid = 0
class WSHandler(tornado.websocket.WebSocketHandler):

#Called when attempt is made for connection from client
def open(self):
obj = SessionManagement()
obj.createsession(self)#storing web socket object for further communication with client

#Called when client sends message
def on_message(self, message):
print 'message received %s' % userid

#Called when user refreshes or closes the page
def on_close(self):
obj = SessionManagement()
obj.deletesession(self)#deleting web socket object
print clients


class SessionManagement():
#Create session and stores into array
def createsession(self, obj):
userid = obj.get_argument("userid")
componentid = obj.get_argument("compid")
clients.append({"wsobj":obj, "userid":userid, "compid":componentid})

#Delete session from array when client refreshes the page or closes the page
def deletesession(self, obj):
for temp in clients:
if (obj==temp['wsobj']):
clients.remove(temp)


class PushToUser(tornado.web.RequestHandler):
def get(self):
userid = self.get_argument('userid')
compid = self.get_argument('compid')
message = self.get_argument('message')
for temp in clients:
if (temp['userid'] == userid and temp['compid'] == compid):
temp['wsobj'].write_message(message)

class PushToAll(tornado.web.RequestHandler):
def get(self):
message=self.get_argument('message')
for temp in clients:
temp['wsobj'].write_message(message)

application = tornado.web.Application([
(r'/ws', WSHandler),
(r'/push', PushToUser), #Ex. /push?userid=123&compid=123&message=hello
(r'/pushtoall', PushToAll), #Ex. /pushtoall?message="hello"
])

if __name__ == "__main__":
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(8888)
tornado.ioloop.IOLoop.instance().start()

Now, run server.py to start the server using

python server.py

Step 2 : Below is a frontend example that interacts with the server that you just created in step 1.

$(document).ready(function () {

var ws;
var host = '192.168.1.1'; //server IP
var port = '8888'; //server port
var uri = 'ws'; //websocket uri
ws = new WebSocket("ws://" + host + ":" + port + uri); //create web socket object

//Called when connection is established with server
ws.onopen = function (evt) {
alert("Connection open");
};

//Called when message is sent from server
ws.onmessage = function (evt) {
alert("message received: " + evt.data)
};

//Called when connection is closed from server
ws.onclose = function (evt) {
alert("Connection close");
};
});

Step 4: Sending message to client using REST

Originally published at https://blog.zahidmak.com on August 5, 2020.

--

--