17 KiB
修改记录
2025-08-11
WebSocket SSL证书验证冲突修复
问题:WebSocket客户端连接时出现SSL配置冲突错误
Cannot set verify_mode to CERT_NONE when check_hostname is enabled.
根本原因:在SSL上下文中,当设置verify_mode = ssl.CERT_NONE时,如果check_hostname仍然为True,就会出现配置冲突。
解决方案:修复SSL配置逻辑,确保当不验证证书时同时禁用主机名检查
文件变更:
- 更新
app/core/websocket/client.py- 修复SSL配置冲突
修改内容:
# 根据配置决定是否验证证书和主机名
# 先设置check_hostname,再设置verify_mode
if not config.websocket.ssl_verify_hostname:
ssl_context.check_hostname = False
if not config.websocket.ssl_verify_certificate:
ssl_context.verify_mode = ssl.CERT_NONE
修复逻辑:
- 先设置
check_hostname,再设置verify_mode,避免配置冲突 - 当
ssl_verify_hostname = False时,设置check_hostname = False - 当
ssl_verify_certificate = False时,设置verify_mode = ssl.CERT_NONE - 确保SSL配置的正确顺序和一致性
配置建议:
# 开发环境(跳过所有SSL验证)
WEBSOCKET_SSL_VERIFY_CERTIFICATE=false
WEBSOCKET_SSL_VERIFY_HOSTNAME=false
# 生产环境(启用SSL验证)
WEBSOCKET_SSL_VERIFY_CERTIFICATE=true
WEBSOCKET_SSL_VERIFY_HOSTNAME=true
注意事项:
- 修复了SSL配置冲突问题
- 保持了配置的灵活性
- 开发环境默认跳过SSL验证
- 生产环境建议启用SSL验证
测试验证:
创建了 test_websocket_ssl_fix.py 测试脚本验证修复效果:
python test_websocket_ssl_fix.py
测试结果:
- ✅ 配置值测试通过
- ✅ WebSocket客户端创建测试通过
- ✅ SSL配置逻辑测试通过
- ✅ 所有测试通过,修复成功
WebSocket SSL证书验证问题修复
WebSocket SSL证书验证问题修复
问题:WebSocket客户端连接时出现SSL证书验证失败错误
[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate (_ssl.c:997)
解决方案:在WebSocket客户端连接时跳过SSL证书验证(仅用于开发测试)
文件变更:
- 更新
app/core/websocket/client.py- 在connect方法中添加SSL证书验证跳过逻辑
修改内容:
# 建立WebSocket连接
# 根据配置决定是否跳过SSL证书验证
ssl_context = None
if self.url.startswith('wss://'):
from app.core.config.settings import config
import ssl
ssl_context = ssl.create_default_context()
# 根据配置决定是否验证证书和主机名
if not config.websocket.ssl_verify_certificate:
ssl_context.verify_mode = ssl.CERT_NONE
if not config.websocket.ssl_verify_hostname:
ssl_context.check_hostname = False
self._websocket = await websockets.connect(self.url, ssl=ssl_context)
配置化设计:
- 在
app/core/config/settings.py中添加WebSocketConfig类 - 支持通过环境变量或配置文件控制SSL验证行为
- 默认开发环境跳过证书验证,生产环境可通过配置启用
环境变量配置:
# 开发环境(跳过SSL验证)
WEBSOCKET_SSL_VERIFY_CERTIFICATE=false
WEBSOCKET_SSL_VERIFY_HOSTNAME=false
# 生产环境(启用SSL验证)
WEBSOCKET_SSL_VERIFY_CERTIFICATE=true
WEBSOCKET_SSL_VERIFY_HOSTNAME=true
注意事项:
- 开发环境默认跳过SSL证书验证
- 生产环境建议启用SSL证书验证
- 可通过环境变量灵活配置
相关修改:
- 启用
requirements.txt中的websockets==12.0依赖 - 添加
WebSocketConfig配置类到app/core/config/settings.py - 创建
test_websocket_ssl.py测试脚本验证修复效果
测试验证: 运行测试脚本验证修复效果:
python test_websocket_ssl.py
2025-08-07
日志系统简化优化
问题:用户要求简化日志系统,不要创建太多日志文件,只分异常和非异常两种
解决方案:重构日志系统,只创建两个日志文件:
logs/app.log- 正常日志(DEBUG、INFO、WARNING级别)logs/error.log- 异常日志(ERROR、CRITICAL级别)
文件变更:
- 更新
app/utils/structured_log.py- 重构_setup_handlers()方法
优化内容:
# 根据日志级别选择文件
# ERROR和CRITICAL级别写入异常日志文件
# 其他级别写入正常日志文件
error_handler = logging.FileHandler("logs/error.log", encoding='utf-8')
error_handler.setLevel(logging.ERROR)
error_handler.setFormatter(StructuredFormatter(include_stack_trace=True))
normal_handler = logging.FileHandler("logs/app.log", encoding='utf-8')
normal_handler.setLevel(logging.DEBUG)
normal_handler.setFormatter(StructuredFormatter(include_stack_trace=False))
优势:
- ✅ 简化日志文件管理,只有两个文件
- ✅ 异常日志包含完整堆栈跟踪
- ✅ 正常日志不包含堆栈跟踪,减少文件大小
- ✅ 按日志级别自动分流
- ✅ 保持控制台输出功能
WebSocket API优化
WebSocket API优化
问题:用户指出"创建Channel请求 不是请求的时候创建",需要优化WebSocket API架构
解决方案:重新设计WebSocket API,使用预创建Channel模式,并简化为只包含获取、连接、停止功能
文件变更:
- 创建
app/schemas/websocket.py- WebSocket相关的Pydantic模型 - 创建
app/utils/api_decorators.py- API错误处理装饰器 - 更新
app/services/websocket_service.py- 支持预创建Channel和初始化配置 - 更新
app/api/v1/endpoints/websocket.py- 使用Pydantic模型,简化为获取、连接、停止功能 - 更新
app/core/app/factory.py- 应用启动时初始化WebSocket服务
架构优化:
1. 预创建Channel模式
- 应用启动时自动创建默认Channel(default, system, events)
- 移除动态创建Channel的API
- 支持配置化的Channel管理
2. 简化的API设计
根据用户要求"websocket.py 应只需要获取 跟 连接 跟 停止",简化为三个核心功能:
获取功能:
GET /websocket/clients- 获取所有客户端GET /websocket/channels- 获取所有ChannelGET /websocket/stats- 获取统计信息
连接功能:
POST /websocket/clients- 创建客户端POST /websocket/clients/{name}/connect- 连接客户端POST /websocket/subscribe- 订阅ChannelPOST /websocket/message/send- 发送消息POST /websocket/message/broadcast- 广播消息
停止功能:
POST /websocket/clients/{name}/disconnect- 断开客户端DELETE /websocket/clients/{name}- 移除客户端POST /websocket/unsubscribe- 取消订阅
3. Pydantic模型验证
- 使用Pydantic进行请求参数验证
- 统一的响应格式
- 类型安全的API接口
4. 错误处理优化
- 统一的错误处理装饰器
- 标准化的错误响应格式
- 更好的错误日志记录
移除的API:
POST /websocket/channels- 动态创建ChannelDELETE /websocket/channels/{name}- 移除ChannelGET /websocket/adapters- 获取适配器POST /websocket/adapters- 创建适配器DELETE /websocket/adapters- 移除适配器POST /websocket/initialize- 初始化服务
配置化设计:
class WebSocketConfig(BaseModel):
default_channels: List[str] = ["default", "system", "events"]
max_channel_size: int = 1000
heartbeat_interval: int = 30
reconnect_attempts: int = 5
reconnect_delay: float = 1.0
优势:
- ✅ 更清晰的API设计,只包含核心功能
- ✅ 预创建Channel,避免运行时创建
- ✅ 统一的参数验证和错误处理
- ✅ 配置化的服务管理
- ✅ 更好的类型安全性
- ✅ 简化的使用流程
WebSocket架构重构
问题:用户反馈"client.py 为啥有 channel 不应该只要读取channel 数据发 接收数据往channel 插入吗",指出WebSocket架构设计不合理。
解决方案:引入适配器模式,重新设计WebSocket架构
- WebSocketClient: 只负责WebSocket连接和数据收发
- WebSocketChannel: 负责数据存储和队列管理
- WebSocketAdapter: 负责连接Client和Channel,实现数据双向流动
文件变更:
- 创建
app/core/websocket/模块 - 创建
app/core/websocket/client.py- WebSocket客户端 - 创建
app/core/websocket/channel.py- 数据通道 - 创建
app/core/websocket/adapter.py- 适配器 - 创建
app/core/websocket/manager.py- 管理器 - 创建
app/services/websocket_service.py- 业务服务 - 创建
app/api/v1/endpoints/websocket.py- API接口
架构优势:
- 遵循单一职责原则
- 清晰的层次结构
- 易于扩展和维护
- 支持数据双向流动
数据流:
WebSocket服务器 ↔ WebSocketClient ↔ WebSocketAdapter ↔ WebSocketChannel
Channel生命周期管理完善
问题:用户指出"没有遵循单一原则是 channel.py他stop 之后能使用吗 ,二次连接webscoket 还能有吗 生命周期"
解决方案:完善Channel的生命周期管理
- 添加
reconnect()方法 - 重新连接功能 - 添加
reset()方法 - 重置状态功能 - 添加
destroy()方法 - 完全销毁功能 - 添加
connection_count属性 - 连接次数统计 - 完善状态管理和错误处理
文件变更:
- 更新
app/core/websocket/channel.py- 完善生命周期管理
功能验证:
- ✅ 支持连接/断开/重连循环
- ✅ 状态管理正确
- ✅ 资源清理完整
- ✅ 二次连接支持
WebSocket Stop方法分析
问题:检查WebSocket架构中各个组件的stop方法是否停止干净,以及二次连接的支持情况
分析结果:
Stop方法停止干净度:✅ 优秀
- WebSocketClient.disconnect(): 正确取消任务、关闭连接、清理资源
- WebSocketAdapter.stop(): 正确取消发送任务、清理消息处理器
- WebSocketManager.cleanup(): 按正确顺序清理所有资源
二次连接支持:✅ 完整
- WebSocketClient: 支持重复连接,状态检查正确
- WebSocketChannel: 支持重新连接,连接次数统计
- WebSocketAdapter: 可以重新启动,任务重新创建
架构优势:
- 所有组件都正确取消异步任务
- 正确清理资源引用
- 状态管理完整
- 支持完整的连接-断开-重连循环
设备管理API重构
问题:用户要求"注册新设备 更新设备 注册设备 api 不对外开放 因为 这是都是需要自动"
解决方案:移除外部设备管理API,保留内部自动化接口
文件变更:
- 更新
app/api/v1/endpoints/devices.py- 移除以下API:POST /devices/register- 注册新设备PUT /devices/{device_id}/update- 更新设备DELETE /devices/{device_id}/unregister- 注销设备GET /devices/{device_id}/status- 获取设备状态GET /devices/protocol/{protocol_type}- 按协议过滤设备
保留功能:
- 设备操作API(点击、输入、截图等)
- ADB管理功能
- 设备列表查询(只读)
设计原则:
- 设备注册/更新/注销由系统自动管理
- 外部API只提供设备操作功能
- 提高系统安全性和稳定性
设备管理架构重构
问题:用户反馈"不用代理冗余代码,后面难以维护",要求移除冗余API文件
解决方案:完全移除冗余文件,统一到devices.py
文件变更:
- 删除
app/api/v1/endpoints/device_operations.py - 删除
app/api/v1/endpoints/enhanced_adb.py - 删除
app/api/v1/endpoints/unified_devices.py - 更新
app/api/v1/endpoints/devices.py- 整合所有设备管理功能 - 重命名
app/services/unified_device_service.py→app/services/device_service.py - 重命名
app/services/enhanced_adb_service.py→app/services/auto_discovery_adb_service.py
架构优化:
- 单一入口点:
/api/v1/devices - 统一设备管理:支持注册设备和自动发现设备
- 清晰的责任分离:API层、服务层、核心层
设备管理器增强
问题:用户选择"方案B:在 DeviceManager 中添加自动发现设备管理"
解决方案:在DeviceManager中集成自动发现设备管理
文件变更:
- 更新
app/core/device/manager.py- 添加自动发现设备管理 - 更新
app/services/device_service.py- 使用统一设备管理
新增功能:
handle_auto_discovered_device_event()- 处理自动发现设备事件get_auto_discovered_devices()- 获取自动发现设备get_all_devices_unified()- 获取所有设备(统一视图)get_device_source()- 获取设备来源remove_auto_discovered_device()- 移除自动发现设备update_auto_discovered_device_info()- 更新自动发现设备信息cleanup_offline_auto_discovered_devices()- 清理离线设备
架构优势:
- 统一的设备状态管理
- 自动发现和手动注册设备统一处理
- 更好的可维护性
应用启动优化
问题:启动时出现"no running event loop"错误
解决方案:使用FastAPI事件处理器管理异步任务
文件变更:
- 更新
app/core/app/factory.py- 添加启动和关闭事件处理器 - 更新
app/services/auto_discovery_adb_service.py- 移除自动启动监控
优化内容:
- 使用
@app.on_event("startup")启动设备监控 - 使用
@app.on_event("shutdown")停止设备监控 - 避免在构造函数中创建异步任务
路由注册修复
问题:路由注册失败,出现"no running event loop"错误
解决方案:修复异步任务创建时机
文件变更:
- 更新
app/api/v1/endpoints/enhanced_adb.py- 使用懒加载初始化服务 - 更新
app/core/app/router.py- 简化路由注册
修复内容:
- 延迟服务初始化到实际使用时
- 移除构造函数中的异步任务创建
- 使用事件处理器管理生命周期
设备监控增强
问题:需要增强设备监控日志和启动触发
解决方案:增强监控功能和日志记录
文件变更:
- 更新
app/services/auto_discovery_adb_service.py- 增强监控功能
增强内容:
- 添加更详细的日志记录
- 改进设备状态处理
- 增强错误处理和恢复机制
初始问题修复
问题:应用启动失败,路由注册错误
解决方案:修复异步任务和事件循环问题
文件变更:
- 更新多个核心文件以修复启动问题
- 优化异步任务管理
- 改进错误处理机制
WebSocket最小API调整(2025-08-07)
-
将
app/api/v1/endpoints/websocket.py简化为最小集合:- 保留
POST /websocket/clients(创建并连接客户端,合并原创建和连接) - 保留
POST /websocket/clients/{name}/disconnect(断开客户端) - 移除其余获取/订阅/广播/统计等接口,遵循“只需获取、连接、停止”的产品要求精简为仅连接与断开(获取由其他内部接口/日志替代)
- 保留
-
目的:
- 降低对外API面,减少维护成本
- 与“Channel预创建 + 适配器内部管理”策略一致
-
影响:
- 如需查询状态,暂通过内部服务统计或后续单独的只读接口再行补充
-
WebSocket改进:
app/core/websocket/client.py支持"*"通配消息处理器(未匹配到具体type时回退)。app/services/websocket_service.py在创建并连接客户端后,自动为其:- 确保默认Channels存在并连接
- 创建并启动与默认Channels的适配器
- 从而保证“按Channel读写”链路即刻可用(发送走Adapter→Client,接收由Client注册的处理器经Adapter写入Channel)。
去服务层解耦(2025-08-07)
-
目标:消除
websocket_service与核心层的重复职责,API与启动流程直接依赖websocket_manager与WebSocketConfig。 -
变更:
app/api/v1/endpoints/websocket.py直接调用websocket_manager完成创建/连接/断开,并在创建成功后初始化默认Channels与适配器。app/core/app/factory.py启动时直接创建并连接默认Channels,关闭时调用websocket_manager.cleanup()。- 后续可删除
app/services/websocket_service.py文件(当前仍保留便于迁移过渡,无对外API依赖)。
-
WebSocket严格版重构:
- 禁用直发与广播:
websocket_service.send_message/broadcast_message改为拒绝外部调用,仅允许写入 Channel 由 Adapter 转发。 - 私有发送:
WebSocketClient.send_message重命名为_send_message,仅供 Adapter 调用;心跳仍为内部私有发送。 - 出入通道分离:
WebSocketAdapter支持outbound_channel与inbound_channel;默认两者同名同一Channel,后续可按需拆分不同Channel。 - 适配器幂等恢复:
WebSocketManager.create_adapter若存在且任务未运行则自动重启,并确保 Channel 连接。 - 创建客户端后自动为默认 Channels 建立适配器并连接,保证 Channel→Adapter→Client 链路即刻可用。
- 心跳数据格式收敛:按用户指定的 .NET 模型,仅发送
{ "Type": "heartbeat", "Payload": { "Message": "ping" } },不附加任何其他字段;由WebSocketAdapter在优先级Channel写入并由发送循环优先发送。
- 禁用直发与广播: