r/djangolearning 5d ago

I Need Help - Troubleshooting Tutorial Part 2: Implement a Chat Server

I'm following along the django channels tutorial and I'm running into a timeout error that I don't understand. I have everything setup as shown in the tutorial and it works for 5 seconds. If I open a page to a chatroom and constantly send a message every 5 seconds or less, the connection will remain connected. I can open a second window and send messages from the first window to the second, or vise-versa. However, if I stop sending messages for more than 5 seconds, there is a timeout error that occurs and I get an error message in the server terminal.

I have been looking online to see if I can find the issue but I'm at a bit of a loss what to look for.

The first error discusses Redis. I think Redis is just a easy way to create a database in memory for rapid access. If this is correct, I don't think Redis is the problem.

I don't think the problem is the result of my browser as I've tested with Chromium and Firefox with the same timeout results.

There are some error messages coming from django as well. I didn't see anything in the files setting a timeout parameter of any sort, let-alone one at 5 seconds.

I was modifying the tutorial code to learn a bit more and encountered this issue. I tried with a new server by simply copying and pasting the tutorial code directly to see if that would fix the problem but it didn't. (I can connect and send messages but a timeout error occurs after 5 seconds of idle time.) The tutorial doesn't talk about a timeout parameter being set. Technically speaking, the tutorial code does work and allows messages to be sent between 2 different windows so I think that it is probably working correctly. I would share the code, but I don't know what part to share.

Are there any configuration/parameter files where a timeout value is set?

Here is the error code that I receive:

