fix(client): statsStream/statusStream 缓存为共享广播流,修延迟不回写
根因:VpnNativeBridge.statsStream getter 每次访问都 receiveBroadcastStream(),多订阅者 (连接页速度 + ConnectionController._onStats 回写 urltest 延迟)各起一条原生订阅;但 EventChannel 原生侧只留一个 sink(StatsStreamHandler.onListen 覆盖),后订阅者赢、先订阅者 变哑。速度订阅赢了 sink → _onStats 收不到 → urltest 实测(已确认到达 native:reality-out=595) 永不回写 node.ping → 连接页延迟一直 —。 修复:receiveBroadcastStream() 只调一次、缓存成 asBroadcastStream() 共享流,所有 Dart 订阅者复用同一条原生订阅。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -223,18 +223,28 @@ class VpnNativeBridge implements VpnBridge {
|
||||
Future<void> setKillSwitch({required bool on}) =>
|
||||
_method.invokeMethod<void>('setKillSwitch', on);
|
||||
|
||||
@override
|
||||
Stream<VpnStatus> get statusStream => _statusRaw
|
||||
// ⚠️ EventChannel 原生侧只保留「一个」sink:每次 receiveBroadcastStream() + listen 都会
|
||||
// 触发 onListen 覆盖原生 sink → 多个订阅者(连接页速度 + ConnectionController 回写延迟)
|
||||
// 互相抢,后订阅的赢、先订阅的流变哑。必须只调一次 receiveBroadcastStream()、缓存成共享
|
||||
// 广播流,所有 Dart 订阅者复用同一条原生订阅。
|
||||
late final Stream<VpnStatus> _statusStream = _statusRaw
|
||||
.receiveBroadcastStream()
|
||||
.map((e) => VpnStatus.fromString(e?.toString() ?? 'error'));
|
||||
.map((e) => VpnStatus.fromString(e?.toString() ?? 'error'))
|
||||
.asBroadcastStream();
|
||||
|
||||
@override
|
||||
Stream<VpnStatsEvent> get statsStream => _statsRaw
|
||||
late final Stream<VpnStatsEvent> _statsStream = _statsRaw
|
||||
.receiveBroadcastStream()
|
||||
.where((e) => e is Map)
|
||||
.map((e) => VpnStatsEvent.fromNativeMap(
|
||||
Map<Object?, Object?>.from(e as Map),
|
||||
));
|
||||
))
|
||||
.asBroadcastStream();
|
||||
|
||||
@override
|
||||
Stream<VpnStatus> get statusStream => _statusStream;
|
||||
|
||||
@override
|
||||
Stream<VpnStatsEvent> get statsStream => _statsStream;
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
|
||||
Reference in New Issue
Block a user