Dart WebSocket的pingInterval工作机制及连接异常问题咨询
Dart WebSocket pingInterval 不生效问题:连接因1001状态码断开
设置客户端WebSocket的pingInterval后,服务器未响应PING帧,连接最终以状态码1001("Going Away")关闭。
示例代码
import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'dart:math'; void main() async { final addr = InternetAddress('0.0.0.0', type: InternetAddressType.IPv4); Server.start(addr); final client = await Client.connect(addr); await client.listen(); print('Script done'); } class Server { Server._(this._server) { init(); } final HttpServer _server; Future<void> init() async { await for (final request in _server) { final socket = await WebSocketTransformer.upgrade(request); print('[Server] Waiting for requests'); await for (final payload in socket) { print('[Server] Incoming request: $payload'); print('[Server] Waiting 5 seconds before sending a response'); await Future.delayed(const Duration(seconds: 5)); socket.add('Hello from Server'); } } } static Future<Server> start(InternetAddress adr) async { final server = await HttpServer.bind(adr, 7444); return Server._(server); } } class Client { Client._(this._socket) { _socket.done.then((_) => print('Socket was done')); } final WebSocket _socket; Future<void> listen() async { _socket.add('Hello from Client'); await for (final String payload in _socket) { print('Client incoming payload: $payload'); } print('Close code: ${_socket.closeCode}'); if (_socket.closeCode == WebSocketStatus.goingAway) { print('Code was "Going Away", meaning the server did not respond to set pingInterval'); } } static Future<WebSocket> _createWebSocket(InternetAddress adr) async { final r = Random(); final key = base64.encode(List<int>.generate(8, (_) => r.nextInt(256))); final client = HttpClient(); client.connectionTimeout = const Duration(seconds: 6); final uri = Uri.parse('http://${adr.address}:7444'); print('Connecting to ${uri}'); final request = await client.getUrl(uri); request.headers.add('Connection', 'upgrade'); request.headers.add('Upgrade', 'websocket'); request.headers.add('sec-websocket-version', '13'); request.headers.add('sec-websocket-key', key); final response = await request.close(); final socket = await response.detachSocket(); return WebSocket.fromUpgradedSocket(socket, serverSide: false); } static Future<Client> connect(InternetAddress adr) async { final socket = await Client._createWebSocket(adr) ..pingInterval = const Duration(seconds: 2); return Client._(socket); } }
运行方式
将上述代码保存为test.dart文件,执行命令:
dart test.dart
问题详情
根据Dart文档,设置2秒的pingInterval时,客户端会在2秒后发送PING帧,并等待2秒接收服务器的PONG帧。但实际测试出现以下现象:
- 当服务器未主动发送数据(示例中服务器5秒后才回复),客户端未收到PONG帧,连接直接断开
- 若将
pingInterval设为5秒,服务器刚好在5秒后回复业务数据,连接则不会断开
这一逻辑不符合预期:PING/PONG机制应该是WebSocket协议层自动处理的,无需依赖服务器的显式业务回复。
疑问
- 是否在代码实现中有操作错误?
- 如何让PING/PONG逻辑在无需服务器显式回复的情况下正常运行?
内容的提问来源于stack exchange,提问作者DarkNeuron
相关产品推荐
相关产品推荐

