.. post:: 2014-02-10 :tags: Python, Flask, gevent :author: Rudi Grinberg Omegle clone in Flask + Gevent + WebSockets =========================================== Python ranks fairly high when it comes getting things done without too much ceremony in the programming community. I briefly had some doubts of this assertion of until I finally found `Flask-Sockets `__. This small library makes it very natural to serve WebSockets in Flask/gevent. You can consider this blog post as an advertisement for this small but extremely useful library. In this post, I will show how to create an extremely simple omegle POC using the Gevent/Flask/Flask-Sockets combo. The end result is that the javascript client is comparable in code size to the server. Here's the code for the server (the client is ugly and uninteresting but you can see it in the repo): .. code-block:: python #!/usr/bin/env python2 import gevent.monkey gevent.monkey.patch_all() import flask from flask import Flask from flask_sockets import Sockets import gevent import gevent.queue from gevent import pywsgi from geventwebsocket.handler import WebSocketHandler app = Flask(__name__, static_url_path='') sockets = Sockets(app) seekers = gevent.queue.Queue() def relay(from_, to): """route messges from_ -> to""" try: while True: to.send(from_.receive()) except: # Notify to about disconnection - unless to disconnected try: to.send("Peer disconnected.") except: pass def session(ws1, ws2): for ws in [ws1, ws2]: ws.send("/Found a person. Say hello") gevent.joinall([ gevent.spawn(relay, ws1, ws2), gevent.spawn(relay, ws2, ws1) ]) def matcher(seekers): while True: gevent.spawn(session, seekers.get(), seekers.get()) gevent.spawn(matcher, seekers) @sockets.route('/ws') def websocket(ws): seekers.put(ws) ws.send("/Welcome. Seeking a partner") while True: # hack to keep the greenlet alive gevent.sleep(0.5) @app.route('/') def index(): return app.send_static_file('index.html') if __name__ == '__main__': pywsgi.WSGIServer(('', 8000), app, handler_class=WebSocketHandler) \ .serve_forever() The implementation is very naive but I still wonder how well it would perform. Many further improvements are possible as well: - Limit the number of concurrent sessions - Create a pool for matchers to make sure that ``seekers`` empties fast enough - Allow clients to advertise names You can see the full code `here `__.