KEMBAR78
Comet web applications with Python, Django & Orbited | PDF
Comet web applications with Python,
                 Django & Orbited


@ PyCon Italia Qu4ttro       Massimo Scamarcia
http://www.pycon.it/           http://www.webright.it/




                        
Comet web applications with Python,
        Django & Orbited




How to push real-time data to
      web browsers?



              
Comet web applications with Python,
                  Django & Orbited


AJAX Polling
   Client: sends AJAX request.
   Server:
       Data available: sends response.
       No data: sends empty response.
   Client: sends AJAX request again.




                        
Comet web applications with Python,
              Django & Orbited




Latency, bandwidth, memory usage and scaling issues!


                    
Comet web applications with Python,
         Django & Orbited




      What about Comet?



              
Comet web applications with Python,
                Django & Orbited




Not a technology in itself
 Long Polling, IFRAME stream, HTMLFile, XHR Streaming, HTML5 SSE




                        
Comet web applications with Python,
         Django & Orbited




          It's an hack!
       Still waiting for an unanimous way to do it.




                   
Comet web applications with Python,
                      Django & Orbited


Long Polling
   Client: sends AJAX request.
   Server: holds the request.
              Data available: sends response.
              Timeout reached: empty response.
   Client: sends AJAX request again.




                            
Comet web applications with Python,
                        Django & Orbited

Http Push (HTTP Streaming*)
   Client: sends HTTP request.
   Server: doesn't terminate the connection.
   Server: sends data when available.
   Connection closed:
                Data is queued.
                Client reconnects.

    [*] http://ajaxpatterns.org/HTTP_Streaming



                               
Comet web applications with Python,
                    Django & Orbited
   HTTP Push: better for heavily-loaded apps.
       Not cross-browser.
   Long Polling: cross-browser and easy.
       Bandwidth usage.
       Too many connections.
   Async Python servers* are better for both:
       Twisted, Tornado, Dieselweb, Eventlet, Concurrence,
         Circuits, Gevent, Cogen.

[*] http://nichol.as/asynchronous-servers-in-python


                             
Comet web applications with Python,
         Django & Orbited




      What about Orbited?



              
Comet web applications with Python,
        Django & Orbited




        He's here to solve problems!

                
Comet web applications with Python,
                     Django & Orbited


   Based on Twisted.
   STOMP* (ActiveMQ, RabbitMQ), IRC and XMPP
     protocol support.
   Ready-to-use and cross-browser JavaScript client
     code.
   You don't have to reinvent the wheel!

[*] http://stomp.codehaus.org/



                             
Comet web applications with Python,
           Django & Orbited




Using Django and Orbited
        Example app developed for PyConIt4:
      http://pyconquiz.webright.it/




                   
Comet web applications with Python,
                  Django & Orbited

Django is used for:
   Application logic.
   Template rendering.
   User auth and registration.
   Handling AJAX requests.
   Sending messages to STOMP server.

                             ...Orbited and jQuery do the rest!




                          
Comet web applications with Python,
        Django & Orbited




              
Comet web applications with Python,
                    Django & Orbited

orbited.cfg                    settings.py
 [global]                       # Available using context
 #reactor=select                # processor or templatetag
 #reactor=kqueue
 reactor = epoll                ORBITED_HOST = 'localhost'
 proxy.enabled = 1              ORBITED_PORT = 8080
 session.ping_interval = 300
                                STOMP_HOST = 'localhost'
 [listen]                       STOMP_PORT = 61613
 http://localhost:8080
 stomp://localhost:61613

 [access]
 * -> localhost:61613



                            
Comet web applications with Python,
                  Django & Orbited

