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}) =>
|
Future<void> setKillSwitch({required bool on}) =>
|
||||||
_method.invokeMethod<void>('setKillSwitch', on);
|
_method.invokeMethod<void>('setKillSwitch', on);
|
||||||
|
|
||||||
@override
|
// ⚠️ EventChannel 原生侧只保留「一个」sink:每次 receiveBroadcastStream() + listen 都会
|
||||||
Stream<VpnStatus> get statusStream => _statusRaw
|
// 触发 onListen 覆盖原生 sink → 多个订阅者(连接页速度 + ConnectionController 回写延迟)
|
||||||
|
// 互相抢,后订阅的赢、先订阅的流变哑。必须只调一次 receiveBroadcastStream()、缓存成共享
|
||||||
|
// 广播流,所有 Dart 订阅者复用同一条原生订阅。
|
||||||
|
late final Stream<VpnStatus> _statusStream = _statusRaw
|
||||||
.receiveBroadcastStream()
|
.receiveBroadcastStream()
|
||||||
.map((e) => VpnStatus.fromString(e?.toString() ?? 'error'));
|
.map((e) => VpnStatus.fromString(e?.toString() ?? 'error'))
|
||||||
|
.asBroadcastStream();
|
||||||
|
|
||||||
@override
|
late final Stream<VpnStatsEvent> _statsStream = _statsRaw
|
||||||
Stream<VpnStatsEvent> get statsStream => _statsRaw
|
|
||||||
.receiveBroadcastStream()
|
.receiveBroadcastStream()
|
||||||
.where((e) => e is Map)
|
.where((e) => e is Map)
|
||||||
.map((e) => VpnStatsEvent.fromNativeMap(
|
.map((e) => VpnStatsEvent.fromNativeMap(
|
||||||
Map<Object?, Object?>.from(e as Map),
|
Map<Object?, Object?>.from(e as Map),
|
||||||
));
|
))
|
||||||
|
.asBroadcastStream();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Stream<VpnStatus> get statusStream => _statusStream;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Stream<VpnStatsEvent> get statsStream => _statsStream;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
|||||||
Reference in New Issue
Block a user