单条消息后 Dart 套接字 onDone

Dart socket onDone after single message

我目前正在我的 flutter 应用程序中实现一个 tcp 套接字连接,该应用程序在后台运行并获取数据以供应用程序显示。 建立连接工作正常,我也从我的服务器收到初始消息,但是,在收到第一条消息后,从我的 socket.listen() 调用 onDone 并且流关闭。

为了正确实施,我需要保持流活动并交换多条消息。实际上,计划是在应用程序 运行 处于前台时始终保持套接字处于活动状态。

服务器端不会有问题,因为我之前在 C# 上实现了相同的客户端(我一直在简单地循环 stream.Read(),没有问题)。

这是我的函数现在的样子:

_socket = await SecureSocket.connect(_ipAddressServer, _portServer,
    onBadCertificate: (X509Certificate c) {
  print("Certificate WARNING: ${c.issuer}:${c.subject}");
  isSocketConnected = true;
  return true;
}).catchError((error, stackTrace) async {
  return false;
}).timeout(const Duration(seconds: 5));
print("Connected!");
_socket.setOption(SocketOption.tcpNoDelay, true);
_socket.listen((message) {
  _handleSocketMessage(message);
}).onDone(() {
  print("Socket done");
});

正如我所说,在收到第一条消息后,立即调用 onDone 并且我不再从套接字收到任何消息。保持与服务器连接的功能是有义务的。

有什么建议吗?

编辑:

也许问题出在其他地方。在 _handleSocketMessage(message) 内部,我实际上再次调用了 _socket.write(data)。这是错误的做法吗?我应该在 isolate 中调用 _handleSocketMessage(message) 吗?我仍在尝试掌握 dart 中多线程的窍门,这部分在 C# 中要容易一些,不会说谎。

我没有发现您的代码有任何问题。我注意到你在 (message) {...} 函数上调用 onDone,而我认为你想使用 _socket.listen()onDone 参数。当你的代码运行时,套接字在打印“套接字完成”后仍然打开,如果我是正确的话。

我想你要找的是这个:

_socket.listen(
  (message) {
    _handleSocketMessage(message);
  },
  onDone: () {
    print('Socked done');
  },
);

问题不在于我的 listen 方法。实际上是我的 _socket.write() 把事情搞砸了。 我的服务器希望我发送一个原始字节数组(在 Dart 术语 Uint8List 中)。来自 c# 我认为 _socket.write() 实际上与 .NET c# 套接字中的相同,但它实际上将 String 从您传递给套接字的任何内容发送到套接字。所以我的 Uint8List 被转换为字符串,我的服务器不知道如何处理它。

我用 _socket.add(payload) 替换了 _socket.write(payload),一切正常。