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

Reply via email to