Django websocket connection on Render not established

I have a django websocket project I have deployed to render. It isn’t able to establish connection in production but it works perfectly fine testing locally.

Here is the error log;
Not Found: /ws/course-group-chat/5/
127.0.0.1 - - [29/Jan/2024:18:12:03 +0000] “GET /ws/course-group-chat/5/?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzEwMDA0MTQ1LCJpYXQiOjE3MDY1NDgxNDUsImp0aSI6IjQ1NGE5ZWVhZjk5YTRhZmZiZTM4ODYxYWNlZjNkYzk2IiwidXNlcl9pZCI6MSwiZW1haWwiOiJmZWxpeGFjaGlhaEBnbWFpbC5jb20iLCJ1c2VybmFtZSI6IkppbSBCZXJrIn0.vU72Z9oYq04S2nVE8c149OaLpC-7OqADrP2V1nHEKDo HTTP/1.1” 404 2789 “-” “Go-http-client/1.1”

This is my ‘Procfile’;
web: gunicorn Skuluu.wsgi:application -w 4
websocket: daphne Skuluu.asgi:application -p $PORT -b 0.0.0.0

asgi.py
import os
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
from channels.security.websocket import AllowedHostsOriginValidator
from chat.middlewares import JWTAuthMiddlewareStack

import chat.routing

os.environ.setdefault(‘DJANGO_SETTINGS_MODULE’, ‘Skuluu.settings’)

application = ProtocolTypeRouter(
{
# Django’s ASGI application to handle traditional HTTP requests
‘http’: get_asgi_application(),

    # WebSocket chat handler
    'websocket': AllowedHostsOriginValidator(
        JWTAuthMiddlewareStack(
            URLRouter(
                chat.routing.websocket_urlpatterns
            )
        )   
    )
}

)

routing.py
from django.urls import re_path
from . import consumers

