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

使用Django Channels开发实时聊天时WebSocket连接报错

Django Channels实时聊天应用WebSocket连接错误解决

问题现象

开发实时聊天应用时,通过房间hash连接WebSocket时抛出以下错误:

ValueError: Socket has not been accepted, so cannot send over it
Exception inside application: Socket has not been accepted, so cannot send over it

问题原因

  1. 核心逻辑错误:在ChatConsumer的connect方法中,先调用self.send()发送消息,再执行self.accept()接受连接。Channels的WebSocketConsumer要求必须先完成连接接受操作,才能向客户端发送数据。
  2. 变量未定义:代码中chat_room = Room.objects.get(hash = hash)里的hash是未定义变量,应使用已获取的room_hash。

修正后的代码

consumers.py

import json
from channels.generic.websocket import WebsocketConsumer
from .models import Room

class ChatConsumer(WebsocketConsumer):
    def connect(self):
        room_hash = self.scope["url_route"]["kwargs"]["room_hash"]
        
        # 优先完成WebSocket连接接受
        self.accept()
        
        # 连接建立后再发送消息
        self.send(text_data=json.dumps({
            'type': 'room_hash',
            'hash': room_hash
        }))

        # 增加异常处理,避免房间不存在导致服务端崩溃
        try:
            chat_room = Room.objects.get(hash=room_hash)
            print(chat_room)
        except Room.DoesNotExist:
            self.send(text_data=json.dumps({
                'type': 'error',
                'message': '指定房间不存在'
            }))
            self.close()

    def disconnect(self):
        pass

    def receive(self, text_data):
        text_data_json = json.loads(text_data)
        message = text_data_json['message']
        print(f"Message is {message}")

关键修改说明

  • 调整self.accept()执行顺序:必须在self.send()之前调用,确保WebSocket连接已建立再传输数据
  • 修复变量引用错误:将hash替换为room_hash,匹配URL路由中获取的变量
  • 增加数据库查询异常处理:避免因房间不存在导致服务端崩溃,同时向客户端返回错误提示

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 10:30:22