import 'dart:convert'; import 'package:web_socket_channel/web_socket_channel.dart'; import '../models/signal_message.dart'; /// 信令客户端,封装 WebSocket 连接与消息收发。 /// /// 连接成功后自动向服务器发送 REGISTER 注册为 CONTROLLER 设备, /// 与 Android 端 WebSocketClient 行为一致。 class SignalingClient { final String serverUrl; final String deviceId; WebSocketChannel? _channel; /// 收到信令消息回调(已解析为 SignalMessage)。 void Function(SignalMessage message)? onMessage; /// 连接成功回调。 void Function()? onConnected; /// 连接断开回调。 void Function()? onDisconnected; /// 连接错误回调。 void Function(String error)? onError; SignalingClient({required this.serverUrl, required this.deviceId}); /// 建立 WebSocket 连接并注册设备。 void connect() { try { final uri = Uri.parse(serverUrl); _channel = WebSocketChannel.connect(uri); _channel!.stream.listen( _onData, onDone: () => onDisconnected?.call(), onError: (Object e) => onError?.call(e.toString()), cancelOnError: false, ); // 连接建立后注册设备(与 Android 端 onOpen -> registerDevice 对应)。 _register(); } catch (e) { onError?.call(e.toString()); } } void _onData(dynamic data) { if (data is! String) return; try { final map = jsonDecode(data) as Map; final message = SignalMessage.fromJson(map); onMessage?.call(message); } catch (_) { // 忽略无法解析的消息。 } } void _register() { final msg = SignalMessage( type: 'REGISTER', fromDeviceId: deviceId, deviceType: 'CONTROLLER', ); _send(msg); // 通知上层已“连接”(WebSocketChannel 会缓冲发送,直到底层连接就绪); // 后续 OFFER 等消息会排在 REGISTER 之后发送,保证服务器先完成注册。 onConnected?.call(); } /// 发送信令消息。 void send(SignalMessage message) => _send(message); void _send(SignalMessage message) { _channel?.sink.add(jsonEncode(message.toJson())); } /// 关闭连接。 void disconnect() { _channel?.sink.close(); _channel = null; } bool get isConnected => _channel != null; }