import 'dart:developer' as developer; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../core/config/app_config.dart'; import '../core/network/ws_client.dart'; import 'node_provider.dart'; export '../core/network/ws_client.dart' show WsConnectionState; /// 全局 WebSocket 客户端 Provider /// 仅当 ENABLE_MOCK=true 时使用模拟数据,debug 构建也连真实 WS 以便调试 final wsClientProvider = Provider((ref) { final nodeState = ref.read(nodeProvider); // Debug/Profile:合约 WS 固定 env_debug,避免节点缓存里的旧 apitest 覆盖 final wsUrl = AppConfig.isDebug ? AppConfig.effectiveWsUrl : (nodeState.currentNode?.normalizedWsHost ?? AppConfig.effectiveWsUrl); final client = WsClient( mockMode: AppConfig.enableMock, wsUrl: wsUrl, // WS 连续重连失败 → 联动节点 failover;切节点后 listen 自动 reconnectWithUrl onPersistentFailure: () { developer.log( 'WS persistent failure → triggering node failover', name: 'Node', ); ref.read(nodeProvider.notifier).reportFailure(immediate: true); }, ); // Release:切节点时重连 WS;Debug 固定单一地址 if (!AppConfig.isDebug) { ref.listen(nodeProvider, (prev, next) { final newWsUrl = next.currentNode?.normalizedWsHost; if (newWsUrl != null && client.currentWsUrl != newWsUrl) { developer.log( 'WS reconnecting: ${client.currentWsUrl} → $newWsUrl', name: 'Node', ); client.reconnectWithUrl(newWsUrl); } }); } ref.onDispose(client.dispose); return client; }); /// 连接状态 StreamProvider final wsConnectionStateProvider = StreamProvider((ref) { final client = ref.watch(wsClientProvider); return client.connectionStream; });