Flutter如何通过dart:io实现WebSocket连接 无需使用web_socket_channel包
回答
关于socket_io_client是否可用的说明
- socket_io_client是Socket.IO协议的专用客户端,仅能对接部署了Socket.IO服务端的接口,无法对接AWS标准WebSocket API。AWS WebSocket API遵循标准RFC 6455 WebSocket协议,和Socket.IO的私有封装协议完全不兼容。
- 你观察到的它使用HTTP发起连接是Socket.IO本身的握手协商逻辑,即使手动修改协议为wss也无法完成和AWS WebSocket API的正常通信,不建议使用该方案。
使用dart:io原生WebSocket对接AWS WebSocket API实现方案
dart:io内置的WebSocket类是标准WebSocket协议的完整实现,完全支持对接AWS WebSocket API,且支持自定义错误处理、重连逻辑,无需引入第三方依赖。
核心实现步骤
- 初始化连接:直接调用
WebSocket.connect方法传入AWS WebSocket的wss地址即可,支持自定义请求头(如果AWS接口需要鉴权头可以在这里传入) - 监听消息:通过
listen方法监听服务端推送的消息 - 错误处理:监听
onError、onDone回调处理连接异常、断开场景 - 发送消息:调用
add方法发送字符串或二进制消息 - 关闭连接:调用
close方法主动断开连接
完整代码示例
import 'dart:io'; import 'dart:convert'; class AwsWebSocketClient { WebSocket? _socket; final String wsUrl; // 替换为你的AWS WebSocket API地址 final Map<String, String>? headers; // 鉴权头等自定义请求头 AwsWebSocketClient({required this.wsUrl, this.headers}); // 建立连接 Future<void> connect() async { try { _socket = await WebSocket.connect(wsUrl, headers: headers); // 心跳间隔,避免AWS主动断开空闲连接,可按需调整 _socket!.pingInterval = const Duration(seconds: 30); // 监听服务端消息 _socket!.listen( (message) { // 处理收到的消息,二进制消息可自行调整解析逻辑 try { final data = jsonDecode(message); _handleReceiveMessage(data); } catch (e) { _handleError(e); } }, onError: (error) { // 连接错误处理 _handleError(error); // 按需触发自动重连 _reconnect(); }, onDone: () { // 连接断开处理 _handleDisconnect(_socket?.closeCode, _socket?.closeReason); // 非主动断开场景可触发重连 if (_socket?.closeCode != 1000) { _reconnect(); } }, cancelOnError: true, ); } catch (e) { // 连接建立失败处理 _handleError(e); _reconnect(); } } // 发送消息 void sendMessage(Map<String, dynamic> data) { if (_socket?.readyState == WebSocket.open) { _socket!.add(jsonEncode(data)); } else { _handleError(Exception('WebSocket未连接,消息发送失败')); } } // 主动关闭连接 Future<void> disconnect() async { await _socket?.close(1000, '主动断开连接'); _socket = null; } // 处理收到的消息,按需实现业务逻辑 void _handleReceiveMessage(dynamic data) { print('收到消息: $data'); } // 统一错误处理,按需实现弹窗、日志上报等逻辑 void _handleError(dynamic error) { print('WebSocket异常: $error'); } // 处理连接断开的业务逻辑 void _handleDisconnect(int? code, String? reason) { print('连接断开,code: $code, reason: $reason'); } // 自动重连逻辑,按需调整重试间隔、最大重试次数 Future<void> _reconnect() async { if (_socket?.readyState == WebSocket.open) return; await Future.delayed(const Duration(seconds: 5)); connect(); } } // 使用示例 void main() async { final client = AwsWebSocketClient( wsUrl: 'wss://你的AWS API ID.execute-api.区域.amazonaws.com/阶段', headers: { // 若AWS开启IAM鉴权或自定义鉴权,在此传入对应头信息 'Authorization': '你的鉴权token' }, ); await client.connect(); // 发送消息示例,action字段需匹配AWS控制台配置的路由规则 client.sendMessage({"action": "sendMessage", "data": "测试内容"}); }
注意事项
- AWS WebSocket API默认要求消息中携带
action字段匹配你配置的路由,发送消息时需要按照AWS控制台的配置规则传入对应参数 - 若使用IAM鉴权,需要提前生成AWS签名放入请求头或者消息参数中,按你自己的鉴权配置调整即可
- 上述代码的重连逻辑可以根据业务需求调整最大重试次数、退避间隔,避免无限重试消耗资源
内容的提问来源于stack exchange,提问作者Tom3652
相关产品推荐
相关产品推荐