websocket_urlpatterns = [
re_path(r’ws/course-group-chat/(?P<course_group_id>\d+)/$', consumers.CourseGroupConsumer.as_asgi()),
]

consumers.py
import json
from channels.generic.websocket import AsyncWebsocketConsumer
from channels.db import database_sync_to_async
from .models import CourseGroup, CourseGroupMessage

class CourseGroupConsumer(AsyncWebsocketConsumer):

async def connect(self):
    # Authenticate the user
    if self.scope["user"].is_anonymous:
        await self.close()
        return

    # Extract course_group_id from the URL route
    course_group_id = self.scope['url_route']['kwargs']['course_group_id']

    # Check if the user is a member of the specified course group
    if not self.is_user_in_course_group(self.scope["user"], course_group_id):
        await self.close()
        return

    # Create a unique room name for the course group
    self.room_group_name = f"course_group_{course_group_id}"

    # Add the user to the WebSocket group
    await self.channel_layer.group_add(
        self.room_group_name,
        self.channel_name
    )

    # Accept the WebSocket connection
    await self.accept()

    # Send a connection established message to the user
    await self.send(text_data=json.dumps({
        'type': 'connection_established',
        'message': 'You are now connected!'
    }))

async def disconnect(self, code):
    # Remove the user from the WebSocket group upon disconnection
    if hasattr(self, 'room_group_name') and self.room_group_name:
        # Remove the user from the WebSocket group upon disconnection
        await self.channel_layer.group_discard(
            self.room_group_name,
            self.channel_name
        )

Start command in my render settings is gunicorn Skuluu.wsgi:application

I’m guessing that could be the reason why the websocket connection is not being found.

I think you need to take gunicorn out and just use daphne. Channels won’t work in a wsgi environment.

Follow through the docs here Tutorial Part 1: Basic Setup — Channels 4.0.0 documentation and it’ll take you through serving HTTP and ws via daphne.

Okay, I’ll try that. I literally didn’t know daphne can server both ws and HTTP.
Thanks. I’ll give you a feedback.

1 Like

Hello @KSD89, I added this daphne command, daphne Skuluu.asgi:application -b 0.0.0.0 -p $PORT as the start command on render and this error occurred during deployment.
Error

==> Build successful 🎉 ==> Deploying... ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "<frozen importlib._bootstrap>", line 1204, in _gcd_import File "<frozen importlib._bootstrap>", line 1176, in _find_and_load File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 690, in _load_unlocked File "<frozen importlib._bootstrap_external>", line 940, in exec_module File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed File "/opt/render/project/src/Skuluu/asgi.py", line 15, in <module> from chat.middlewares import JWTAuthMiddlewareStack File "/opt/render/project/src/chat/middlewares.py", line 2, in <module> from rest_framework_simplejwt.authentication import JWTAuthentication File "/opt/render/project/src/.venv/lib/python3.11/site-packages/rest_framework_simplejwt/authentication.py", line 4, in <module> from django.contrib.auth.models import AbstractBaseUser File "/opt/render/project/src/.venv/lib/python3.11/site-packages/django/contrib/auth/models.py", line 3, in <module> from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager File "/opt/render/project/src/.venv/lib/python3.11/site-packages/django/contrib/auth/base_user.py", line 57, in <module> class AbstractBaseUser(models.Model): File "/opt/render/project/src/.venv/lib/python3.11/site-packages/django/db/models/base.py", line 129, in __new__ app_config = apps.get_containing_app_config(module) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/render/project/src/.venv/lib/python3.11/site-packages/django/apps/registry.py", line 260, in get_containing_app_config self.check_apps_ready() File "/opt/render/project/src/.venv/lib/python3.11/site-packages/django/apps/registry.py", line 138, in check_apps_ready raise AppRegistryNotReady("Apps aren't loaded yet.") django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet. ==> Common ways to troubleshoot your deploy: https://docs.render.com/troubleshooting-deploys ==> Using Node version 20.10.0 (default) ==> Docs on specifying a Node version: https://render.com/docs/node-version ==> Running 'daphne Skuluu.asgi:application -b 0.0.0.0 -p $PORT' Traceback (most recent call last): File "/opt/render/project/src/.venv/bin/daphne", line 8, in <module> sys.exit(CommandLineInterface.entrypoint()) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/render/project/src/.venv/lib/python3.11/site-packages/daphne/cli.py", line 171, in entrypoint cls().run(sys.argv[1:]) File "/opt/render/project/src/.venv/lib/python3.11/site-packages/daphne/cli.py", line 233, in run application = import_by_path(args.application) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/render/project/src/.venv/lib/python3.11/site-packages/daphne/utils.py", line 12, in import_by_path target = importlib.import_module(module_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/importlib/__init__.py", line 126, in import_module return _bootstrap._gcd_import(name[level:], package, level) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "<frozen importlib._bootstrap>", line 1204, in _gcd_import File "<frozen importlib._bootstrap>", line 1176, in _find_and_load File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 690, in _load_unlocked File "<frozen importlib._bootstrap_external>", line 940, in exec_module File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed File "/opt/render/project/src/Skuluu/asgi.py", line 15, in <module> from chat.middlewares import JWTAuthMiddlewareStack File "/opt/render/project/src/chat/middlewares.py", line 2, in <module> from rest_framework_simplejwt.authentication import JWTAuthentication File "/opt/render/project/src/.venv/lib/python3.11/site-packages/rest_framework_simplejwt/authentication.py", line 4, in <module> from django.contrib.auth.models import AbstractBaseUser File "/opt/render/project/src/.venv/lib/python3.11/site-packages/django/contrib/auth/models.py", line 3, in <module> from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager File "/opt/render/project/src/.venv/lib/python3.11/site-packages/django/contrib/auth/base_user.py", line 57, in <module> class AbstractBaseUser(models.Model): File "/opt/render/project/src/.venv/lib/python3.11/site-packages/django/db/models/base.py", line 129, in __new__ app_config = apps.get_containing_app_config(module) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/render/project/src/.venv/lib/python3.11/site-packages/django/apps/registry.py", line 260, in get_containing_app_config self.check_apps_ready() File "/opt/render/project/src/.venv/lib/python3.11/site-packages/django/apps/registry.py", line 138, in check_apps_ready raise AppRegistryNotReady("Apps aren't loaded yet.") django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet. ==> Using Node version 20.10.0 (default) ==> Docs on specifying a Node version: https://render.com/docs/node-version ==> Running 'daphne Skuluu.asgi:application -b 0.0.0.0 -p $PORT' Traceback (most recent call last): File "/opt/render/project/src/.venv/bin/daphne", line 8, in <module> sys.exit(CommandLineInterface.entrypoint()) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/render/project/src/.venv/lib/python3.11/site-packages/daphne/cli.py", line 171, in entrypoint cls().run(sys.argv[1:]) File "/opt/render/project/src/.venv/lib/python3.11/site-packages/daphne/cli.py", line 233, in run application = import_by_path(args.application) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/render/project/src/.venv/lib/python3.11/site-packages/daphne/utils.py", line 12, in import_by_path target = importlib.import_module(module_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/importlib/__init__.py", line 126, in import_module return _bootstrap._gcd_import(name[level:], package, level) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "<frozen importlib._bootstrap>", line 1204, in _gcd_import File "<frozen importlib._bootstrap>", line 1176, in _find_and_load File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 690, in _load_unlocked File "<frozen importlib._bootstrap_external>", line 940, in exec_module File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed File "/opt/render/project/src/Skuluu/asgi.py", line 15, in <module> from chat.middlewares import JWTAuthMiddlewareStack File "/opt/render/project/src/chat/middlewares.py", line 2, in <module> from rest_framework_simplejwt.authentication import JWTAuthentication File "/opt/render/project/src/.venv/lib/python3.11/site-packages/rest_framework_simplejwt/authentication.py", line 4, in <module> from django.contrib.auth.models import AbstractBaseUser File "/opt/render/project/src/.venv/lib/python3.11/site-packages/django/contrib/auth/models.py", line 3, in <module> from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager File "/opt/render/project/src/.venv/lib/python3.11/site-packages/django/contrib/auth/base_user.py", line 57, in <module> class AbstractBaseUser(models.Model): File "/opt/render/project/src/.venv/lib/python3.11/site-packages/django/db/models/base.py", line 129, in __new__ app_config = apps.get_containing_app_config(module) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/render/project/src/.venv/lib/python3.11/site-packages/django/apps/registry.py", line 260, in get_containing_app_config self.check_apps_ready() File "/opt/render/project/src/.venv/lib/python3.11/site-packages/django/apps/registry.py", line 138, in check_apps_ready raise AppRegistryNotReady("Apps aren't loaded yet.") django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.

Can you paste your asgi.py file?

Sure.

Updates on the error, I figured it out.
I had to bring in these codes in this arrangement.
`import os

Set the Django settings module

os.environ.setdefault(‘DJANGO_SETTINGS_MODULE’, ‘Skuluu.settings’)

import django

Call django.setup() to populate Django’s application registry

django.setup()`

But now I’m getting a different error related to authentication. Since I’m using daphne for both HTTP and Websocket requests.

I get an error logging in via the http protocol.
Here’s the error;

Your service is live 🎉 2024-01-30 13:21:50,646 ERROR Internal Server Error: / Traceback (most recent call last): File "/opt/render/project/src/.venv/lib/python3.11/site-packages/django/core/handlers/exception.py", line 55, in inner response = get_response(request) ^^^^^^^^^^^^^^^^^^^^^ TypeError: JWTAuthMiddleware.__call__() missing 2 required positional arguments: 'receive' and 'send' 2024-01-30 13:27:01,724 ERROR Internal Server Error: /api/user-auth/login/ Traceback (most recent call last): File "/opt/render/project/src/.venv/lib/python3.11/site-packages/django/core/handlers/exception.py", line 55, in inner response = get_response(request) ^^^^^^^^^^^^^^^^^^^^^ TypeError: JWTAuthMiddleware.__call__() missing 2 required positional arguments: 'receive' and 'send'

Here’s my middlewares and asgi code respectively,

middlewares.py

`from channels.auth import AuthMiddlewareStack
from django.contrib.auth.models import AnonymousUser
from django.db import close_old_connections
from jwt import decode as jwt_decode
from django.conf import settings
from user_auth.models import User
from channels.db import database_sync_to_async

class JWTAuthMiddleware:
def init(self, inner):
self.inner = inner

async def __call__(self, scope, receive, send):
    close_old_connections()
    query_string = scope.get('query_string', b'').decode()
    headers = dict(scope['headers'])

    # Extract JWT token from query parameters or headers
    if 'token' in query_string:
        token = query_string.split('=')[1]
    elif b'authorization' in headers:
        token = headers[b'authorization'].decode().split()[1]
    else:
        token = None


    if token:
        try:
            # Decode JWT token and get user_id
            payload = jwt_decode(token, settings.SECRET_KEY, algorithms=['HS256'])

            user_id = payload['user_id']

            # Fetch user object from the database asynchronously
            user = await self.get_user_by_id(user_id)
            scope['user'] = user

        except Exception as e:
            scope['user'] = AnonymousUser()

    return await self.inner(scope, receive, send)

@staticmethod
@database_sync_to_async
def get_user_by_id(user_id):
    return User.objects.get(id=user_id)

def JWTAuthMiddlewareStack(inner):
return JWTAuthMiddleware(AuthMiddlewareStack(inner))
`

asgi.py

`
import os

Set the Django settings module

os.environ.setdefault(‘DJANGO_SETTINGS_MODULE’, ‘Skuluu.settings’)

import django

Call django.setup() to populate Django’s application registry

django.setup()

from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
from channels.security.websocket import AllowedHostsOriginValidator
from chat.middlewares import JWTAuthMiddlewareStack
import chat.routing

Get the ASGI application for Django

django_asgi_app = get_asgi_application()

Define the WebSocket application

application = ProtocolTypeRouter({
# Handle traditional HTTP requests
‘http’: django_asgi_app,

# Handle WebSocket connections with JWT authentication middleware
'websocket': AllowedHostsOriginValidator(
    JWTAuthMiddlewareStack(
        URLRouter(chat.routing.websocket_urlpatterns)
    )
),

})
`

Please where you able to fix the issue??

I’ve been trying to get this working too.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.