Codestance
PHP, Linux and Marketing Playground Home Articles Resources Tips Tutorials
11/3/2014
a p p . l i s t e n ( o p t i o n s . p o r t ) t o r n a d o . i o l o o p . I O L o o p . i n s t a n c e ( ) . s t a r t ( )
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 . / s e r v e r . p yp o r t = 9 9 9 9 . Notice that we put decorator @ t o r n a d o . w e b . a s y n c h r o n o u sbefore get method, and this will prevent the R e q u e s t H a n d l e rfrom automatically calling s e l f . f i n i s h ( )eg. it means that server will hold connection until we execute finish. Now, lets go to our browser and write in address bar h t t p : / / l o c a l h o s t : 8 8 8 8 /or eventually click on this link. Because this is mostly w e b s o c k e toriented post we should continue with modifying/extending our simple example:
i m p o r tt o r n a d o . i o l o o p i m p o r tt o r n a d o . w e b i m p o r tt o r n a d o . w e b s o c k e t f r o mt o r n a d o . o p t i o n si m p o r td e f i n e ,o p t i o n s ,p a r s e _ c o m m a n d _ l i n e d e f i n e ( " p o r t " ,d e f a u l t = 8 8 8 8 ,h e l p = " r u no nt h eg i v e np o r t " ,t y p e = i n t ) #w eg o n n as t o r ec l i e n t si nd i c t i o n a r y . . c l i e n t s=d i c t ( ) c l a s sI n d e x H a n d l e r ( t o r n a d o . w e b . R e q u e s t H a n d l e r ) : @ t o r n a d o . w e b . a s y n c h r o n o u s d e fg e t ( s e l f ) : s e l f . w r i t e ( " T h i si sy o u rr e s p o n s e " ) s e l f . f i n i s h ( ) c l a s sW e b S o c k e t H a n d l e r ( t o r n a d o . w e b s o c k e t . W e b S o c k e t H a n d l e r ) : d e fo p e n ( s e l f ,* a r g s ) : s e l f . i d=s e l f . g e t _ a r g u m e n t ( " I d " ) s e l f . s t r e a m . s e t _ n o d e l a y ( T r u e ) c l i e n t s [ s e l f . i d ]={ " i d " :s e l f . i d ," o b j e c t " :s e l f } d e fo n _ m e s s a g e ( s e l f ,m e s s a g e ) : " " " w h e nw er e c e i v es o m em e s s a g ew ew a n ts o m em e s s a g eh a n d l e r . . f o rt h i se x a m p l eiw i l lj u s tp r i n tm e s s a g et oc o n s o l e " " " p r i n t" C l i e n t% sr e c e i v e dam e s s a g e:% s "%( s e l f . i d ,m e s s a g e ) d e fo n _ c l o s e ( s e l f ) : i fs e l f . i di nc l i e n t s : d e lc l i e n t s [ s e l f . i d ] a p p=t o r n a d o . w e b . A p p l i c a t i o n ( [ ( r ' / ' ,I n d e x H a n d l e r ) , ( r ' / ' ,W e b S o c k e t H a n d l e r ) , ] ) i f_ _ n a m e _ _= =' _ _ m a i n _ _ ' : p a r s e _ c o m m a n d _ l i n e ( ) a p p . l i s t e n ( o p t i o n s . p o r t ) t o r n a d o . i o l o o p . I O L o o p . i n s t a n c e ( ) . s t a r t ( )
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 didnt change route to w e b s o c k e thandler, they can both work on same route, but what is different is that when we want to connect to w e b s o c k e tthere is ws:// insted http:// and T o r n a d o knows how to handle those routes. For simple client we can use index handler with html rendering so lets change server.py a bit:
c l a s sI n d e x H a n d l e r ( t o r n a d o . w e b . R e q u e s t H a n d l e r ) : @ t o r n a d o . w e b . a s y n c h r o n o u s d e fg e t ( s e l f ) : # s e l f . w r i t e ( " T h i si sy o u rr e s p o n s e " ) s e l f . r e n d e r ( " i n d e x . h t m l " )
http://www.codestance.com/tutorials-archive/python-tornado-web-server-with-websockets-part-i-441 2/6
11/3/2014
# w ed o n ' tn e e ds e l f . f i n i s h ( )b e c a u s es e l f . r e n d e r ( )i sf a l l o w e db ys e l f . f i n i s h ( )i n s i d et o r n a d o # s e l f . f i n i s h ( )
And this is it.. we can now run our T o r n a d oserver 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 w e b s o c k e tand 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 w e b s o c k e tconnections 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 hotels TravelPony Boy shows his father photos of his mother in bed with another man YJNews
Boosting PHP Apps Performance with APC 1 comment XCache v3.0.1, More Performance For PHP Apps
2 comments
Nginx Proxy Websockets To Socket.IO 5 comments VIDEO: STACK Fitness Weekly: 2 Exercises You Should Nginx Download File Trigger 7 comments Do Every Day Stack
16 Comments
CodeStance
Share
Login
Favorite
3/6
Share
Favorite
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 chuphay
Reply Share
2 months ago
Hi... it almost seems to work... but when I click on Run Websocket, it says "connection is closed..."
1 Mia
Reply Share
9 days ago
Did you ever get around to writing part 2? I can't seem to find it... :)
Reply Share
Filip Curic
Mod
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
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
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
Hello, some FF versions by default disable websockets because possible vulnerabilities so you need to check what version 4/6 http://www.codestance.com/tutorials-archive/python-tornado-web-server-with-websockets-part-i-441
11/3/2014
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
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
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/...
Reply Share
alexvassel
Only the changing of the url does work. I use last version of FF and Chrome.
Reply Share
David Chamberlin
I just independently came to the same conclusion. I also changed the ws url to be contextual - maybe that's why the root URI didn't work? Changes to javascript are: var ws = new WebSocket("ws://" + window.location.host + "/ws?Id=123456789"); and to python: app = tornado.web.Application([ (r'/', IndexHandler), (r'/ws', WebSocketHandler), ])
Reply Share
B Budd
6 months ago
Is this a debugging exercise? I just started using tornado, but with the index.html exercise (the other two work fine) I'm getting a "RuntimeError("finish() called twice. May be caused by using async operations without the @asynchronous decorator". ? I am not really sure what may be happening.... somehow my decorator isn't being recognized? But I'm not seeing any import errors....
Reply Share
Filip Curic
Mod
Hello, thank you for your reply. Why this is happening is because self.render() is fallowed by self.finish() inside tornado so you can just remove self.finish(). It's my mistake, sorry.
Reply Share
B Budd
Ah! That's one thing I didn't try... thank you for your speedy reply, and for the basic info. Very helpful!
Subscribe
http://www.codestance.com/tutorials-archive/python-tornado-web-server-with-websockets-part-i-441
5/6
11/3/2014
http://www.codestance.com/tutorials-archive/python-tornado-web-server-with-websockets-part-i-441
6/6