0

I'm trying to write my first Django project using websockets. I use django channels. And everything worked fine until the time to integrate react, nginx and django came.

Now I get:

Could not connect to wss://our.web.site/ws/notifications/id/?token={my_token}

Request URL: https://our.web.site/ws/notifications/id/?token={my_token}

Request Method: GET

Status code: 404 Not Found

My asgi.py:

import os

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

from apps.notifications.middlewares import JwtAuthMiddlewareStack
from apps.notifications.routing import websocket_urlpatterns

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")

# application = get_asgi_application()

application = ProtocolTypeRouter(
    {
        "http": get_asgi_application(),
        "websocket": AllowedHostsOriginValidator(
            JwtAuthMiddlewareStack(URLRouter(websocket_urlpatterns))
        ),
    }
)

my routing.py:

from django.urls import re_path

from . import consumers

websocket_urlpatterns = [
    re_path(r"ws/notifications/(?P<user_id>\w+)/$", consumers.NotificationConsumer.as_asgi()),
]

my consumers.py:

import json

from channels.db import database_sync_to_async
from channels.generic.websocket import AsyncWebsocketConsumer

from apps.notifications.models import Notification, OnlineUser


class NotificationConsumer(AsyncWebsocketConsumer):
    def __init__(self, *args, **kwargs):
        super().__init__(args, kwargs)
        self.user = None
        self.pool_name = None

    async def connect(self):
        self.user = self.scope["user"]
        self.pool_name = f"user_id_{self.user.id}"
        await self.accept()

        await self.channel_layer.group_add(
            self.pool_name,
            self.channel_name,
        )
        await self.add_online_user()

    async def disconnect(self, close_code):
        await self.remove_online_user()
        await self.channel_layer.group_discard(self.pool_name, self.channel_name)

    async def receive(self, text_data):
        text_data_json = json.loads(text_data)
        message = text_data_json["message"]
        await self.channel_layer.group_send(self.pool_name, {"type": "read_message", "message": message})

    async def read_message(self, event):
        message = event["message"]
        await self.mark_notifications_as_read(message)
        await self.send(text_data=json.dumps({"message": message, "message_type": "read_message"}, ensure_ascii=False))

    async def notification_message(self, event):
        message = event["message"]
        await self.send(text_data=json.dumps({"message": message}, ensure_ascii=False))

    @database_sync_to_async
    def mark_notifications_as_read(self, notification):
        Notification.objects.filter(
            object_id=notification["contentObjectId"], for_user=notification["userId"], type=notification["type"]
        ).update(read=True)

    @database_sync_to_async
    def add_online_user(self):
        OnlineUser.objects.get_or_create(user=self.user)

    @database_sync_to_async
    def remove_online_user(self):
        OnlineUser.objects.filter(user=self.user).delete()

nginx:

    location /ws/ {
        proxy_pass          http://127.0.0.1:8000;
        proxy_http_version 1.1;
        proxy_set_header    Upgrade $http_upgrade;
        proxy_set_header    Connection $connection_upgrade;
        proxy_set_header    Host $server_name;
        proxy_set_header    X-Forwarded-Proto $scheme;
        proxy_set_header    X-Forwarded-For $remote_addr;
    }

I'm not sure that error is connected with backend and I will be glad if someone can help me to find out with what the error is connected.

1

0