build: 控制端功能移植到flutter版本
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
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<String, dynamic>;
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user