3

I am using Django Channels with uvicorn and I have following type of code:

async def connect(self): 
    """Accept connect if user has been provided by middleware"""  
    self.user = self.scope.get('user') 
    if self.user: 
        await self.accept() 
    else: 
        await self.close()

Basically, if after going through middleware if use is none i am closing the connection. When I run it with Daphne, it works perfectly fine. Otherwise, when I run it via uvicorn server, it throws following error:

ERROR: Exception in ASGI application
Traceback (most recent call last):
  File "/home/coldbrewtech/frnd/backend/env/lib/python3.6/site-packages/uvicorn/protocols/websockets/websockets_impl.py", line 146, in run_asgi
    result = await self.app(self.scope, self.asgi_receive, self.asgi_send)
  File "/home/coldbrewtech/frnd/backend/env/lib/python3.6/site-packages/uvicorn/middleware/asgi2.py", line 7, in __call__
    await instance(receive, send)
  File "/home/coldbrewtech/frnd/backend/env/lib/python3.6/site-packages/channels/consumer.py", line 59, in __call__
    [receive, self.channel_receive], self.dispatch
  File "/home/coldbrewtech/frnd/backend/env/lib/python3.6/site-packages/channels/utils.py", line 59, in await_many_dispatch
    await task
  File "/home/coldbrewtech/frnd/backend/env/lib/python3.6/site-packages/channels/utils.py", line 51, in await_many_dispatch
    result = task.result()
  File "/home/coldbrewtech/frnd/backend/env/lib/python3.6/site-packages/uvicorn/protocols/websockets/websockets_impl.py", line 226, in asgi_receive
    data = await self.recv()
  File "/home/coldbrewtech/frnd/backend/env/lib/python3.6/site-packages/websockets/protocol.py", line 419, in recv
    return_when=asyncio.FIRST_COMPLETED,
  File "/usr/lib/python3.6/asyncio/tasks.py", line 311, in wait
    fs = {ensure_future(f, loop=loop) for f in set(fs)}
  File "/usr/lib/python3.6/asyncio/tasks.py", line 311, in <setcomp>
    fs = {ensure_future(f, loop=loop) for f in set(fs)}
  File "/usr/lib/python3.6/asyncio/tasks.py", line 526, 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

But when I add await self.accept() before await self.close(), it doesn't throw any error. Can anyone please help me out with this.

Thanks in advance!!!

drec4s
  • 7,946
  • 8
  • 33
  • 54
hardik24
  • 1,008
  • 1
  • 11
  • 34

1 Answers1

0

This is apparently an issue in channels, where the close() method is not ready to be called during the socket setup.

From what I can read in the issue, the solution is exactly what you're doing, that is to accept the connection first and then close it.