AttributeError in ASGI/Daphne Django problem

Question:

I had done this tutorial for WebSocket with Django but I have this problem when I execute "python manage.py runserver":

HTTP GET /chat/hello/ 200 [0.01, 127.0.0.1:65009]
WebSocket HANDSHAKING /ws/chat/hello/ [127.0.0.1:65014]
Exception inside application: 'int' object has no attribute 'decode'
Traceback (most recent call last):
  File "D:ProjectsNew Backendvenvlibsite-packagesdjangocontribstaticfileshandlers.py", line 101, in __call__
    return await self.application(scope, receive, send)
  File "D:ProjectsNew Backendvenvlibsite-packageschannelsrouting.py", line 62, in __call__
    return await application(scope, receive, send)
  File "D:ProjectsNew Backendvenvlibsite-packageschannelssessions.py", line 47, in __call__
    return await self.inner(dict(scope, cookies=cookies), receive, send)
  File "D:ProjectsNew Backendvenvlibsite-packageschannelssessions.py", line 263, in __call__
    return await self.inner(wrapper.scope, receive, wrapper.send)
  File "D:ProjectsNew Backendvenvlibsite-packageschannelsauth.py", line 185, in __call__
    return await super().__call__(scope, receive, send)
  File "D:ProjectsNew Backendvenvlibsite-packageschannelsmiddleware.py", line 24, in __call__
    return await self.inner(scope, receive, send)
  File "D:ProjectsNew Backendvenvlibsite-packageschannelsrouting.py", line 116, in __call__
    return await application(
  File "D:ProjectsNew Backendvenvlibsite-packageschannelsconsumer.py", line 94, in app
    return await consumer(scope, receive, send)
  File "D:ProjectsNew Backendvenvlibsite-packageschannelsconsumer.py", line 58, in __call__
    await await_many_dispatch(
  File "D:ProjectsNew Backendvenvlibsite-packageschannelsutils.py", line 57, in await_many_dispatch
    await task
  File "D:ProjectsNew Backendvenvlibsite-packageschannelsutils.py", line 49, in await_many_dispatch
    result = task.result()
  File "D:ProjectsNew Backendvenvlibsite-packageschannels_rediscore.py", line 367, in receive
    message_channel, message = await self.receive_single(
  File "D:ProjectsNew Backendvenvlibsite-packageschannels_rediscore.py", line 422, in receive_single
    content = await self._brpop_with_clean(
  File "D:ProjectsNew Backendvenvlibsite-packageschannels_rediscore.py", line 255, in _brpop_with_clean
    connection = self.connection(index)
  File "D:ProjectsNew Backendvenvlibsite-packageschannels_rediscore.py", line 738, in connection
    self.pools[index] = self.create_pool(index)
  File "D:ProjectsNew Backendvenvlibsite-packageschannels_rediscore.py", line 133, in create_pool
    return aioredis.ConnectionPool.from_url(host["address"])
  File "D:ProjectsNew Backendvenvlibsite-packagesredisasyncioconnection.py", line 1284, in from_url
    url_options = parse_url(url)
  File "D:ProjectsNew Backendvenvlibsite-packagesredisasyncioconnection.py", line 1176, in parse_url
    parsed: ParseResult = urlparse(url)
  File "C:UsersluixgAppDataLocalProgramsPythonPython39liburllibparse.py", line 392, in urlparse
    url, scheme, _coerce_result = _coerce_args(url, scheme)
  File "C:UsersluixgAppDataLocalProgramsPythonPython39liburllibparse.py", line 128, in _coerce_args
    return _decode_args(args) + (_encode_result,)
  File "C:UsersluixgAppDataLocalProgramsPythonPython39liburllibparse.py", line 112, in _decode_args
    return tuple(x.decode(encoding, errors) if x else '' for x in args)
  File "C:UsersluixgAppDataLocalProgramsPythonPython39liburllibparse.py", line 112, in <genexpr>
    return tuple(x.decode(encoding, errors) if x else '' for x in args)
AttributeError: 'int' object has no attribute 'decode'
WebSocket DISCONNECT /ws/chat/hello/ [127.0.0.1:65014]

I’m trying with:

  1. Django=4.1.2 channels=4.0.0 daphne=4.0.0 python=3.9.10

I’ve been trying for days to see the error but nothing is wrong, my only guess is that there might be a conflict with the versions of the libraries I’m using.

Asked By: LuisFerchx

||

Answers:

A Daphne asynchronous server runs on the server and creates separate containers or instances that run individually. You are no longer simply running your python django project, but you are now also running a websocket server for your django project to connect to.

In other languages this would be solved by using a separate server but because you have designed your server using daphne django you can run it on a single server where each instance connects to each other. You’re going to have to make sure your server configuration is in line with what you are trying to do. It should work to simply redirect all websocket /wss/ requests from localhost even in production because we are actually accessing a server or instance that is local to our system.

Consider the following apache server configuration, if you are running locally then you should not have to rewrite any rules for /ws/ but if you are at production level you will need to redirect your http and ws connections to https and wss

    <VirtualHost _default_:443>
    ...
    RewriteEngine on
    RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC,OR]
    RewriteCond %{HTTP:CONNECTION} ^Upgrade$ [NC]
    RewriteRule .* ws://127.0.0.1:8001%{REQUEST_URI} [P,QSA,L]
    ProxyPass /wss/ wss://127.0.0.1:8001/
    ProxyPassReverse /wss/ wss://127.0.0.1:8001/
    ...

Then you have to run the daphne asynchronous server which will start both instances.

daphne -b 0.0.0.0 -p 8001 django_project.asgi:application // Local Development Level
daphne -e ssl:443:privateKey=key.pem:certKey=crt.pem django_project.asgi:application // Production Level

Good luck and stay vigilant !

Answered By: Gracen Ownby

My problem was easy:

Daphne (locally) works differently on windows than on Ubuntu:

For Ubuntu this configuration is used in the settings.py:

ASGI_APPLICATION = "mysite.asgi.application"
CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "channels_redis.core.RedisChannelLayer",
        "CONFIG": {
            "hosts": [("127.0.0.1", 6379)],
        },
    },
}

But for Windows this configuration is used:

CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "channels.layers.InMemoryChannelLayer"
    },
}

This is because of the way Redis works.
However, this shouldn’t be the functionality for a production server, I only use it to work locally.

Although it also has to do a lot with the versions that the channels packages work with.

I also solved this by running the following command:

python -m pip install -U channels["daphne"]

References:
ASGI_APPLICATION not working with Django Channels

Answered By: LuisFerchx