Django Channels实现MQTT over WebSocket时连接重启及视图发消息问题
Socket反复重启故障解决
- 语法错误修复:你提供的
ChatTwoConsumer中connect方法没有正确缩进,不属于类内部方法,运行会触发语法错误导致连接断开,客户端自动重连就会出现反复重启的现象,修正后代码如下:
# consumer.py class ChatTwoConsumer(WebsocketConsumer): def connect(self): print('here') self.accept()
- MQTT协议适配:默认
WebsocketConsumer仅处理基础WebSocket连接,MQTT over WebSocket场景下,客户端在WebSocket连接建立后会发送MQTT CONNECT握手报文,你当前代码没有返回对应的CONNACK响应,客户端判定握手失败主动断开触发重连。你需要额外实现receive方法解析MQTT报文并按协议规范返回响应,也可以直接复用现有封装好的MQTT over WebSocket处理逻辑简化开发。 - 路由规则修正:
routing.py中的mqtt路由正则r'mqtt'没有加首尾匹配符,会匹配所有包含mqtt字段的路径,可能触发异常路由,建议修改为:
re_path(r'^mqtt/$', consumer.ChatTwoConsumer.as_asgi())
视图层发送消息实现
通过Channels自带的Channel Layer即可实现视图层到Consumer的消息推送,操作步骤如下:
- 首先确认你已经完成Channel Layer配置(推荐使用Redis作为后端存储),之后修改Consumer代码,将连接按主题加入对应分组:
from channels.generic.websocket import WebsocketConsumer from asgiref.sync import async_to_sync class ChatTwoConsumer(WebsocketConsumer): def connect(self): self.accept() # 此处替换为当前用户授权可访问的MQTT主题对应的分组名 self.topic_group = "mqtt_auth_topic_01" # 将当前连接加入主题分组 async_to_sync(self.channel_layer.group_add)( self.topic_group, self.channel_name ) def disconnect(self, close_code): # 断开连接时移出分组 async_to_sync(self.channel_layer.group_discard)( self.topic_group, self.channel_name ) # 分组消息处理方法,方法名对应group_send时的type参数,点替换为下划线 def push_topic_data(self, event): payload = event['payload'] self.send(text_data=payload)
- 视图层调用Channel Layer的group_send方法推送消息:
from django.http import HttpResponse from channels.layers import get_channel_layer from asgiref.sync import async_to_sync def push_mqtt_data(request): channel_layer = get_channel_layer() # 往指定主题分组推送数据,所有加入该分组的连接都会收到消息 async_to_sync(channel_layer.group_send)( "mqtt_auth_topic_01", { "type": "push_topic_data", "payload": "需要推送的主题数据内容" } ) return HttpResponse("推送完成")
内容的提问来源于stack exchange,提问作者Ashish bansal
相关产品推荐
相关产品推荐

