我在开发一款flutter实时播报的桌面应用,用到了flutter_tts和web_socket_channel,面临着一个问题就是下面的第2个问题,虽然临时解决不让应用卡住,但是并未彻底解决,如有好的办法,请私信我
1. WebSocket连接稳定性问题
情况描述:
- WebSocket连接经常断开,需要频繁重连
- 网络不稳定时连接失败率高
- 重连机制不够完善,可能导致消息丢失
问题原因:
- 网络环境不稳定
- 服务器端连接超时设置
- 客户端重连逻辑不够健壮
解决方案:
// 重连相关变量
Timer? _reconnectTimer;
int _reconnectAttempts = 0;
static const int maxReconnectAttempts = 10;
static const int reconnectIntervalSeconds = 45; // 45秒重连一次,确保用户能看到提示
- 实现了自动重连机制,最多重连10次
- 设置45秒重连间隔,避免频繁重连
- 添加了重连次数显示,让用户了解连接状态
2. TTS语音播报问题
情况描述:
- TTS播放时可能阻塞消息处理
- 多条消息同时到达时播放混乱
- TTS初始化失败导致功能不可用
问题原因:
- TTS播放是同步操作,会阻塞主线程
- 没有消息队列机制,多条消息同时处理
- TTS初始化时机不当
解决方案:
// 消息队列相关变量
final Queue<AlarmInfoEntity> _messageQueue = Queue<AlarmInfoEntity>();
bool _isProcessingMessages = false;
Timer? _messageProcessingTimer;
- 实现了消息队列机制,确保消息按顺序处理
- 添加了TTS播放完成回调,避免阻塞
- 设置了10秒超时机制,防止TTS无响应
3. UI更新线程安全问题
情况描述:
- 在非主线程更新UI导致崩溃
- 初始化过程中过早调用UI更新方法
- Snackbar显示时机不当
问题原因:
- WebSocket回调在后台线程执行
- 初始化过程中widget树还未完全构建
- 缺乏线程安全的UI更新机制
解决方案:
/// 线程安全的UI更新工具类
class UIUtil {
/// 确保在主线程执行UI更新
static Future<void> runOnMainThread(Function callback) async {
// ... 实现代码
}
/// 安全地显示Snackbar
static void showSnackbar(String title, String message, {Duration? duration}) {
// ... 实现代码
}
}
- 创建了UIUtil工具类,确保UI更新在主线程执行
- 使用
delayedExecute方法避免在构建过程中调用UI更新 - 添加了错误处理机制
4. 初始化顺序问题
情况描述:
- 组件初始化顺序不当导致依赖注入失败
- TTS初始化阻塞应用启动
- LoginLogic依赖获取失败
问题原因:
- GetX依赖注入时机不当
- TTS初始化是同步操作,影响启动速度
- 缺乏异步初始化机制
解决方案:
@override
void onInit() {
super.onInit();
// 延迟初始化,避免在构建过程中访问依赖
Future.delayed(Duration(milliseconds: 100), () {
try {
loginLogic = Get.find<LoginLogic>();
// 异步初始化TTS,避免阻塞主线程
_initializeTtsAsync();
} catch (e) {
if (kDebugMode) {
print("HomeLogic初始化错误: $e");
}
}
});
}
- 使用延迟初始化避免依赖注入问题
- TTS初始化改为异步操作,不阻塞主线程
- 添加了错误处理机制
5. 错误处理和用户体验问题
情况描述:
- 错误信息不够友好
- 用户无法了解当前系统状态
- 缺乏手动重连功能
问题原因:
- 错误处理机制不完善
- 状态显示不够清晰
- 用户操作选项有限
解决方案:
// 手动重连(供外部调用)
void manualReconnect() {
_stopReconnectTimer();
_reconnectAttempts = 0;
reconnectAttempts.value = 0; // 重置界面显示的重连次数
connectWebSocket();
}
- 添加了详细的状态显示(连接中、重连中、连接失败)
- 实现了手动重连功能
- 优化了错误提示信息,更加用户友好
6. 内存泄漏和资源管理问题
情况描述:
- Timer未正确释放导致内存泄漏
- WebSocket连接未正确关闭
- TTS资源未及时释放
问题原因:
- 缺乏完整的资源清理机制
- 组件销毁时未清理定时器
- 连接关闭逻辑不完善
解决方案:
@override
void onClose() {
_stopReconnectTimer();
_stopMessageProcessingTimer();
_closeWebSocket();
ttsService.stop();
super.onClose();
}
- 在
onClose方法中完整清理所有资源 - 确保Timer、WebSocket、TTS资源正确释放
- 防止内存泄漏
总结
通过以上优化,系统现在具备了:
- 稳定的WebSocket连接:自动重连机制,最多重连10次
- 可靠的消息处理:消息队列确保顺序播放,TTS超时保护
- 线程安全的UI更新:专用工具类确保UI操作在主线程执行
- 完善的错误处理:友好的错误提示和状态显示
- 良好的用户体验:手动重连、状态显示、资源管理
这些改进大大提高了系统的稳定性和用户体验。