Django base template (<head /> tag)
 <script>document.domain = document.domain;</script>
 <script src="{{ ORBITED_MEDIA_URL }}Orbited.js"></script>
 <script type="text/javascript">
 Orbited.settings.port = {{ ORBITED_PORT }};
 Orbited.settings.hostname = "{{ ORBITED_HOST }}";
 Orbited.settings.streaming = true;

 TCPSocket = Orbited.TCPSocket;
 </script>

 <script src="{{ ORBITED_MEDIA_URL }}JSON.js"></script>
 <script
 src="{{ ORBITED_MEDIA_URL }}protocols/stomp/stomp.js"></script>



                          
Comet web applications with Python,
                     Django & Orbited
<script>
$(document).ready(function() {
    stomp = new STOMPClient();
    stomp.onopen = function() { debug('Connected.');};
    stomp.onclose = function(c) { debug(Lost Connection, Code: '+c);};
    stomp.onerror = function(error){ debug("Error: " + error);};
    stomp.onerrorframe = function(frame){ debug("Error: " + frame.body);};
    stomp.onconnectedframe = function() {
        {% if game %}
        stomp.subscribe('/games/{{ game.id }}/status');
        stomp.subscribe('/games/{{ game.id }}/players');
       {% else %}// subscribe to other channels...{% endif %}
    };
    stomp.onmessageframe = function(frame){
        // frame.headers.destination for channel, frame.body for JSON data
        destpatterns.dispatch(frame);
    };
    stomp.connect('{{ STOMP_HOST }}', {{ STOMP_PORT }});
});
</script>
                              
Comet web applications with Python,
                   Django & Orbited

Django view
 @require_POST
 @login_required
 def game_start(request, game_id):
   game = get_object_or_404(Game, id=game_id)
   if request.user != game.author:
      return HttpResponseForbidden()
   try:
       # start() method set game start_time and send JSON
       # to ”/games/{{ game.id }}/status” using stomp.py
      game.start()
   except GameError, e:
       return JSONResponse({'error': str(e)})
   return JSONResponse({})



                           
Comet web applications with Python,
        Django & Orbited




       Does it scale?



              
Comet web applications with Python,
        Django & Orbited




              
Comet web applications with Python,
        Django & Orbited




              
Comet web applications with Python,
         Django & Orbited




           Thank you
       and have fun with the quiz game!




                

Comet web applications with Python, Django & Orbited

  • 1.
    Comet web applicationswith Python, Django & Orbited @ PyCon Italia Qu4ttro Massimo Scamarcia http://www.pycon.it/ http://www.webright.it/    
  • 2.
    Comet web applicationswith Python, Django & Orbited How to push real-time data to web browsers?    
  • 3.
    Comet web applicationswith Python, Django & Orbited AJAX Polling  Client: sends AJAX request.  Server:  Data available: sends response.  No data: sends empty response.  Client: sends AJAX request again.    
  • 4.
    Comet web applicationswith Python, Django & Orbited Latency, bandwidth, memory usage and scaling issues!    
  • 5.
    Comet web applicationswith Python, Django & Orbited What about Comet?    
  • 6.
    Comet web applicationswith Python, Django & Orbited Not a technology in itself Long Polling, IFRAME stream, HTMLFile, XHR Streaming, HTML5 SSE    
  • 7.
    Comet web applicationswith Python, Django & Orbited It's an hack! Still waiting for an unanimous way to do it.    
  • 8.
    Comet web applicationswith Python, Django & Orbited Long Polling  Client: sends AJAX request.  Server: holds the request.  Data available: sends response.  Timeout reached: empty response.  Client: sends AJAX request again.    
  • 9.
    Comet web applicationswith Python, Django & Orbited Http Push (HTTP Streaming*)  Client: sends HTTP request.  Server: doesn't terminate the connection.  Server: sends data when available.  Connection closed:  Data is queued.  Client reconnects. [*] http://ajaxpatterns.org/HTTP_Streaming    
  • 10.
    Comet web applicationswith Python, Django & Orbited  HTTP Push: better for heavily-loaded apps.  Not cross-browser.  Long Polling: cross-browser and easy.  Bandwidth usage.  Too many connections.  Async Python servers* are better for both:  Twisted, Tornado, Dieselweb, Eventlet, Concurrence, Circuits, Gevent, Cogen. [*] http://nichol.as/asynchronous-servers-in-python    
  • 11.
    Comet web applicationswith Python, Django & Orbited What about Orbited?    
  • 12.
    Comet web applicationswith Python, Django & Orbited He's here to solve problems!    
  • 13.
    Comet web applicationswith Python, Django & Orbited  Based on Twisted.  STOMP* (ActiveMQ, RabbitMQ), IRC and XMPP protocol support.  Ready-to-use and cross-browser JavaScript client code.  You don't have to reinvent the wheel! [*] http://stomp.codehaus.org/    
  • 14.
    Comet web applicationswith Python, Django & Orbited Using Django and Orbited Example app developed for PyConIt4: http://pyconquiz.webright.it/    
  • 15.
    Comet web applicationswith Python, Django & Orbited Django is used for:  Application logic.  Template rendering.  User auth and registration.  Handling AJAX requests.  Sending messages to STOMP server. ...Orbited and jQuery do the rest!    
  • 16.
    Comet web applicationswith Python, Django & Orbited    
  • 17.
    Comet web applicationswith Python, Django & Orbited orbited.cfg settings.py [global] # Available using context #reactor=select # processor or templatetag #reactor=kqueue reactor = epoll ORBITED_HOST = 'localhost' proxy.enabled = 1 ORBITED_PORT = 8080 session.ping_interval = 300 STOMP_HOST = 'localhost' [listen] STOMP_PORT = 61613 http://localhost:8080 stomp://localhost:61613 [access] * -> localhost:61613    
  • 18.
    Comet web applicationswith Python, Django & Orbited Django base template (<head /> tag) <script>document.domain = document.domain;</script> <script src="{{ ORBITED_MEDIA_URL }}Orbited.js"></script> <script type="text/javascript"> Orbited.settings.port = {{ ORBITED_PORT }}; Orbited.settings.hostname = "{{ ORBITED_HOST }}"; Orbited.settings.streaming = true; TCPSocket = Orbited.TCPSocket; </script> <script src="{{ ORBITED_MEDIA_URL }}JSON.js"></script> <script src="{{ ORBITED_MEDIA_URL }}protocols/stomp/stomp.js"></script>    
  • 19.
    Comet web applicationswith Python, Django & Orbited <script> $(document).ready(function() { stomp = new STOMPClient(); stomp.onopen = function() { debug('Connected.');}; stomp.onclose = function(c) { debug(Lost Connection, Code: '+c);}; stomp.onerror = function(error){ debug("Error: " + error);}; stomp.onerrorframe = function(frame){ debug("Error: " + frame.body);}; stomp.onconnectedframe = function() { {% if game %} stomp.subscribe('/games/{{ game.id }}/status'); stomp.subscribe('/games/{{ game.id }}/players'); {% else %}// subscribe to other channels...{% endif %} }; stomp.onmessageframe = function(frame){ // frame.headers.destination for channel, frame.body for JSON data destpatterns.dispatch(frame); }; stomp.connect('{{ STOMP_HOST }}', {{ STOMP_PORT }}); }); </script>    
  • 20.
    Comet web applicationswith Python, Django & Orbited Django view @require_POST @login_required def game_start(request, game_id): game = get_object_or_404(Game, id=game_id) if request.user != game.author: return HttpResponseForbidden() try: # start() method set game start_time and send JSON # to ”/games/{{ game.id }}/status” using stomp.py game.start() except GameError, e: return JSONResponse({'error': str(e)}) return JSONResponse({})    
  • 21.
    Comet web applicationswith Python, Django & Orbited Does it scale?    
  • 22.
    Comet web applicationswith Python, Django & Orbited    
  • 23.
    Comet web applicationswith Python, Django & Orbited    
  • 24.
    Comet web applicationswith Python, Django & Orbited Thank you and have fun with the quiz game!