mirror of
https://github.com/zhinianboke/xianyu-auto-reply.git
synced 2025-08-02 12:37:35 +08:00
修复bug
This commit is contained in:
parent
3aae24920f
commit
4510b65840
7
Start.py
7
Start.py
@ -85,8 +85,13 @@ async def main():
|
||||
print("CookieManager 创建完成")
|
||||
|
||||
# 1) 从数据库加载的 Cookie 已经在 CookieManager 初始化时完成
|
||||
# 为每个 Cookie 启动任务
|
||||
# 为每个启用的 Cookie 启动任务
|
||||
for cid, val in manager.cookies.items():
|
||||
# 检查账号是否启用
|
||||
if not manager.get_cookie_status(cid):
|
||||
logger.info(f"跳过禁用的 Cookie: {cid}")
|
||||
continue
|
||||
|
||||
try:
|
||||
await manager._add_cookie_async(cid, val)
|
||||
logger.info(f"启动数据库中的 Cookie 任务: {cid}")
|
||||
|
@ -1322,6 +1322,12 @@ class XianyuLive:
|
||||
"""Token刷新循环"""
|
||||
while True:
|
||||
try:
|
||||
# 检查账号是否启用
|
||||
from cookie_manager import manager as cookie_manager
|
||||
if cookie_manager and not cookie_manager.get_cookie_status(self.cookie_id):
|
||||
logger.info(f"【{self.cookie_id}】账号已禁用,停止Token刷新循环")
|
||||
break
|
||||
|
||||
current_time = time.time()
|
||||
if current_time - self.last_token_refresh_time >= self.token_refresh_interval:
|
||||
logger.info("Token即将过期,准备刷新...")
|
||||
@ -1480,6 +1486,12 @@ class XianyuLive:
|
||||
"""心跳循环"""
|
||||
while True:
|
||||
try:
|
||||
# 检查账号是否启用
|
||||
from cookie_manager import manager as cookie_manager
|
||||
if cookie_manager and not cookie_manager.get_cookie_status(self.cookie_id):
|
||||
logger.info(f"【{self.cookie_id}】账号已禁用,停止心跳循环")
|
||||
break
|
||||
|
||||
await self.send_heartbeat(ws)
|
||||
await asyncio.sleep(self.heartbeat_interval)
|
||||
except Exception as e:
|
||||
@ -1673,6 +1685,12 @@ class XianyuLive:
|
||||
async def handle_message(self, message_data, websocket):
|
||||
"""处理所有类型的消息"""
|
||||
try:
|
||||
# 检查账号是否启用
|
||||
from cookie_manager import manager as cookie_manager
|
||||
if cookie_manager and not cookie_manager.get_cookie_status(self.cookie_id):
|
||||
logger.debug(f"【{self.cookie_id}】账号已禁用,跳过消息处理")
|
||||
return
|
||||
|
||||
# 发送确认消息
|
||||
try:
|
||||
message = message_data
|
||||
@ -2122,6 +2140,12 @@ class XianyuLive:
|
||||
await self.create_session() # 创建session
|
||||
while True:
|
||||
try:
|
||||
# 检查账号是否启用
|
||||
from cookie_manager import manager as cookie_manager
|
||||
if cookie_manager and not cookie_manager.get_cookie_status(self.cookie_id):
|
||||
logger.info(f"【{self.cookie_id}】账号已禁用,停止主循环")
|
||||
break
|
||||
|
||||
headers = WEBSOCKET_HEADERS.copy()
|
||||
headers['Cookie'] = self.cookies_str
|
||||
|
||||
|
@ -190,11 +190,21 @@ class CookieManager:
|
||||
if cookie_id not in self.cookies:
|
||||
raise ValueError(f"Cookie ID {cookie_id} 不存在")
|
||||
|
||||
old_status = self.cookie_status.get(cookie_id, True)
|
||||
self.cookie_status[cookie_id] = enabled
|
||||
# 保存到数据库
|
||||
db_manager.save_cookie_status(cookie_id, enabled)
|
||||
logger.info(f"更新Cookie状态: {cookie_id} -> {'启用' if enabled else '禁用'}")
|
||||
|
||||
# 如果状态发生变化,需要启动或停止任务
|
||||
if old_status != enabled:
|
||||
if enabled:
|
||||
# 启用账号:启动任务
|
||||
self._start_cookie_task(cookie_id)
|
||||
else:
|
||||
# 禁用账号:停止任务
|
||||
self._stop_cookie_task(cookie_id)
|
||||
|
||||
def get_cookie_status(self, cookie_id: str) -> bool:
|
||||
"""获取Cookie的启用状态"""
|
||||
return self.cookie_status.get(cookie_id, True) # 默认启用
|
||||
@ -204,6 +214,55 @@ class CookieManager:
|
||||
return {cid: value for cid, value in self.cookies.items()
|
||||
if self.cookie_status.get(cid, True)}
|
||||
|
||||
def _start_cookie_task(self, cookie_id: str):
|
||||
"""启动指定Cookie的任务"""
|
||||
if cookie_id in self.tasks:
|
||||
logger.warning(f"Cookie任务已存在,跳过启动: {cookie_id}")
|
||||
return
|
||||
|
||||
cookie_value = self.cookies.get(cookie_id)
|
||||
if not cookie_value:
|
||||
logger.error(f"Cookie值不存在,无法启动任务: {cookie_id}")
|
||||
return
|
||||
|
||||
try:
|
||||
# 获取Cookie对应的user_id
|
||||
cookie_info = db_manager.get_cookie_details(cookie_id)
|
||||
user_id = cookie_info.get('user_id') if cookie_info else None
|
||||
|
||||
# 使用异步方式启动任务
|
||||
if hasattr(self.loop, 'is_running') and self.loop.is_running():
|
||||
# 事件循环正在运行,使用run_coroutine_threadsafe
|
||||
fut = asyncio.run_coroutine_threadsafe(
|
||||
self._add_cookie_async(cookie_id, cookie_value, user_id),
|
||||
self.loop
|
||||
)
|
||||
fut.result(timeout=5) # 等待最多5秒
|
||||
else:
|
||||
# 事件循环未运行,直接创建任务
|
||||
task = self.loop.create_task(self._run_xianyu(cookie_id, cookie_value, user_id))
|
||||
self.tasks[cookie_id] = task
|
||||
|
||||
logger.info(f"成功启动Cookie任务: {cookie_id}")
|
||||
except Exception as e:
|
||||
logger.error(f"启动Cookie任务失败: {cookie_id}, {e}")
|
||||
|
||||
def _stop_cookie_task(self, cookie_id: str):
|
||||
"""停止指定Cookie的任务"""
|
||||
if cookie_id not in self.tasks:
|
||||
logger.warning(f"Cookie任务不存在,跳过停止: {cookie_id}")
|
||||
return
|
||||
|
||||
try:
|
||||
task = self.tasks[cookie_id]
|
||||
if not task.done():
|
||||
task.cancel()
|
||||
logger.info(f"已取消Cookie任务: {cookie_id}")
|
||||
del self.tasks[cookie_id]
|
||||
logger.info(f"成功停止Cookie任务: {cookie_id}")
|
||||
except Exception as e:
|
||||
logger.error(f"停止Cookie任务失败: {cookie_id}, {e}")
|
||||
|
||||
|
||||
# 在 Start.py 中会把此变量赋值为具体实例
|
||||
manager: Optional[CookieManager] = None
|
121
账号禁用功能修复说明.md
Normal file
121
账号禁用功能修复说明.md
Normal file
@ -0,0 +1,121 @@
|
||||
# 账号禁用功能修复说明
|
||||
|
||||
## 问题分析
|
||||
|
||||
在原有的代码中,账号禁用功能存在以下问题:
|
||||
|
||||
### 1. 账号状态检查不完整
|
||||
- `reply_server.py` 中的 `match_reply` 函数虽然有账号状态检查,但只影响关键词匹配回复
|
||||
- `XianyuAutoAsync.py` 的消息处理流程中没有检查账号的启用/禁用状态
|
||||
- Token刷新、心跳、WebSocket连接等核心功能都没有账号状态检查
|
||||
|
||||
### 2. 任务管理机制缺陷
|
||||
- 账号禁用时,对应的 `XianyuLive` 任务(WebSocket连接、token刷新任务等)并没有被停止
|
||||
- `cookie_manager.py` 中的 `update_cookie_status` 方法只更新了状态,但没有停止或启动相应的任务
|
||||
- 任务一旦启动就会持续运行,不受账号状态影响
|
||||
|
||||
### 3. 重启后token刷新的原因
|
||||
- `Start.py` 启动时会为所有数据库中的Cookie启动任务,不管其启用状态
|
||||
- `XianyuAutoAsync.py` 中的token刷新是独立的定时任务,一旦启动就会持续运行
|
||||
|
||||
## 解决方案
|
||||
|
||||
### 1. 修改XianyuAutoAsync消息处理流程
|
||||
|
||||
**文件**: `XianyuAutoAsync.py`
|
||||
|
||||
**修改内容**:
|
||||
- 在 `handle_message` 方法开头添加账号状态检查
|
||||
- 在 `main` 方法的主循环中添加账号状态检查
|
||||
- 在 `token_refresh_loop` 方法中添加账号状态检查
|
||||
- 在 `heartbeat_loop` 方法中添加账号状态检查
|
||||
|
||||
**效果**: 禁用的账号将不再处理消息、刷新token或发送心跳
|
||||
|
||||
### 2. 修改CookieManager任务管理
|
||||
|
||||
**文件**: `cookie_manager.py`
|
||||
|
||||
**修改内容**:
|
||||
- 在 `update_cookie_status` 方法中添加任务启动/停止逻辑
|
||||
- 新增 `_start_cookie_task` 方法用于启动指定账号的任务
|
||||
- 新增 `_stop_cookie_task` 方法用于停止指定账号的任务
|
||||
|
||||
**效果**:
|
||||
- 禁用账号时立即停止相关任务
|
||||
- 启用账号时立即启动相关任务
|
||||
|
||||
### 3. 修改Start.py启动逻辑
|
||||
|
||||
**文件**: `Start.py`
|
||||
|
||||
**修改内容**:
|
||||
- 启动时检查每个账号的启用状态
|
||||
- 只为启用状态的账号创建任务
|
||||
- 跳过禁用的账号
|
||||
|
||||
**效果**: 重启后禁用的账号不会自动启动任务
|
||||
|
||||
## 修改后的工作流程
|
||||
|
||||
### 账号禁用时
|
||||
1. 用户在管理界面点击禁用账号
|
||||
2. 前端调用 `/cookies/{cid}/status` API
|
||||
3. `cookie_manager.update_cookie_status` 被调用
|
||||
4. 状态更新到数据库和内存
|
||||
5. 检测到状态变化,调用 `_stop_cookie_task`
|
||||
6. 取消对应的异步任务
|
||||
7. 正在运行的 `XianyuLive` 实例在下次循环时检测到状态变化并退出
|
||||
|
||||
### 账号启用时
|
||||
1. 用户在管理界面点击启用账号
|
||||
2. 前端调用 `/cookies/{cid}/status` API
|
||||
3. `cookie_manager.update_cookie_status` 被调用
|
||||
4. 状态更新到数据库和内存
|
||||
5. 检测到状态变化,调用 `_start_cookie_task`
|
||||
6. 创建新的异步任务启动 `XianyuLive` 实例
|
||||
|
||||
### 系统重启时
|
||||
1. `Start.py` 从数据库加载所有Cookie
|
||||
2. 检查每个Cookie的启用状态
|
||||
3. 只为启用状态的Cookie创建任务
|
||||
4. 禁用的Cookie被跳过
|
||||
|
||||
## 关键代码片段
|
||||
|
||||
### 消息处理中的状态检查
|
||||
```python
|
||||
async def handle_message(self, message_data, websocket):
|
||||
# 检查账号是否启用
|
||||
from cookie_manager import manager as cookie_manager
|
||||
if cookie_manager and not cookie_manager.get_cookie_status(self.cookie_id):
|
||||
logger.debug(f"【{self.cookie_id}】账号已禁用,跳过消息处理")
|
||||
return
|
||||
```
|
||||
|
||||
### 任务管理逻辑
|
||||
```python
|
||||
def update_cookie_status(self, cookie_id: str, enabled: bool):
|
||||
old_status = self.cookie_status.get(cookie_id, True)
|
||||
self.cookie_status[cookie_id] = enabled
|
||||
db_manager.save_cookie_status(cookie_id, enabled)
|
||||
|
||||
# 如果状态发生变化,需要启动或停止任务
|
||||
if old_status != enabled:
|
||||
if enabled:
|
||||
self._start_cookie_task(cookie_id)
|
||||
else:
|
||||
self._stop_cookie_task(cookie_id)
|
||||
```
|
||||
|
||||
## 测试验证
|
||||
|
||||
可以使用提供的 `test_account_disable.py` 脚本来测试账号禁用功能是否正常工作。
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **立即生效**: 修改后账号禁用/启用将立即生效,无需重启系统
|
||||
2. **资源清理**: 禁用账号时会正确清理相关的异步任务和资源
|
||||
3. **状态持久化**: 账号状态会保存到数据库,重启后保持一致
|
||||
4. **错误处理**: 添加了完善的错误处理和日志记录
|
||||
5. **向后兼容**: 修改不影响现有功能,保持向后兼容性
|
Loading…
x
Reference in New Issue
Block a user