pythondjangowebsocketredisdjango-channels

Django channels - Not Found: /ws/stock/track/


I'm following this video, but I don't get the same console output as in the video.

My console output:

[20/Feb/2024 19:09:12] "GET /stocktracker/?stockpicker=AAPL&stockpicker=AMGN HTTP/1.1" 200 6449
Not Found: /ws/stock/track/
[20/Feb/2024 19:09:12] "GET /ws/stock/track/?stockpicker=AAPL&stockpicker=AMGN HTTP/1.1" 404 2613

Console output on local site (using py manage.py runserver):

stockpicker=AAPL&stockpicker=AMGN

stocktracker/?stockpicker=AAPL&stockpicker=AMGN:176 WebSocket connection to 'ws://127.0.0.1:8000/ws/stock/track/?stockpicker=AAPL&stockpicker=AMGN' failed: 
(anonymous) @ stocktracker/?stockpicker=AAPL&stockpicker=AMGN:176

asgi.py:

"""
ASGI config for backend project.

It exposes the ASGI callable as a module-level variable named ``application``.

For more information on this file, see
https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/
"""

import os

from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
from channels.auth import AuthMiddlewareStack
from Tradingapp.routing import websocket_urlpatterns

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
# Initialize Django ASGI application early to ensure the AppRegistry
# is populated before importing code that may import ORM models.
django_asgi_app = get_asgi_application()

application = ProtocolTypeRouter({
    "http": django_asgi_app,
    # Just HTTP for now. (We can add other protocols later.)
    "websocket": AuthMiddlewareStack(
      URLRouter(
        websocket_urlpatterns
      )
    )
})

routing.py:

from django.urls import re_path

from . import consumers

websocket_urlpatterns = [
    # Celery data is sent to a "group" and this group has multiple users
    #to listen for the same thing via websockets
    re_path(r'ws/stock/(?P<room_name>\w+)/$', consumers.StockConsumer.as_asgi()),
]

JS connection:

    const roomName = JSON.parse(document.getElementById('room-name').textContent)
    var queryString = window.location.search
    queryString = queryString.substring(1)
    console.log(queryString)
    const stockSocket = new WebSocket('ws://' + window.location.host + '/ws/stock/' + roomName + '/' + '?' + queryString)

consumers.py:

import json

from channels.generic.websocket import AsyncWebsocketConsumer


class StockConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        self.room_name = self.scope["url_route"]["kwargs"]["room_name"]
        self.room_group_name = f"stock_{self.room_name}"

        # Join room group
        await self.channel_layer.group_add(self.room_group_name, self.channel_name)

        await self.accept()

    async def disconnect(self, close_code):
        # Leave room group
        await self.channel_layer.group_discard(self.room_group_name, self.channel_name)

    # Receive message from WebSocket
    async def receive(self, text_data):
        text_data_json = json.loads(text_data)
        message = text_data_json["message"]

        # Send message to room group
        await self.channel_layer.group_send(
            self.room_group_name, {"type": "stock_update", "message": message}
        )

    # Receive message from room group
    async def stock_update(self, event):
        message = event["message"]

        # Send message to WebSocket
        await self.send(text_data=json.dumps({"message": message}))

CHANNEL_LAYERS in settings.py:

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

I looked in other stack overflow questions, like this one, but I couldn't find a solution that helped me


Solution

  • I asked in the Django discord, and a kind man named Vaarun helped me with my issue; I did not install Daphne in my installed apps.

    Not working

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'Tradingapp',
        'corsheaders',
        'rest_framework',
        'django_celery_results',
        'django_celery_beat',
        'channels',
    ]
    

    Working

    INSTALLED_APPS = [
        'daphne',
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'Tradingapp',
        'corsheaders',
        'rest_framework',
        'django_celery_results',
        'django_celery_beat',
        'channels',
    ]
    

    Make sure to run pip install daphne as well.