单条消息后 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)
,一切正常。
我目前正在我的 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)
,一切正常。