70

I'm currently researching websocket support in Python and am a bit confused with the offerings.

On one hand it's possible to use Flask + gevent. On the other hand, uwsgi has socket support and at last there is an extension that bundles both uwsgi and gevent.

What's the problem with implementing websockets with only one of these? What do I win by mixing them?

Changing the question

What does adding gevent do that threaded uwsgi won't?

ruipacheco
  • 15,025
  • 19
  • 82
  • 138
  • There is an extension written by Kenneth Reitz named "Flask-Sockets" that is excellent for websockets. Check it out. https://github.com/kennethreitz/flask-sockets – codegeek Apr 16 '14 at 14:13
  • 3
    Thanks, but I'm also interested in finding out the role of gevent in this mess. – ruipacheco Apr 16 '14 at 15:53
  • I would say because it is a asyncronous. So there for a single worker is not sat solely dealing with one client. – Joe Doherty Apr 16 '14 at 19:39

1 Answers1

155

In regular HTTP requests the connections between client and server are short-lived, a client connects to the server, sends a request, receives the response and then closes the connection. In this model the server can serve a large number of clients using a small number of workers. The concurrency model in this situation is typically based on threads, processes or a combination of both.

When you use websocket the problem is more complex, because a websocket connection is open for a long period of time, so the server cannot use a small pool of workers to serve a large number of clients, each client needs to get its own dedicated worker. If you use threads and/or processes then your app will not scale to support a large number of clients because you can't have large number of threads/processes.

This is where gevent enters the picture. Gevent has a concurrency model based on greenlets, which scale much better than threads/processes. So serving websocket connections with a gevent based server allows you support more clients, due to the lightweight nature of greenlets. With uWSGI you have a choice of concurrency models to use with web sockets, and that includes the greenlet based model from gevent. You can also use gevent's web server standalone if you want.

But note that gevent does not know anything about web sockets, it is just a server. To use websocket connections you have to add an implementation of the websocket server.

There are two extensions for Flask that simplify the use of websockets. The Flask-Sockets extension by Kenneth Reitz is a wrapper for gevent and gevent-websocket. The Flask-SocketIO extension (shameless plug as I'm the author) is a wrapper for gevent and gevent-socketio on the server, plus Socket.IO on the client. Socket.IO is higher level socket protocol that can use web socket if available but can also use other transport mechanisms on older browsers.

starball
  • 20,030
  • 7
  • 43
  • 238
Miguel Grinberg
  • 65,299
  • 14
  • 133
  • 152
  • @Miguel - How do I run Socket.IO if I'm using a manager ? Cant do the prescribed - socketio.run(app) – vivekanon May 27 '16 at 08:00
  • upvoted! if i had to listen to socket connections from say a few different APIs in flask, what would be the right way to go about it? celery? threads? process pool – PirateApp Jun 12 '18 at 03:25
  • Why are you palming people off to Socket.IO when the question is about websockets? Seems you've shoehorned an advertisement into something unrelated. – Peilonrayz Oct 09 '22 at 23:54