You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django应用WebSocket连接失败,终端报404错误求解决

Django WebSocket连接失败排查与解决

问题现象

WebSocket连接失败,错误信息:WebSocket connection to 'ws://localhost:8000/ws/chat/cujncvifd/' failed,终端输出Not Found: /ws/chat/cujncvifd/。

相关代码片段

settings.py

INSTALLED_APPS = [
    'channels',
    'common_anime_chat.apps.CommonAnimeChatConfig',
    'users.apps.UsersConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    
]

ASGI_APPLICATION = 'anime_chat_app.routing.application'
CHANNEL_LAYERS = {
    'default':{
        "BACKEND":"channels.layers.InMemoryChannelLayer"
    }
}

asgi.py

import os
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
import common_anime_chat.routing


os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'anime_chat_app.settings')

#the new code about the application you told me to write

主项目目录 routing.py

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
import common_anime_chat.routing

application = ProtocolTypeRouter({
    'websocket':AuthMiddlewareStack(
        URLRouter(
            common_anime_chat.routing.websocket_urlpatterns
        )
    ),
    "http":get_asgi_application(),
   
})

common_anime_chat应用 routings.py

from django.urls import re_path
from . import consumers

websocket_urlpatterns = [
    re_path(r'^ws/chat/(?P<room_name>\w+)/$', consumers.ChatRoomConsumer.as_asgi())
]

consumers.py

from channels.generic.websocket import AsyncWebsocketConsumer
import json

class ChatRoomConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        self.room_name = self.scope['url_route']['kwargs']['room_name']
        self.room_group_name = 'chat_%s' % self.room_name
        await self.channel_layer.group_add(
            self.room_group_name,
            self.channel_name
        )

        await self.accept()

        await self.channel_layer.group_send(
            self.room_group_name,
            {
                'type':'tester_message',
                'tester':'hello world'
            }
        )

    async def tester_message(self, event):
            tester = event['tester']
            await self.send(text_data=json.dumps({
                 'tester':tester,
            }))
    async def disconnect(self, close_code):
        await self.channel_layer.group_discard(
            self.room_group_name,
            self.channel_name
        )

common_anime_chat/urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('', views.home, name='common-anime-chat-home'),
    path('about/', views.about, name='common-anime-chat-about'),
    path('chat/<str:room_name>/', views.room, name='room'),
]

chatroom.html

{% extends 'common_anime_chat/base.html' %}
{% load static %}
{% block stylesheet %}
<link rel="stylesheet" type="text/css" href="{% static 'chatroom.css' %}">
{% endblock stylesheet %}
{% block content %}
<div id="user-hello"></div>

{{ room_name|json_script:"room-name" }}
<script>
    const roomName = JSON.parse(document.getElementById('room-name').textContent);
    console.log(roomName)
    const chatSocket = new WebSocket(
        'ws://' +
        window.location.host +
        '/ws/chat/'+ 
        roomName +
        '/'
    );

    chatSocket.onmessage = function (e) {
        const data = JSON.parse(e.data);
        document.querySelector('#user-hello').innerHTML = (data.tester);
    };
</script>
{% endblock content %}

已尝试的解决方案

  • 在common_anime_chat的routings.py中切换"ws://"与"ws/"
  • 在模板的WebSocket连接代码中移除"ws"
  • 关闭防火墙
  • 重启服务器,更新Django和Channels至最新版本

排查与解决步骤

1. 修复路由文件名不匹配问题

主项目routing.py中导入的是common_anime_chat.routing,但你的应用中WebSocket路由文件名为routings.py(多了一个s),这是导致路由无法被找到的核心原因。

  • 方案一:将common_anime_chat应用中的routings.py重命名为routing.py
  • 方案二:修改主项目routing.py中的导入语句和引用:
    import common_anime_chat.routings
    
    application = ProtocolTypeRouter({
        'websocket':AuthMiddlewareStack(
            URLRouter(
                common_anime_chat.routings.websocket_urlpatterns
            )
        ),
        "http":get_asgi_application(),
    })
    

2. 修正ASGI应用配置

当前asgi.py未正确导出Channels应用实例,修改为:

import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'anime_chat_app.settings')

# 直接复用主项目的路由配置
from anime_chat_app.routing import application

3. 调整WebSocket路由正则匹配规则

如果room_name包含下划线、字母、数字以外的字符(比如连字符),原正则\w+无法匹配,修改为兼容性更强的规则:

websocket_urlpatterns = [
    re_path(r'^ws/chat/(?P<room_name>[^/]+)/$', consumers.ChatRoomConsumer.as_asgi())
]

[^/]+表示匹配除斜杠外的任意字符,覆盖更多room_name场景。

4. 修正消费者中的错误方法

消费者disconnect方法中使用了错误的方法名,Channels中正确的移除分组方法是group_remove,修改为:

async def disconnect(self, close_code):
    await self.channel_layer.group_remove(
        self.room_group_name,
        self.channel_name
    )

5. 确保用正确方式启动服务器

使用Channels兼容的ASGI服务器启动项目,直接运行:

python manage.py runserver

若使用Daphne,先安装再启动:

pip install daphne
daphne anime_chat_app.asgi:application

内容的提问来源于stack exchange,提问作者user21744561

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 00:18:12