Anda di halaman 1dari 6

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 w e b s o c k e tserver with T o r n a d o , which is currently my favorite when i need mockup service so i can show it to someone. Anyway this article will mostly cover w e b s o c k e t sthen 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 T o r n a d oon our machine we need P y t h o nfirst, anyhow, P y t h o nis installed on most L i n u xdistros possibly because most Gnome and KDE apps using Python 2.5+ interpreters. For installing P y t h o non Windows machine you can check it out here. After we have P y t h o nin place we should continue installing Tornado with e a s y _ i n s t a l lt o r n a d ocommand 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, im using Eclipse for P y t h o ndevelopment but you can use whatever you like. Now lets get to the real, simple example. Lets create a file called server.py :
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 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 ) 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 ( ) 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 ) , ] ) 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 ( )
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

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

Python Tornado Web Server With WebSockets Part I - Codestance

# 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 ( )

Now we need index.html, so lets create one..


< ! D O C T Y P Eh t m l > < h t m l > < h e a d > < m e t ac h a r s e t = " u t f 8 " > < s c r i p tt y p e = " t e x t / j a v a s c r i p t " > v a rm e s s a g e C o n t a i n e r=d o c u m e n t . g e t E l e m e n t B y I d ( " m e s s a g e s " ) ; f u n c t i o nW e b S o c k e t T e s t ( ){ i f( " W e b S o c k e t "i nw i n d o w ){ m e s s a g e C o n t a i n e r . i n n e r H T M L=" W e b S o c k e ti ss u p p o r t e db yy o u rB r o w s e r ! " ; v a rw s=n e wW e b S o c k e t ( " w s : / / l o c a l h o s t : 8 8 8 8 / ? I d = 1 2 3 4 5 6 7 8 9 " ) ; w s . o n o p e n=f u n c t i o n ( ){ w s . s e n d ( " M e s s a g et os e n d " ) ; } ; w s . o n m e s s a g e=f u n c t i o n( e v t ){ v a rr e c e i v e d _ m s g=e v t . d a t a ; m e s s a g e C o n t a i n e r . i n n e r H T M L=" M e s s a g ei sr e c e i v e d . . . " ; } ; w s . o n c l o s e=f u n c t i o n ( ){ m e s s a g e C o n t a i n e r . i n n e r H T M L=" C o n n e c t i o ni sc l o s e d . . . " ; } ; }e l s e{ m e s s a g e C o n t a i n e r . i n n e r H T M L=" W e b S o c k e tN O Ts u p p o r t e db yy o u rB r o w s e r ! " ; } } < / s c r i p t > < / h e a d > < b o d y > < ah r e f = " j a v a s c r i p t : W e b S o c k e t T e s t ( ) " > R u nW e b S o c k e t < / a > < d i vi d = " m e s s a g e s "s t y l e = " h e i g h t : 2 0 0 p x ; b a c k g r o u n d : b l a c k ; c o l o r : w h i t e ; " > < / d i v > < / b o d y > < / h t m l >

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

Sort by Best http://www.codestance.com/tutorials-archive/python-tornado-web-server-with-websockets-part-i-441

11/3/2014 Sort by Best

Python Tornado Web Server With WebSockets Part I - Codestance

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 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

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, 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

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/...
Reply Share

alexvassel

Filip Curic 6 months ago

Only the changing of the url does work. I use last version of FF and Chrome.
Reply Share

David Chamberlin

alexvassel 3 months ago

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

B Budd 6 months ago

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

Filip Curic 6 months ago


Reply Share

Ah! That's one thing I didn't try... thank you for your speedy reply, and for the basic info. Very helpful!

Subscribe

Add Disqus to your site

http://www.codestance.com/tutorials-archive/python-tornado-web-server-with-websockets-part-i-441

5/6

11/3/2014

Python Tornado Web Server With WebSockets Part I - Codestance

http://www.codestance.com/tutorials-archive/python-tornado-web-server-with-websockets-part-i-441

6/6

Anda mungkin juga menyukai