Dart websocket pingInterval实际上是如何使用的?

时间:2014-06-01 00:17:45

标签: websocket dart

我一直在使用网络套接字进行测试,并希望使用pingInterval来确定客户端是否已关闭,但我无法检测到。我每隔4秒就通过websocket发送一条消息。当我退出浏览器时,没有生成错误条件,我想,我无法弄清楚如何检测web-socket关闭连接。我怎么能检测出来?我也是Dart和Web应用程序的新手。

1 个答案:

答案 0 :(得分:2)

我使用SDK 1.5.0.dev测试了它:

服务器代码:

import 'dart:io';
main() {
  HttpServer.bind('127.0.0.1', 4040).then((server) {
    server.listen((HttpRequest request) {
      WebSocketTransformer.upgrade(request).then((socket) {
        socket.listen((msg){
          socket.pingInterval = new Duration(seconds : 1);
          print('server received message: $msg');
          socket.add('server received message: $msg');
        });
        socket.done.then((e){
            print("WebSocket closed with:"
                  "socket.closeReason: ${socket.closeReason}, "
                  "socket.closeCode: ${socket.closeCode}");
          });
      });
    });
  });
}

客户代码:

import 'dart:html';
import 'dart:async';
void main() {
  querySelector('button').onClick.first.then((e){
    for (int i = 0; i > -1; i++){
      print("epic code");
    }
  });
  WebSocket ws = new WebSocket('ws://127.0.0.1:4040');
  ws.onMessage.listen((MessageEvent e) {
    querySelector('#response').appendHtml('<p>${e.data}</p>');
  });
  Timer t = new Timer.periodic(new Duration(seconds : 1), (t) {
    ws.sendString('timer fired');
  });
}

<强> HTML:

<!DOCTYPE html>

<html>
  <head>
    <meta charset="utf-8">
    <title>ClientTest</title>
    <link rel="stylesheet" href="clienttest.css">
  </head>
  <body>
    <button type="button">Hang</button>
    <p>Response:</p>

    <div id="response">
    </div>

    <script type="application/dart" src="clienttest.dart"></script>
    <script src="packages/browser/dart.js"></script>
  </body>
</html>

例如,如果您关闭浏览器窗口,那么客户端 - 服务器将关闭socket.closeReason: , socket.closeCode: 1005套接字,当然如果不是“猝死”,您可以提供自己的理由CloseEvent codes

但是如果您设置pingInterval并按Hang按钮,则服务器将在超时时关闭套接字,但使用socket.closeReason: null, socket.closeCode: null。如果没有pingInterval,它将继续等待。

可能Dart团队应该提供比null更“详尽”的东西。但您可以使用Stream timeout

自行ping通
Stream timeout(Duration timeLimit, {Function void onTimeout(EventSink sink)})
  

使用与此流相同的事件创建新流。

     

每当超过timeLimit从两个事件之间传递时   stream,调用onTimeout函数。

     

在收听返回的流之前,倒计时才会开始。   每次从此转发事件时都会重置倒计时   流,或暂停和恢复流。

     

使用一个参数调用onTimeout函数:一个EventSink   允许将事件放入返回的流中。此EventSink仅限   在调用onTimeout期间有效。

     

如果省略onTimeout,超时只会发出TimeoutException   进入返回流的错误通道。

     

返回的流不是广播流,即使此流是。