flask-uwsgi-websocket
flask-uwsgi-websocket copied to clipboard
Using uWSGI's asyncio engine & Redis for generic websocket communication
Following issue #27, i've been trying to implement a send/receive asyncio listener coroutine as follows:
websock = WebSocket(app)
@websock.route('/websocket')
def echo(ws):
r = redis_conn.pubsub()
r.subscribe("test_channel")
asyncio.Task(listen(ws,r))
With the coroutine (called as a task, temporary: to edit to something sensible when bugs clear):
@asyncio.coroutine
def listen(ws,r):
for msg in r.listen():
ws.send(str(msg['data']))
while True:
msg=ws.receive()
if msg is not None:
print(msg)
else:
yield from asyncio.wait(1)
The server (namely, main flask app) should be able to send a message from anywhere using e.g.,redis_conn.publish('test_channel','hello @'+str(time.time()))
Using uwsgi (compiled with asyncio support) v2.0.10 and greenlet v0.4.7.
It seems uwsgi/websockets using uwsgi's asyncio event loop are is not supported in this configuration; asyncio is not in the supported concurrency models list (here
The error i'm getting when trying to connect is (browser to websocket route):
[BUG] current_wsgi_req NOT FOUND !!!
Task exception was never retrieved
future: exception=SystemError('you can call uwsgi api function only from the main callable',)>
Traceback (most recent call last):
File "/usr/lib/python3.4/asyncio/tasks.py", line 237, in _step
result = next(coro)
File "./api/__init__.py", line 80, in try_listen
msg = ws.receive()
File "./api/apivenv3/lib/python3.4/site-packages/flask_uwsgi_websocket/websocket.py", line 21, in receive
return self.recv()
File "./api/apivenv3/lib/python3.4/site-packages/flask_uwsgi_websocket/websocket.py", line 25, in recv
return uwsgi.websocket_recv()
SystemError: you can call uwsgi api function only from the main callable
Any way around this error from within flask? [BUG] suggests uWSGI can't tell where the request is from (thread/process issue?)