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

Django Channels对接Angular前端时出现路由错误:找不到socket/order路径

问题:Django Channels与Angular前端对接时WebSocket路由匹配失败

首次使用Django Channels对接现有Angular前端,严格遵循官方文档编写代码后,WebSocket路由仍无法正常匹配,报错信息如下:

Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
January 10, 2023 - 15:34:50
Django version 4.1.3, using settings 'BrokerBackEnd.settings'
Starting ASGI/Daphne version 4.0.0 development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
WebSocket HANDSHAKING /socket/order [127.0.0.1:63732]
HTTP GET /orders/ 200 [0.07, 127.0.0.1:63731]
Exception inside application: No route found for path 'socket/order'.
Traceback (most recent call last):
  File "C:\Users\Neha\Documents\broker-back-end-py\env\lib\site-packages\django\contrib\staticfiles\handlers.py", line 101, in __call__
    return await self.application(scope, receive, send)
  File "C:\Users\Neha\Documents\broker-back-end-py\env\lib\site-packages\channels\routing.py", line 62, in __call__
    return await application(scope, receive, send)
  File "C:\Users\Neha\Documents\broker-back-end-py\env\lib\site-packages\channels\routing.py", line 134, in __call__
    raise ValueError("No route found for path %r." % path)
ValueError: No route found for path 'socket/order'.
WebSocket DISCONNECT /socket/order [127.0.0.1:63732]

相关代码文件

settings.py

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

    'Orders'
]

ASGI_APPLICATION = 'BrokerBackEnd.asgi.application'

asgi.py

import os

from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
import Orders.routing as route

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

application = ProtocolTypeRouter({
    'http': get_asgi_application(),
    
    'websocket': URLRouter(
            route.websocket_urlpatterns
        )
})

consumer.py

class OrderConsumer(WebsocketConsumer):
    def connect(self):
        self.accept()
    
    def receive(self, text_data=None, bytes_data=None):
        self.send(text_data="Message = " + text_data)
    
    def disconnect(self, code):
        return super().disconnect(code)

routing.py(Orders应用下)

from django.urls import re_path
from .consumer import OrderConsumer

websocket_urlpatterns = [
    re_path(r"socket/order/", OrderConsumer.as_asgi())
]

Angular前端代码

import { catchError, map } from 'rxjs/operators';
import { Injectable } from "@angular/core";
import { EMPTY, Observable } from "rxjs";
import { webSocket, WebSocketSubject } from 'rxjs/webSocket';
import { Order } from './order.model';
import { MatSnackBar } from '@angular/material/snack-bar';

@Injectable({
    providedIn: 'root'
})
export class OrderWebSocketService {

    myWebSocket: WebSocketSubject<Order> = webSocket('ws://localhost:8000/socket/order');

    constructor(private snackBar: MatSnackBar) { }

    public connect(): Observable<Order> {
        return this.myWebSocket.asObservable().pipe(
            map((obj) => obj),
            catchError((error) => this.errorHandler(error))
        );
    }

    public close(): void {
        this.myWebSocket.complete();
    }

    errorHandler(e: any): Observable<any> {
        this.showMessage('Something wrong happened with websocket!', true);
        return EMPTY;
    }

    showMessage(msg: string, isError: boolean = false): void {
        this.snackBar.open(msg, 'X', {
            duration: 3000,
            horizontalPosition: "right",
            verticalPosition: "top",
            panelClass: isError ? ['msg-error'] : ['msg-success']
        });
    }
    
}

解决建议

1. 修正路由正则匹配规则

当前后端路由正则r"socket/order/"要求路径结尾必须带斜杠,但前端请求的是/socket/order(无结尾斜杠),导致匹配失败。修改routing.py的正则表达式,让它兼容带/不带斜杠的请求:

from django.urls import re_path
from .consumer import OrderConsumer

websocket_urlpatterns = [
    re_path(r"^socket/order/?$", OrderConsumer.as_asgi())
]
  • ^:匹配路径开头
  • /?:表示结尾的斜杠是可选的
  • $:匹配路径结尾

2. 确认Consumer的导入是否完整

检查consumer.py是否正确导入了WebsocketConsumer,否则会导致路由无法正确关联到Consumer:

from channels.generic.websocket import WebsocketConsumer

class OrderConsumer(WebsocketConsumer):
    def connect(self):
        self.accept()
    
    def receive(self, text_data=None, bytes_data=None):
        self.send(text_data="Message = " + text_data)
    
    def disconnect(self, code):
        return super().disconnect(code)

3. 验证应用名称与导入路径的大小写一致性

Python对路径和模块名称大小写敏感,确认Orders应用的目录名称、routing.py的位置与asgi.py中的导入语句import Orders.routing as route完全匹配,避免因大小写问题导致路由未正确加载。

4. 检查CORS配置(可选)

如果前端和后端存在跨域情况,确保settings.py中正确配置了CORS允许WebSocket连接:

CORS_ALLOWED_ORIGINS = [
    "http://localhost:4200",  # Angular默认端口
]
# 允许WebSocket的跨域请求
CORS_ALLOW_CREDENTIALS = True

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 11:30:56