Codestance Python Tornado Web Server with Websockets – Part I
Total Page:16
File Type:pdf, Size:1020Kb
11/3/2014 Python Tornado Web Server With WebSockets – Part I - Codestance Codestance PHP, Linux and Marketing Playground Home Articles Resources Tips Tutorials 2013 Middax | Rainbow Newsletter Me gusta 28 Tw eet 37 34 September 7, 2013 16 Comments Python Tornado Web Server With WebSockets – Part I Today i will show you and give you some input how to make a web and websocket server with Tornado, which is currently my favorite when i need “mockup” service so i can show it to someone. Anyway this article will mostly cover websockets then “standard” web. Tornado is a scalable, non-blocking web server and web application framework written in Python. It was developed for use by FriendFeed; the company was acquired by Facebook in 2009 and Tornado was open-sourced soon after. For installing Tornado on our machine we need Python first, anyhow, Python is installed on most Linux distros possibly because most Gnome and KDE apps using Python 2.5+ interpreters. For installing Python on Windows machine you can check it out here. After we have Python in place we should continue installing Tornado with easy_install tornado command which will install latest stable version. For running easy_install from Windows command prompt you can google a bit because this is covered on a lot of blogs. Also, i’m using Eclipse for Python development but you can use whatever you like. Now let’s get to the real, simple example. Let’s create a file called server.py : import tornado.ioloop import tornado.web from tornado.options import define, options, parse_command_line define("port", default=8888, help="run on the given port", type=int) class IndexHandler(tornado.web.RequestHandler): @tornado.web.asynchronous def get(self): self.write("This is your response") self.finish() app = tornado.web.Application([ (r'/', IndexHandler), ]) if __name__ == '__main__': parse_command_line() http://www.codestance.com/tutorials-archive/python-tornado-web-server-with-websockets-part-i-441 1/6 11/3/2014 Python Tornado Web Server With WebSockets – Part I - Codestance app.listen(options.port) tornado.ioloop.IOLoop.instance().start() We can see our example for simple response without rendering any html (this will be part II). Also, we can start this example with additional option port which is by default on 8888. For changing port we can start it by ./server.py --port=9999. Notice that we put decorator @tornado.web.asynchronous before get method, and this will prevent the RequestHandler from automatically calling self.finish() eg. it means that server will hold connection until we execute finish. Now, let’s go to our browser and write in address bar http://localhost:8888/ or eventually click on this link. Because this is mostly websocket oriented post we should continue with modifying/extending our simple example: import tornado.ioloop import tornado.web import tornado.websocket from tornado.options import define, options, parse_command_line define("port", default=8888, help="run on the given port", type=int) # we gonna store clients in dictionary.. clients = dict() class IndexHandler(tornado.web.RequestHandler): @tornado.web.asynchronous def get(self): self.write("This is your response") self.finish() class WebSocketHandler(tornado.websocket.WebSocketHandler): def open(self, *args): self.id = self.get_argument("Id") self.stream.set_nodelay(True) clients[self.id] = {"id": self.id, "object": self} def on_message(self, message): """ when we receive some message we want some message handler.. for this example i will just print message to console """ print "Client %s received a message : %s" % (self.id, message) def on_close(self): if self.id in clients: del clients[self.id] app = tornado.web.Application([ (r'/', IndexHandler), (r'/', WebSocketHandler), ]) if __name__ == '__main__': parse_command_line() app.listen(options.port) tornado.ioloop.IOLoop.instance().start() With upper extended simple example, we done nothing yet because we actually need some client to connect with. If we go again and refresh localhost link in our browser we should get same message as last time. Also we can see that we didn’t change route to websocket handler, they can both work on same route, but what is different is that when we want to connect to websocket there is ws:// insted http:// and Tornado knows how to handle those routes. For simple client we can use index handler with html rendering so let’s change server.py a bit: class IndexHandler(tornado.web.RequestHandler): @tornado.web.asynchronous def get(self): #self.write("This is your response") self.render("index.html") http://www.codestance.com/tutorials-archive/python-tornado-web-server-with-websockets-part-i-441 2/6 11/3/2014 Python Tornado Web Server With WebSockets – Part I - Codestance #we don't need self.finish() because self.render() is fallowed by self.finish() inside tornado #self.finish() Now we need index.html, so let’s create one.. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script type="text/javascript"> </script> </head> <body> <a href="javascript:WebSocketTest()">Run WebSocket</a> <div id="messages" style="height:200px;background:black;color:white;"></div> </body> </html> And this is it.. we can now run our Tornado server and ho to http://localhost:8888/ we will see index.html rendered in browser, also if we click on link “Run WebSocket” it should start connecting on our websocket and we should see messages in container. This is it for now, my next few post will hold few modification on server side and i will make small and simple client side library for handling websocket connections and messages. Happy Hacking! Tags: python, tornado, websockets Newer Older AROUND THE WEB ALSO ON CODESTANCE WHAT'S THIS? The Secret Way to Save Hundreds of Dollars on 5-star Boosting PHP Apps Performance with APC 1 comment hotels TravelPony XCache v3.0.1, More Performance For PHP Apps Boy shows his father photos of his mother in bed with 2 comments another man YJNews Nginx Proxy Websockets To Socket.IO 5 comments VIDEO: STACK Fitness Weekly: 2 Exercises You Should Do Every Day Stack Nginx Download File Trigger 7 comments 16 Comments CodeStance Login Sort by Best Share Favorite http://www.codestance.com/tutorials-archive/python-tornado-web-server-with-websockets-part-i-441 3/6 11/3/2014 Python Tornado Web Server With WebSockets – Part I - Codestance Sort by Best Share Favorite Join the discussion… Mike Morris • 3 months ago Thanks for this article. I think I have it rendering index.html but all I see is a large black box. Clicking on Run WebSocket seems to do nothing. What should I actually see? I have another python script reading OBDII from my truck and calculating 1-second MPG, and I'd like to send that value every time I get it to the browser. From my research it seems your tutorial has got me most of the way there. How do I send messages to the browser from my script in the same folder? Again, thanks for getting me this far! 3 • Reply • Share › chuphay • 2 months ago Hi... it almost seems to work... but when I click on Run Websocket, it says "connection is closed..." 1 • Reply • Share › Mia • 9 days ago Did you ever get around to writing part 2? I can't seem to find it... :) • Reply • Share › Filip Curic Mod Mia • a day ago Hi, thanks for asking, tho i'm bit busy last few months and it's really hard for me to get some time to make part two, writing application, testing and writing article. I hope i will have time this month :) • Reply • Share › Mia Filip Curic • a day ago Great! Actually part I was such a good start-off point, I figured out the rest after and went on to write a little 2d mmorpg (it was all just to practice learning websockets)! • Reply • Share › Filip Curic Mod Mia • 3 hours ago I'm glad you liked it, its shame because i don't have much of time because lot of work, but just for you to know, in next part i will focus mostly on client side and server side security for websocket. This will, i hope, give you some good ideas how to build secure ws/wss tasks and interfaces. Also, i plan to make this on python and java, java because i think its kind of better and more EE solution than python. Br, Filip • Reply • Share › Racky Senapati • 3 months ago When are you going to upload the second part - Python Tornado Web Server With WebSockets – Part II • Reply • Share › alexvassel • 6 months ago Hello. Having a problems: FF says "Firefox can't establish a connection to the server at ws://localhost:8888/?Id=123456789."; Chrome says "WebSocket connection to 'ws://localhost:8080/?Id=123456789' failed: Unexpected response code: 200". • Reply • Share › Filip Curic Mod alexvassel • 6 months ago Hello, http://www.codestance.csoomm/tuet oFriFa lsv-earrscihoivnes/p ybthyo dne-tfoarnualtd od-iswaeb-lsee rwveerb-wsiothc-kwebtss obcekectsa-upsaret- pi-o44s1sible vulnerabilities so you need to check what version 4/6 11/3/2014 Python Tornado Web Server With WebSockets – Part I - Codestance some FF versions by default disable websockets because possible vulnerabilities so you need to check what version do you use and try to enable them. • Reply • Share › alexvassel Filip Curic • 6 months ago Figured out this thing. IndexHandler and WebSocketHandler have the same url. So ws request hits IndexHandler that returns normal 200 response. Changing WebSocketHandler url makes the trick. • Reply • Share › Filip Curic Mod alexvassel • 6 months ago Url should not be the problem, instead of new Websocket(..) you can try using MozWebSocket(..) so you can actually check first if its Mozilla then others. You can also check browser compatibility from Mozilla site : https://developer.mozilla.org/..