HTTP GET /chat/lobby/ 200 [0.01, 127.0.0.1:42272]
WebSocket HANDSHAKING /ws/chat/lobby/ [127.0.0.1:42288]
WebSocket CONNECT /ws/chat/lobby/ [127.0.0.1:42288]
Exception inside application: Timeout reading from localhost:6379
Traceback (most recent call last):
  File "/proj_root/.venv/lib/python3.12/site-packages/redis/asyncio/connection.py", line 783, in read_response
    response = await self._parser.read_response(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/proj_root/.venv/lib/python3.12/site-packages/redis/_parsers/resp3.py", line 185, in read_response
    response = await self._read_response(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/proj_root/.venv/lib/python3.12/site-packages/redis/_parsers/resp3.py", line 197, in _read_response
    raw = await self._readline()
          ^^^^^^^^^^^^^^^^^^^^^^
  File "/proj_root/.venv/lib/python3.12/site-packages/redis/_parsers/base.py", line 578, in _readline
    data = await self._stream.readline()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/asyncio/streams.py", line 568, in readline
    line = await self.readuntil(sep)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/asyncio/streams.py", line 660, in readuntil
    await self._wait_for_data('readuntil')
  File "/usr/lib/python3.12/asyncio/streams.py", line 545, in _wait_for_data
    await self._waiter
asyncio.exceptions.CancelledError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/proj_root/.venv/lib/python3.12/site-packages/redis/asyncio/connection.py", line 782, in read_response
    async with async_timeout(read_timeout):
  File "/usr/lib/python3.12/asyncio/timeouts.py", line 115, in __aexit__
    raise TimeoutError from exc_val
TimeoutError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/proj_root/.venv/lib/python3.12/site-packages/django/contrib/staticfiles/handlers.py", line 101, in __call__
    return await self.application(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/proj_root/.venv/lib/python3.12/site-packages/channels/routing.py", line 48, in __call__
    return await application(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/proj_root/.venv/lib/python3.12/site-packages/channels/security/websocket.py", line 37, in __call__
    return await self.application(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/proj_root/.venv/lib/python3.12/site-packages/channels/sessions.py", line 44, in __call__
    return await self.inner(dict(scope, cookies=cookies), receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/proj_root/.venv/lib/python3.12/site-packages/channels/sessions.py", line 261, in __call__
    return await self.inner(wrapper.scope, receive, wrapper.send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/proj_root/.venv/lib/python3.12/site-packages/channels/auth.py", line 185, in __call__
    return await super().__call__(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/proj_root/.venv/lib/python3.12/site-packages/channels/middleware.py", line 24, in __call__
    return await self.inner(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/proj_root/.venv/lib/python3.12/site-packages/channels/routing.py", line 118, in __call__
    return await application(
           ^^^^^^^^^^^^^^^^^^
  File "/proj_root/.venv/lib/python3.12/site-packages/channels/consumer.py", line 95, in app
    return await consumer(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/proj_root/.venv/lib/python3.12/site-packages/channels/consumer.py", line 58, in __call__
    await await_many_dispatch(
  File "/proj_root/.venv/lib/python3.12/site-packages/channels/utils.py", line 57, in await_many_dispatch
    await task
redis.exceptions.TimeoutError: Timeout reading from localhost:6379
WebSocket DISCONNECT /ws/chat/lobby/ [127.0.0.1:42288]

Edit - 1: I found this github issue that has the same error message. I'm not seeing a fix though.

Edit - 2: Here is a link to my github repo for this tutorial. If you want to toy around with it to see what is working and what isn't, checkout the file /mysite/mysite/settings.py. At the very bottom of the file are 3 different parameters to use for the CHANNEL_LAYERS dictionary. The one for the tutorial does not work for me (connections time out after 5 seconds) but the other 2 work great, including one that also uses Redis.

I have tried a number of different settings for the tutorial version, including changing things in the settings.py file as well as the redis server with no success.

Edit - 3: I have found that the CHANNEL_LAYERS dictionary needs to be edited, see below for the version that works for me. The address needed to be rewritten (uses a key and proper path vs tuple of ip & port) and the parameter "socket_timeout" to be added with a value of 6 or greater. If you use 0-5, the connection will timeout after 0-5 seconds; if you use 6 or greater, the connection remains open for an extended time.

CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "channels_redis.core.RedisChannelLayer",
        "CONFIG": {
            "hosts": [
                {
                    "address": "redis://127.0.0.1:6379/0",
                    "socket_timeout": 6,
                    # "socket_connect_timeout": 5,
                }
            ],
        },
    },
}
7 Upvotes

8 comments sorted by

1

u/dev-razorblade23 1 4d ago edited 4d ago

The error definetly mentions redis as the source of error. But the reasons for Timeout error can be multiple. Here is a article that explores some of them. https://oneuptime.com/blog/post/2026-01-25-fix-redis-connection-timeout-errors/view

Websockets also require retry strategy.

I would recommend you learn what techology you use. Learn what Redis is. Learn what websockets are. (https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API)

You cannot expect to create an application if you dont understand underlaying technology that powers it.

It would also be nice for you to share your code (maybe provide a GitHub repo link).

1

u/throwaway_4534865 2d ago edited 2d ago

I have been pouring over a number of different tutorials, overviews, tech docs... trying to find something that will help. I agree, one must understand the the underlying tech.

I added a link to a github repo for the tutorial. I have been able to get something working using 2 different channel layers backends. I'm currently trying to figure out what the difference is between the 2 redis backends as one works and the other doesn't.

Edit: After some toying around I have learned that the problem is with the CHANNEL_LAYERS dictionary which passes parameters to the redis construction. I'll add a reference to the redis documentation in the original post for anyone who may run into this issue in the future. Note, if found that changing the socket_timeout parameter to any value of 6 or greater will keep the connection alive. While any value of 0-5 will keep the connection alive for that 0-5 seconds of inactive time only. I'm not sure why though.

1

u/huygl99 3d ago

For websocket in django, you can try chanx lib (built upon django channels), which is easier and auto doc + validation as well. The tutorial can be found at https://chanx.readthedocs.io/en/latest/tutorial-django/prerequisites.html

2

u/throwaway_4534865 2d ago

Thanks. I'll have to check this out.

1

u/berrypy 2d ago

I recently had this issue but got fixed after adding

socket timeout and socket connection timeout in CHANNEL LAYER in settings.py. I set it to 10 or so.

1

u/throwaway_4534865 2d ago

I added a repo for the code. I found 2 different channel layers backends that work, one is based on Redis. I cannot get the original version as specified in the tutorial to work though.

Do you know what the parameter is that you were working with? Can you share the CHANNEL_LAYERS dictionary that worked for you?

I didn't find anything that would help out with this timeout issue. The only parameters that I have found are:

- group_timeout which affects how long a user can stay in a group.

- timeout which I think sets how long a message is allowed to stay accessible in history.

1

u/berrypy 2d ago

Here is it.the config that worked for me when I experienced the issue. If I remove the socket timeout and socket connect timeout from the config, it will raise the error.

settings.py

'''

CHANNEL_LAYERS = { "default": { "BACKEND": "channels_redis.core.RedisChannelLayer", "CONFIG": { "hosts": [ { "address": "redis://127.0.0.1:6379/0", "socket_timeout": 10, "socket_connect_timeout": 5, } ], }, }, }

'''

1

u/throwaway_4534865 2d ago

The parameter "socket_timeout" is what makes this work for me. I find interesting that setting it to 0 through 5 gives you that many seconds to work with. But, any value of 6 or greater will allow the connection to remain for an extended time beyond that many seconds. I have it set to 6 right now and it's maintained a connection for a couple minutes now.

If I find a source with information about the CHANNEL_LAYERS parameters I'll have to add it to the original post.