socket_core.dart 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. import 'dart:async';
  2. import 'package:web_socket_channel/io.dart';
  3. import 'package:web_socket_channel/web_socket_channel.dart';
  4. import '../utils/Constants.dart';
  5. import '../utils/logger.dart';
  6. /// WebSocket状态
  7. enum SocketStatus {
  8. socketStatusConnected, // 已连接
  9. socketStatusFailed, // 失败
  10. socketStatusClosed, // 连接关闭
  11. }
  12. class WebSocketUtility {
  13. /// 单例对象
  14. static final WebSocketUtility _socket = WebSocketUtility._internal();
  15. /// 内部构造方法,可避免外部暴露构造函数,进行实例化
  16. WebSocketUtility._internal();
  17. /// 获取单例内部方法
  18. factory WebSocketUtility() {
  19. return _socket;
  20. }
  21. late WebSocketChannel _webSocket; // WebSocket
  22. SocketStatus? _socketStatus; // socket状态
  23. Timer? _heartBeat; // 心跳定时器
  24. final int _heartTimes = 30000; // 心跳间隔(毫秒)
  25. final int _reconnectCount = 2; // 重连次数,默认60次
  26. int _reconnectTimes = 0; // 重连计数器
  27. Timer? _reconnectTimer; // 重连定时器
  28. late Function onError; // 连接错误回调
  29. late Function onOpen; // 连接开启回调
  30. late Function onMessage; // 接收消息回调
  31. /// 初始化WebSocket
  32. void initWebSocket({required Function onOpen, required Function onMessage, required Function onError}) {
  33. this.onOpen = onOpen;
  34. this.onMessage = onMessage;
  35. this.onError = onError;
  36. openSocket();
  37. }
  38. /// 开启WebSocket连接
  39. void openSocket() {
  40. // closeSocket();
  41. _webSocket = WebSocketChannel.connect(Uri.parse(Global.SocketUrl));
  42. logd('WebSocket连接成功: ${Global.SocketUrl}');
  43. // 连接成功,返回WebSocket实例
  44. _socketStatus = SocketStatus.socketStatusConnected;
  45. // 连接成功,重置重连计数器
  46. _reconnectTimes = 0;
  47. if (_reconnectTimer != null) {
  48. _reconnectTimer?.cancel();
  49. _reconnectTimer = null;
  50. }
  51. onOpen();
  52. // 接收消息
  53. _webSocket.stream.listen((data) => webSocketOnMessage(data),
  54. onError: webSocketOnError, onDone: webSocketOnDone);
  55. }
  56. /// WebSocket接收消息回调
  57. webSocketOnMessage(data) {
  58. onMessage(data);
  59. }
  60. /// WebSocket关闭连接回调
  61. webSocketOnDone() {
  62. logd('webSocketOnDone closed');
  63. _socketStatus = SocketStatus.socketStatusClosed;
  64. /*reconnect();*/
  65. }
  66. /// WebSocket连接错误回调
  67. webSocketOnError(e) {
  68. WebSocketChannelException ex = e;
  69. _socketStatus = SocketStatus.socketStatusFailed;
  70. onError(ex.message);
  71. closeSocket();
  72. }
  73. /// 初始化心跳
  74. void initHeartBeat() {
  75. destroyHeartBeat();
  76. _heartBeat =
  77. Timer.periodic(Duration(milliseconds: _heartTimes), (timer) {
  78. sentHeart();
  79. });
  80. }
  81. /// 心跳
  82. void sentHeart() {
  83. sendMessage('{"module": "HEART_CHECK", "message": "请求心跳"}');
  84. }
  85. /// 销毁心跳
  86. void destroyHeartBeat() {
  87. if (_heartBeat != null) {
  88. _heartBeat?.cancel();
  89. _heartBeat = null;
  90. }
  91. }
  92. /// 关闭WebSocket
  93. void closeSocket() {
  94. logd('WebSocket连接关闭');
  95. _webSocket.sink.close();
  96. destroyHeartBeat();
  97. _socketStatus = SocketStatus.socketStatusClosed;
  98. }
  99. /// 发送WebSocket消息
  100. void sendMessage(message) {
  101. switch (_socketStatus) {
  102. case SocketStatus.socketStatusConnected:
  103. logd('发送中:$message');
  104. _webSocket.sink.add(message);
  105. break;
  106. case SocketStatus.socketStatusClosed:
  107. logd('连接已关闭');
  108. break;
  109. case SocketStatus.socketStatusFailed:
  110. logd('发送失败');
  111. break;
  112. default:
  113. break;
  114. }
  115. }
  116. /// 重连机制
  117. void reconnect() {
  118. if (_reconnectTimes < _reconnectCount) {
  119. _reconnectTimes++;
  120. _reconnectTimer =
  121. Timer.periodic(Duration(milliseconds: _heartTimes), (timer) {
  122. openSocket();
  123. });
  124. } else {
  125. if (_reconnectTimer != null) {
  126. logd('重连次数超过最大次数');
  127. _reconnectTimer?.cancel();
  128. _reconnectTimer = null;
  129. }
  130. return;
  131. }
  132. }
  133. get socketStatus => _socketStatus;
  134. get webSocketCloseCode => _webSocket.closeCode;
  135. }