在Dart中如何处理套接字断开连接?

9
我正在使用服务器上的Dart 1.8.5。 我想要实现一个TCP Socket服务器来监听传入的连接,向每个客户端发送一些数据,并在客户端断开连接时停止生成数据。
以下是示例代码:
void main() {
  ServerSocket.bind(
      InternetAddress.ANY_IP_V4,
      9000).then((ServerSocket server) {
    runZoned(() {
      server.listen(handleClient);
    }, onError: (e) {
      print('Server error: $e');
    });
  });
}

void handleClient(Socket client) {
  client.done.then((_) {
    print('Stop sending');
  });
  print('Send data');
}

这段代码接受连接并打印“发送数据”。但即使客户端已经离开,它也永远不会打印“停止发送”。那么问题来了:如何在监听器中捕获客户端的断线?

2
在我看来,这似乎是一个错误。请在http://dartbug.com上创建一个问题。 - Günter Zöchbauer
2
https://code.google.com/p/dart/issues/detail?id=22583 - lig
您可以在我的回答中看到示例。它显示“停止发送”,并详细解释了在Dart SDK中发现的问题。 - mezoni
1个回答

4

Socket 是双向的,即它有一个输入流和一个输出汇。当通过调用 Socket.close() 关闭输出汇时,done 返回 Future。

如果您希望在输入流关闭时收到通知,请尝试使用 Socket.drain()

请参见下面的示例。 您可以使用 telnet 进行测试。 当您连接到服务器时,它将每秒发送字符串“Send.”。 当您关闭 telnet(ctrl-],然后键入 close)时,服务器将打印“Stop.”。

import 'dart:io';
import 'dart:async';

void handleClient(Socket socket) {

  // Send a string to the client every second.
  var timer = new Timer.periodic(
      new Duration(seconds: 1), 
      (_) => socket.writeln('Send.'));

  // Wait for the client to disconnect, stop the timer, and close the
  // output sink of the socket.
  socket.drain().then((_) {
    print('Stop.');    
    timer.cancel();
    socket.close();
  });
}

void main() {
  ServerSocket.bind(
      InternetAddress.ANY_IP_V4,
      9000).then((ServerSocket server) {
    runZoned(() {
      server.listen(handleClient);
    }, onError: (e) {
      print('Server error: $e');
    });
  });
}

我正在尝试实现你的回答。我发送查询并在收到查询后需要关闭套接字。我该怎么做? - Nick
当我尝试排空套接字时,我会收到“Unhandled Exception: Bad state: Stream has already been listened to.”的错误提示。 - Hari Honor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接