TypeError when connection is closed in connect()
See original GitHub issueI have the same problem then #185 but I think, I can reproduce it.
When you close a connection in the connect() method of a WebsocketConsumer, it works fine with daphne but uvicorn raises a TypeError
Traceback (most recent call last):
File "/home/ossi/src/channels-examples/.venv/lib/python3.7/site-packages/uvicorn/protocols/websockets/websockets_impl.py", line 140, in run_asgi
result = await asgi(self.asgi_receive, self.asgi_send)
File "/home/ossi/src/channels-examples/.venv/lib/python3.7/site-packages/channels/sessions.py", line 179, in __call__
return await self.inner(receive, self.send)
File "/home/ossi/src/channels-examples/.venv/lib/python3.7/site-packages/channels/middleware.py", line 41, in coroutine_call
await inner_instance(receive, send)
File "/home/ossi/src/channels-examples/.venv/lib/python3.7/site-packages/channels/consumer.py", line 59, in __call__
[receive, self.channel_receive], self.dispatch
File "/home/ossi/src/channels-examples/.venv/lib/python3.7/site-packages/channels/utils.py", line 59, in await_many_dispatch
await task
File "/home/ossi/src/channels-examples/.venv/lib/python3.7/site-packages/channels/utils.py", line 51, in await_many_dispatch
result = task.result()
File "/home/ossi/src/channels-examples/.venv/lib/python3.7/site-packages/uvicorn/protocols/websockets/websockets_impl.py", line 222, in asgi_receive
data = await self.recv()
File "/home/ossi/src/channels-examples/.venv/lib/python3.7/site-packages/websockets/protocol.py", line 419, in recv
return_when=asyncio.FIRST_COMPLETED,
File "/usr/lib/python3.7/asyncio/tasks.py", line 361, in wait
fs = {ensure_future(f, loop=loop) for f in set(fs)}
File "/usr/lib/python3.7/asyncio/tasks.py", line 361, in <setcomp>
fs = {ensure_future(f, loop=loop) for f in set(fs)}
File "/usr/lib/python3.7/asyncio/tasks.py", line 592, in ensure_future
raise TypeError('An asyncio.Future, a coroutine or an awaitable is '
TypeError: An asyncio.Future, a coroutine or an awaitable is required
I created this branch on the django-channels-example repository: https://github.com/ostcar/channels-examples/tree/uvicorn-test
All I changed was, that the websocket connection is always closed: https://github.com/andrewgodwin/channels-examples/compare/master...ostcar:uvicorn-test
I think the problem is, that you call websockets.WebSocketServerProtocol.recv()
before the websocket connection is open so websockets.WebSocketServerProtocol.connection_open()
was not called. In this case the attribute transfer_data_task
is still None. So when websockets.WebSocketServerProtocol.recv()
calls
yield from asyncio.wait(
[pop_message_waiter, self.transfer_data_task],
loop=self.loop,
return_when=asyncio.FIRST_COMPLETED,
)
it tries to await None
what causes the exception.
I don’t know, if this is a but in the websockets package or if you should check self.closed
before calling self.recv()
Issue Analytics
- State:
- Created 5 years ago
- Reactions:7
- Comments:18 (8 by maintainers)
Top GitHub Comments
@tomchristie ping? I have reduced the issue by enabling logging in Uvicorn’s own test suite. I also submitted pull request #704 with a sketch of a fix. Are you still keen to dig into it? 😃
Here is a minimal example without using django:
To test it, you have to start it with an asgi server an open a websocket connection.
With daphne:
With uvicorn and websockets:
With uvicorn and wsproto:
The error seems to be, that the
while True:
loop does not break. But when I look into the django channels code, it seems, that django channels also does not close the loop.The loop in django channels is here: https://github.com/django/channels/blob/03d221792e6881477911728615a6d51ec9fab73b/channels/utils.py#L45
The
close
message is send here: https://github.com/django/channels/blob/03d221792e6881477911728615a6d51ec9fab73b/channels/generic/websocket.py#L226An exception, that could break the loop is raised when
websocket.disconnect
is handled: https://github.com/django/channels/blob/03d221792e6881477911728615a6d51ec9fab73b/channels/generic/websocket.py#L241