【发布时间】:2014-06-01 00:17:45
【问题描述】:
我一直在使用 web-socket 进行测试,并想使用 pingInterval 来确定客户端是否已关闭,但我无法检测到。我每 4 秒通过 websocket 发送一条消息。我想,当我退出浏览器时,不会产生任何错误情况,而且我还无法弄清楚如何检测到 web-socket 关闭了连接。我怎样才能检测到呢?我也是 Dart 和 Web 应用程序的新手。
【问题讨论】:
我一直在使用 web-socket 进行测试,并想使用 pingInterval 来确定客户端是否已关闭,但我无法检测到。我每 4 秒通过 websocket 发送一条消息。我想,当我退出浏览器时,不会产生任何错误情况,而且我还无法弄清楚如何检测到 web-socket 关闭了连接。我怎样才能检测到呢?我也是 Dart 和 Web 应用程序的新手。
【问题讨论】:
我使用 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 在两个事件之间传递时 流,onTimeout函数被调用。
在收听返回的流之前,倒计时不会开始。 每次从这里转发事件时都会重置倒计时 流,或者当流暂停和恢复时。
onTimeout 函数使用一个参数调用:一个 EventSink,它 允许将事件放入返回的流中。此 EventSink 仅 在调用 onTimeout 期间有效。
如果省略 onTimeout,超时只会抛出 TimeoutException 进入返回流的错误通道。
返回的流不是广播流,即使这个流是。
【讨论】: