Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Real-time apps with gevent-socketio

Real-time apps with gevent-socketio

pyconsg 2013

Calvin Cheng

June 15, 2013
Tweet

More Decks by Calvin Cheng

Other Decks in Technology

Transcript

  1. OVERVIEW • Concepts ✓concurrency ✓parallelism ✓threads ✓processes ✓gevent greenlets •

    Concepts ✓sockets ✓python sockets ✓WebSockets ✓Socket.IO • Code: A simple Socket.IO example • Code: Socket.IO’s on and emit Saturday, June 15, 13
  2. CONCEPTS • Concurrency? • Parallelism? • Threads? • Processes? •

    Gevent’s greenlets? • Gevent monkey patch Saturday, June 15, 13
  3. THREADS • basic unit of CPU utilization • lightweight process

    • unlike process, threads do not have their own PCB • runs within a process • shares code, data, heap • can be concurrent and parallel (warning: GIL limitation in python) Saturday, June 15, 13
  4. PROCESSES • an instance of a program that is being

    executed • runs within the kernel • shares code, data, heap, stack • holds information about active processes in data structures called PCB • can be concurrent and parallel Saturday, June 15, 13
  5. PYTHON CONTEXT • python (CPython) GIL prevents parallel threads •

    generally, use python’s multiprocessing • exception... Saturday, June 15, 13
  6. GEVENT • lightweight coroutines, with concurrency capabilities • asynchronous IO

    (libev/libevent) • lightweight threads called greenlets (cooperative multi- threading) • libev/libevent handles events (“emit” call to send message via socketio in the context of gevent-socketio implementation) • gevent spawns concurrent tasks (lightweight thread of execution - greenlets) Saturday, June 15, 13
  7. GREENLETS • spin-off from stackless python • main building-blocks of

    gevent • “lightweight threads”- different from POSIX threads (pthreads) - no implicit scheduling • we specify when the code runs or when it gets switched away Saturday, June 15, 13
  8. MONKEY PATCH • extend/modify run-time code of dynamic languages without

    altering source code • The order matters! Apply patch first. import gevent.monkey; gevent.monkey.patch_thread() import threading Saturday, June 15, 13
  9. CONCEPTS • sockets? • Python sockets • WebSockets? • Socket.IO?

    ✓namespace & js logic (client-side “controllers”) ✓server ✓router (“urls”) ✓namespace & methods (server-side “controllers”) Saturday, June 15, 13
  10. SOCKETS • Berkeley sockets (BSD sockets, equiv to POSIX sockets)

    • written in C • When a socket is created, a communication endpoint becomes available • A file descriptor is returned • “Everything is a file” Saturday, June 15, 13
  11. PYTHON SOCKETS • Berkeley sockets (BSD sockets, equiv to POSIX

    sockets) • written in C • When a socket is created, a communication endpoint becomes available • A file descriptor is returned • “Everything is a file” • Various languages provide similar interfaces and are essentially wrappers Saturday, June 15, 13
  12. PYTHON SOCKETS #  server.py import  socket serversocket  =  socket.socket(socket.AF_INET,  socket.SOCK_STREAM)

    serversocket.bind(('localhost',  8089)) serversocket.listen(5) while  True:        connection,  address  =  serversocket.accept()        buf  =  connection.recv(64)        if  len(buf)>0:                print  buf Saturday, June 15, 13
  13. PYTHON SOCKETS #  client.py import  socket clientsocket  =  socket.socket(socket.AF_INET,  socket.SOCK_STREAM)

    clientsocket.connect(('localhost',  8089)) clientsocket.send('hello') Saturday, June 15, 13
  14. WEBSOCKETS • Full-duplex message transfer • Independent TCP-type protocol, not

    HTTP • “Upgrade” request in HTTP 1.1 • Server can also force an upgrade by sending “426 upgrade required” • stream of messages, not bytes, splitted across data frames, end marked by FIN • connection persists Saturday, June 15, 13
  15. SOCKET.IO • javascript library with client side and server-side components

    • 6 transports ✓WebSocket ✓Adobe Flash Socket ✓AJAX long polling ✓AJAX multipart streaming ✓Forever IFrame ✓JSONP polling • Most capable transport selected at runtime no change required to its abstracted API! socket.io-transports analogous to orm-(db adaptors and databases) Saturday, June 15, 13
  16. SOCKET.IO • many implementations for different languages, not just the

    original (nodejs) javascript implementation ✓python ✓perl ✓java ✓golang ✓erlang • why? Because fundamentally, Socket.IO is logic built on top of sockets. And as we already know, various languages have their own interfaces to Berkeley sockets! Saturday, June 15, 13
  17. NAMESPACE & JS FUNCTIONS <script  src="/static/js/socket.io.js"></script> <script>   WEB_SOCKET_SWF_LOCATION="/static/flashsocket/WebSocketMain.swf" var

     socket  =  io.connect("/chat"); //  ..  other  js  logic </script> • flash transport (WEB_SOCKET_SWF_LOCATION) optional • install socket.io.js client (which comes with WebSocketMain.swf which we can use optionally) via nodeenv, npm and bower • establish a “socket” js object via io.connect() • “/chat” is a Socket.IO namespace which is like a “controller” and NOT a url (“router”) (client-side “Controllers”) Saturday, June 15, 13
  18. SOCKET.IO SERVER from gevent import monkey from socketio.server import SocketIOServer

    monkey.patch_all() PORT = 5000 if __name__ == '__main__': print 'Listening on http://127.0.0.1:%s and on port 10843 (flash policy server)' % PORT SocketIOServer(('', PORT), app, resource="socket.io").serve_forever() Saturday, June 15, 13
  19. SOCKET.IO ROUTER (“URL”) @app.route('/socket.io/<path:remaining>') def  socketio(remaining):        try:

                   socketio_manage(request.environ,  {'/chat':  ChatNamespace},   request)        except:                app.logger.error("Exception  while  handling  socketio   connection",  exc_info=True)        return  Response() Saturday, June 15, 13
  20. NAMESPACE & METHODS class  ChatNamespace(BaseNamespace,  RoomsMixin,  BroadcastMixin):      

     nicknames  =  []        def  initialize(self):                ...        def  log(self,  message):                ...        def  on_join(self,  room):                ...        def  on_nickname(self,  nickname):                ...                return  True,  nickname        def  recv_disconnect(self):                ...                return  True        def  on_user_message(self,  msg):                ...                return  True (server-side “Controllers”) Saturday, June 15, 13
  21. NAMESPACE & JS FUNCTIONS $(function()  {        var

     WEB_SOCKET_SWF_LOCATION  =  '/static/js/socketio/WebSocketMain.swf',        socket  =  io.connect('/chat');        socket.on('connect',  function  ()  {                $('#chat').addClass('connected');                socket.emit('join',  window.room);        });        socket.on('announcement',  function  (msg)  {                $('#lines').append($('<p>').append($('<em>').text(msg)));        });        socket.on('nicknames',  function  (nicknames)  {                $('#nicknames').empty().append($('<span>Online:  </span>'));                for  (var  i  in  nicknames)  {                    $('#nicknames').append($('<b>').text(nicknames[i]));                }        });        socket.on('msg_to_room',  message);        socket.on('reconnect',  function  ()  {                $('#lines').remove();                message('System',  'Reconnected  to  the  server');        });        socket.on('reconnecting',  function  ()  {                message('System',  'Attempting  to  re-­‐connect  to  the  server');        }); (client-side “Controllers”) Saturday, June 15, 13
  22. RESOURCES • http://sdiehl.github.io/gevent-tutorial/ • https://github.com/abourget/gevent-socketio • My notes & source

    code https://learn-gevent-socketio.readthedocs.org/en/latest/ https://github.com/calvinchengx/pyconsg2013 https://github.com/calvinchengx/learnsocketio Saturday, June 15, 13