98 lines
3.6 KiB
Python
98 lines
3.6 KiB
Python
"""
|
|
WebSocket consumers for configuration updates
|
|
"""
|
|
import json
|
|
import logging
|
|
from channels.generic.websocket import AsyncWebsocketConsumer
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class ConfigConsumer(AsyncWebsocketConsumer):
|
|
"""
|
|
WebSocket consumer for real-time configuration updates
|
|
当管理员修改配置后,通过 WebSocket 实时推送配置变化
|
|
"""
|
|
|
|
async def connect(self):
|
|
"""处理 WebSocket 连接"""
|
|
self.user = self.scope["user"]
|
|
|
|
# 只允许认证用户连接
|
|
if not self.user.is_authenticated:
|
|
await self.close()
|
|
return
|
|
|
|
# 使用全局配置组名,所有用户都能接收配置更新
|
|
self.group_name = "config_updates"
|
|
|
|
# 加入配置更新组
|
|
await self.channel_layer.group_add(
|
|
self.group_name,
|
|
self.channel_name
|
|
)
|
|
|
|
await self.accept()
|
|
logger.info(f"Config WebSocket connected: user_id={self.user.id}, channel={self.channel_name}")
|
|
|
|
async def disconnect(self, close_code):
|
|
"""处理 WebSocket 断开连接"""
|
|
if hasattr(self, 'group_name'):
|
|
await self.channel_layer.group_discard(
|
|
self.group_name,
|
|
self.channel_name
|
|
)
|
|
logger.info(f"Config WebSocket disconnected: user_id={self.user.id}, close_code={close_code}")
|
|
|
|
async def receive(self, text_data):
|
|
"""
|
|
接收客户端消息
|
|
客户端可以发送心跳包或配置更新请求
|
|
"""
|
|
try:
|
|
data = json.loads(text_data)
|
|
message_type = data.get("type")
|
|
|
|
if message_type == "ping":
|
|
# 响应心跳包
|
|
await self.send(text_data=json.dumps({
|
|
"type": "pong",
|
|
"timestamp": data.get("timestamp")
|
|
}))
|
|
elif message_type == "config_update":
|
|
# 处理配置更新请求
|
|
key = data.get("key")
|
|
value = data.get("value")
|
|
if key and value is not None:
|
|
logger.info(f"User {self.user.id} requested config update: {key}={value}")
|
|
# 这里可以添加权限检查,只有管理员才能发送配置更新
|
|
if self.user.is_superuser:
|
|
# 广播配置更新给所有连接的客户端
|
|
await self.channel_layer.group_send(
|
|
self.group_name,
|
|
{
|
|
"type": "config_update",
|
|
"data": {
|
|
"type": "config_update",
|
|
"key": key,
|
|
"value": value
|
|
}
|
|
}
|
|
)
|
|
except json.JSONDecodeError:
|
|
logger.error(f"Invalid JSON received from user {self.user.id}")
|
|
except Exception as e:
|
|
logger.error(f"Error handling message from user {self.user.id}: {str(e)}")
|
|
|
|
async def config_update(self, event):
|
|
"""
|
|
接收来自 channel layer 的配置更新消息并发送给客户端
|
|
这个方法名对应 group_send 中的 type 字段
|
|
"""
|
|
try:
|
|
# 从 event 中提取数据并发送给客户端
|
|
await self.send(text_data=json.dumps(event["data"]))
|
|
logger.debug(f"Sent config update to user {self.user.id}: {event['data']}")
|
|
except Exception as e:
|
|
logger.error(f"Error sending config update to user {self.user.id}: {str(e)}")
|