Thanks for a fast answer Roberto, you probably missed the code in my second message, I did something very similar to the flask approach, using 2 gevent events for communication, but calling "recv_nb" and "send" from the main thread.
It works perfectly, and reacts immediately on messages coming from both sides. It seems the approach you suggested "ready = gevent.select.select([websocket_fd], [], [], 1.0)" will block, when the server is ready to send data, cause it does not account for it, only for reading from the browser, but this is unacceptable. And it requires going back to python every second, which is also not good, wasting a lot of CPU cycles in python. I have every browser page connected to the websocket, so it might create a lot of useless overhead. The only question remaining was how often should uwsgi.websocket_recv_nb() be called, but I solved it by adding one timeout to the "ready.wait()" line, changing it to "ready.wait(timeout=59)", where I have 60 seconds uwsgi_read_timeout set in nginx. Everything still reacts immediately on changes from both sides, but uwsgi sends pings this way at least every minute. Here's the final version https://gist.github.com/ikatson/9266862 On Thu, Feb 27, 2014 at 9:46 PM, Roberto De Ioris <[email protected]> wrote: > > > Hmm, I'm really not sure, if uwsgi makes any pings this way, with > > nonblocking recv() and without any timeouts set in the code. > > It seems to do so locally (version 1.9.14), and not to do on production > > (version 2.0.1) > > > > Roberto, can you comment on this please? > > The right behaviour is the one in 2.x, ping/pong are automatically managed > in each websocket_recv, so you cannot avoid to call it (but it is not a > problem). > > What you are doing wrong is managing the websocket transaction in a new > greenlet. This greenlet has no memory structure (allocated by uWSGI) to > manage websocket packets, that is why you get that error. > > Your code should be written as: > > uwsgi.websocket_handshake(env['HTTP_SEC_WEBSOCKET_KEY'], > env.get('HTTP_ORIGIN', '')) > > websocket_fd = uwsgi.connection_fd() > > while True: > > ready = gevent.select.select([websocket_fd], [], [], 1.0) > if not ready[0]: > uwsgi.websocket_recv_nb() > else: > uwsgi.websocket_send('foobar') > > no additional greenlet are spawned for websocket management. > > Another approach (more elegant and versatile) is the one written by Zach > Kelling: > > > https://github.com/zeekay/flask-uwsgi-websocket/blob/master/flask_uwsgi_websocket/_gevent.py#L36 > > he basically uses gevent queues to manage communication between greenlets, > letting the uWSGI greenlet to manage I/O in a synchronized way > > > > -- > Roberto De Ioris > http://unbit.it > _______________________________________________ > uWSGI mailing list > [email protected] > http://lists.unbit.it/cgi-bin/mailman/listinfo/uwsgi >
_______________________________________________ uWSGI mailing list [email protected] http://lists.unbit.it/cgi-bin/mailman/listinfo/uwsgi
