From 5183b0623bdfaf4b5c29eba34e48b32b647927ce Mon Sep 17 00:00:00 2001 From: zhangmeng <494089941@qq.com> Date: Fri, 18 Jun 2021 15:21:19 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=81=E8=A3=85=20websocekt=20util=20?= =?UTF-8?q?=E7=B1=BB=EF=BC=8C=E6=B7=BB=E5=8A=A0websocket=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/utils/websocket/web_socket_util.dart | 194 +++++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 lib/utils/websocket/web_socket_util.dart diff --git a/lib/utils/websocket/web_socket_util.dart b/lib/utils/websocket/web_socket_util.dart new file mode 100644 index 0000000..4521d14 --- /dev/null +++ b/lib/utils/websocket/web_socket_util.dart @@ -0,0 +1,194 @@ +import 'dart:async'; +import 'package:bot_toast/bot_toast.dart'; +import 'package:power_logger/power_logger.dart'; +import 'package:web_socket_channel/io.dart'; +import 'package:web_socket_channel/web_socket_channel.dart'; + +const String baseUri = 'wss://test.kaidalai.cn/websocket'; +enum SOCKETSTATUS { + CONNECTED, //已连接 + BREAKOFF, //已断开 + CLOSED, //已关闭 +} + +class WebSocketUtil { + static final WebSocketUtil _socket = WebSocketUtil._(); + +//内部构造函数 + WebSocketUtil._(); +//单例模式 + factory WebSocketUtil() => _socket; + + IOWebSocketChannel? _webSocket; + + ///用户设置不同的服务器地址 + String user = 'admin'; + + ///连接状态 + SOCKETSTATUS _socketStatus = SOCKETSTATUS.CLOSED; + + ///心跳计时器; + Timer? _heartTimer; + + ///心跳间隔 + Duration _heartDuration = Duration(seconds: 30); + + ///重连计数器 + int _reconnectCount = 0; + + ///重连最大次数 + int _reconnectTimes = 30; + + ///重连计时器 + Timer? _reconnectTimer; + + ///连接错误回调 + Function(dynamic e)? onError; + + ///开启回调 + Function? onStart; + + ///接收消息回调 + Function(String message)? onReceiveMes; + + ///关闭连接回调; + Function? onClosed; + + ///注册websocket + void initWebSocket( + {Duration? heartDuration, + Function? onStart, + Function(String message)? onReceiveMes, + Function? onClosed, + Function(dynamic e)? onError}) { + this.onStart = onStart; + this.onReceiveMes = onReceiveMes; + this.onClosed = onClosed; + this.onError = onError; + if (heartDuration != null) { + this._heartDuration = heartDuration; + } + print('——————————webSocket init ——————————'); + } + + ///设置用户 + void setUser(String user) { + this.user = user; + } + + ///开启websocket + void startWebSocket() { + closeWebSocket(); + try { + _webSocket = IOWebSocketChannel.connect(Uri.parse('$baseUri/$user')); + print('webSocket已连接服务器:$baseUri/$user'); + _socketStatus = SOCKETSTATUS.CONNECTED; + endReconnect(); + onStart?.call(); + _webSocket!.stream.listen( + (event) => webSocketReceiveMessage(event as String), + onError: webSocketOnError, + onDone: webSocketClosed); + initHeartBeat(); + } catch (e) { + BotToast.showText(text: 'webSocket连接失败'); + onError?.call(e); + LoggerData.addData(e); + } + } + + //接收消息回调 + webSocketReceiveMessage(message) { + if (message == '心跳正常') { + print('心跳正常————————${DateTime.now()}'); + } else { + onReceiveMes?.call(message); + } + } + + //关闭连接回调 + webSocketClosed() { + closeWebSocket(); + onClosed?.call(); + } + //连接出错回调 + webSocketOnError(e) { + WebSocketChannelException ex = e; + _socketStatus = SOCKETSTATUS.BREAKOFF; + onError?.call(ex.message); + print('——————连接断开,开始重连'); + startReconnect(); + } + + //启动重连计时 + void startReconnect() { + endReconnect(); + _reconnectTimer = Timer.periodic(Duration(milliseconds: 5000), (timer) { + _reconnectCount++; + print('——————第${_reconnectCount}次重连'); + startWebSocket(); + if (_reconnectCount >= _reconnectTimes) { + print('——————重连失败'); + closeWebSocket(); + } + }); + } + + //重置重连计时 + void endReconnect() { + _reconnectTimer?.cancel(); + _reconnectTimer = null; + _reconnectCount = 0; + } + + ///初始化心跳 + void initHeartBeat() { + destoryHeart(); + _heartTimer = Timer.periodic(_heartDuration, (timer) { + sentHeart(); + }); + } + + //发送心跳 + void sentHeart() { + sendMessage('heartbeat'); + } + + ///销毁心跳 + void destoryHeart() { + _heartTimer?.cancel(); + _heartTimer = null; + } + + /// + ///关闭websocket + void closeWebSocket() { + if (_webSocket != null) { + _webSocket!.sink.close(); + print('——————websocket连接已关闭'); + } + endReconnect(); + destoryHeart(); + _socketStatus = SOCKETSTATUS.CLOSED; + } + + ///向websocket服务器发送消息 + void sendMessage(message) { + if (_webSocket != null) { + switch (_socketStatus) { + case SOCKETSTATUS.CONNECTED: + print('发送中:' + message); + _webSocket!.sink.add(message); + break; + case SOCKETSTATUS.CLOSED: + print('连接已关闭'); + break; + case SOCKETSTATUS.BREAKOFF: + print('发送失败'); + break; + default: + break; + } + } + } +}