Flutter:隔离中的解密未使用解密消息更新 UI

问题描述 投票:0回答:1

我正在 Flutter 中实现一个聊天应用程序,其中需要使用单独的隔离来解密消息以防止 UI 阻塞。但是,我遇到了一个问题,即解密的消息没有替换 UI 中的占位符文本。

这是我当前的设置:

  1. 我在
    initState
    中初始化一个解密隔离:
void initDecryptionIsolate() async {
  decryptionIsolate = await Isolate.spawn(decryptionIsolateEntryPoint, receivePort.sendPort);
  receivePort.listen(handleIsolateMessage);
}
  1. 我向
    isolate
    发送解密请求:
void sendDecryptionRequest(String messageId, String? encryptedText, String auth) {
  if (encryptedText != null && encryptedText.isNotEmpty) {
    decryptionIsolate?.controlPort.send({
      'messageId': messageId,
      'encryptedText': encryptedText,
      'auth': auth,
    });
  }
}
  1. isolate 处理请求并发回解密的消息:
static void decryptionIsolateEntryPoint(SendPort sendPort) {
    final ReceivePort receivePort = ReceivePort();
    sendPort.send(receivePort.sendPort);
    print('Decryption isolate started');
    receivePort.listen((message) {
      print('Received message in decryption isolate: $message');
      if (message is Map<String, dynamic>) {
        final auth = message['auth'];
        final messageId = message['messageId'];
        final encryptedText = message['encryptedText'];

        if (messageId != null && encryptedText != null && auth != null) {
          try {
            final decryptedText =
                SecureMessageHandler().decryptMessage(encryptedText, auth);
            sendPort.send({
              'messageId': messageId,
              'decryptedText': decryptedText,
            });
          } catch (e) {
            sendPort.send({
              'messageId': messageId,
              'decryptedText': 'Error: Failed to decrypt message',
            });
          }
        }
      }
    });
  }

  1. 主要
    isolate
    处理解密消息:
void handleIsolateMessage(dynamic message) {
    print('Received message in main isolate: $message');
    if (message is Map<String, String>) {
      final messageId = message['messageId'];
      final decryptedText = message['decryptedText'];
      if (messageId != null && decryptedText != null) {
        setState(() {
          decryptedMessageCache[messageId] = decryptedText;
        });
        appState.updateMessage({
          '_id': messageId,
          'plain': decryptedText,
          'chatroomId': appState.chatroom.value,
        });
      }
    }
  }

尽管如此设置,UI 并未使用解密的消息进行更新。占位符文本仍然可见,控制台仅显示:

flutter: Decryption isolate started
flutter: Received message in main isolate: SendPort

在这个实现中我缺少什么来确保解密的消息正确显示在 UI 中?

我的观察是,发送到handleIsolateMessage函数的消息参数的类型为

SendPort
,而不是预期的
String Map

任何见解或建议将不胜感激!

flutter multithreading dart encryption isolate
1个回答
0
投票

您不应使用控制端口向您的隔离发送请求。 使用您在步骤 3 中生成的 receivePort :

sendPort.send(receivePort.sendPort);

您正确地将其发送回主隔离区,但您没有在另一侧捕获它(步骤 4):

  void handleIsolateMessage(dynamic message) {
    print('Received message in main isolate: $message');
    // Add this
    if (message is SendPort) {
      // save reference to the sendPort
      // And then use it in your call to "sendDecryptionRequest"
    } 
    else if (message is Map<String, String>) {
      final messageId = message['messageId'];
      final decryptedText = message['decryptedText'];
      if (messageId != null && decryptedText != null) {
        setState(() {
          decryptedMessageCache[messageId] = decryptedText;
        });
        appState.updateMessage({
          '_id': messageId,
          'plain': decryptedText,
          'chatroomId': appState.chatroom.value,
        });
      }
    }
  }

我强烈建议您仔细阅读 Dart 网站上的这篇精彩文章:Isolates,它详细解释了这一切,并提供了包含错误处理和竞争条件管理的完整代码示例。 另一种方法是使用包WorkerManager,它可能适合您的需求。

© www.soinside.com 2019 - 2024. All rights reserved.