使用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
问题原因
- 核心逻辑错误:在
ChatConsumer的connect方法中,先调用self.send()发送消息,再执行self.accept()接受连接。Channels的WebSocketConsumer要求必须先完成连接接受操作,才能向客户端发送数据。 - 变量未定义:代码中
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
相关产品推荐
相关产品推荐

