diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart index a39af3474..734f43b85 100644 --- a/flutter/lib/models/model.dart +++ b/flutter/lib/models/model.dart @@ -38,7 +38,7 @@ import 'platform_model.dart'; typedef HandleMsgBox = Function(Map evt, String id); typedef ReconnectHandle = Function(OverlayDialogManager, SessionID, bool); -final _waitForImage = {}; +final _waitForImage = {}; class FfiModel with ChangeNotifier { PeerInfo _pi = PeerInfo(); @@ -491,7 +491,7 @@ class FfiModel with ChangeNotifier { parent.target?.dialogManager.showLoading( translate('Connected, waiting for image...'), onCancel: closeConnection); - _waitForImage[peerId] = true; + _waitForImage[sessionId] = true; _reconnects = 1; } Map features = json.decode(evt['features']); @@ -637,14 +637,14 @@ class ImageModel with ChangeNotifier { addCallbackOnFirstImage(Function(String) cb) => callbacksOnFirstImage.add(cb); onRgba(Uint8List rgba) { - final waitforImage = _waitForImage[id]; + final waitforImage = _waitForImage[sessionId]; if (waitforImage == null) { debugPrint('Exception, peer $id not found for waiting image'); return; } if (waitforImage == true) { - _waitForImage[id] = false; + _waitForImage[sessionId] = false; parent.target?.dialogManager.dismissAll(); if (isDesktop) { for (final cb in callbacksOnFirstImage) { @@ -1584,6 +1584,7 @@ class FFI { var id = ''; var version = ''; var connType = ConnType.defaultConn; + var closed = false; /// dialogManager use late to ensure init after main page binding [globalKey] late final dialogManager = OverlayDialogManager(); @@ -1655,13 +1656,16 @@ class FFI { ); final stream = bind.sessionStart(sessionId: sessionId, id: id); final cb = ffiModel.startEventListener(sessionId, id); - () async { - final useTextureRender = bind.mainUseTextureRender(); - // Preserved for the rgba data. - await for (final message in stream) { + final useTextureRender = bind.mainUseTextureRender(); + // Preserved for the rgba data. + stream.listen((message) { + if (closed) return; + () async { if (message is EventToUI_Event) { if (message.field0 == "close") { - break; + closed = true; + debugPrint('Exit session event loop'); + return; } Map? event; @@ -1675,8 +1679,8 @@ class FFI { } } else if (message is EventToUI_Rgba) { if (useTextureRender) { - if (_waitForImage[id]!) { - _waitForImage[id] = false; + if (_waitForImage[sessionId]!) { + _waitForImage[sessionId] = false; dialogManager.dismissAll(); for (final cb in imageModel.callbacksOnFirstImage) { cb(id); @@ -1696,9 +1700,8 @@ class FFI { } } } - } - debugPrint('Exit session event loop'); - }(); + }(); + }); // every instance will bind a stream this.id = id; } @@ -1716,6 +1719,7 @@ class FFI { /// Close the remote session. Future close() async { + closed = true; chatModel.close(); if (imageModel.image != null && !isWebDesktop) { await setCanvasConfig( diff --git a/flutter/lib/models/native_model.dart b/flutter/lib/models/native_model.dart index bf8009005..309c30f68 100644 --- a/flutter/lib/models/native_model.dart +++ b/flutter/lib/models/native_model.dart @@ -1,7 +1,6 @@ import 'dart:convert'; import 'dart:ffi'; import 'dart:io'; -import 'dart:typed_data'; import 'package:device_info_plus/device_info_plus.dart'; import 'package:external_path/external_path.dart'; @@ -9,10 +8,8 @@ import 'package:ffi/ffi.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:flutter_hbb/consts.dart'; -import 'package:get/get.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:path_provider/path_provider.dart'; -import 'package:win32/win32.dart' as win32; import '../common.dart'; import '../generated_bridge.dart'; @@ -266,9 +263,9 @@ class PlatformFFI { /// Start listening to the Rust core's events and frames. void _startListenEvent(RustdeskImpl rustdeskImpl) { - () async { - await for (final message - in rustdeskImpl.startGlobalEventStream(appType: _appType)) { + var sink = rustdeskImpl.startGlobalEventStream(appType: _appType); + sink.listen((message) { + () async { try { Map event = json.decode(message); // _tryHandle here may be more flexible than _eventCallback @@ -280,8 +277,8 @@ class PlatformFFI { } catch (e) { debugPrint('json.decode fail(): $e'); } - } - }(); + }(); + }); } void setEventCallback(StreamEventHandler fun) async {