From 089bf5d2378b3c4a61d795b2a92bede2c193b771 Mon Sep 17 00:00:00 2001
From: admin <344137771@qq.com>
Date: Tue, 06 Jan 2026 11:22:58 +0800
Subject: [PATCH] 1

---
 src/plugins/ws-socket.js |  242 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 242 insertions(+), 0 deletions(-)

diff --git a/src/plugins/ws-socket.js b/src/plugins/ws-socket.js
new file mode 100644
index 0000000..83a2692
--- /dev/null
+++ b/src/plugins/ws-socket.js
@@ -0,0 +1,242 @@
+class WsSocket {
+  /**
+   * Websocket 连接
+   *
+   * @var Websocket
+   */
+  connect = null
+
+  /**
+   * 配置信息
+   *
+   * @var Object
+   */
+  config = {
+    heartbeat: {
+      setInterval: null,
+      pingInterval: 20000,
+      pingTimeout: 60000,
+    },
+    reconnect: {
+      lockReconnect: false,
+      setTimeout: null, // 计时器对象
+      time: 5000, // 重连间隔时间
+      number: 1000, // 重连次数
+    },
+  }
+
+  // 最后心跳时间
+  lastTime = 0
+
+  /**
+   * 自定义绑定消息事件
+   *
+   * @var Array
+   */
+  onCallBacks = []
+
+  defaultEvent = {
+    onError: evt => {},
+    onOpen: evt => {},
+    onClose: evt => {},
+  }
+
+  /**
+   * 创建 WsSocket 的实例
+   *
+   * @param {Function} urlCallBack url闭包函数
+   * @param {Object} events 原生 WebSocket 绑定事件
+   */
+  constructor(urlCallBack, events) {
+    this.urlCallBack = urlCallBack
+
+    // 定义 WebSocket 原生方法
+    this.events = Object.assign({}, this.defaultEvent, events)
+
+    this.on('connect', data => {
+      this.config.heartbeat.pingInterval = data.ping_interval * 1000
+      this.config.heartbeat.pingTimeout = data.ping_timeout * 1000
+      this.heartbeat()
+    })
+  }
+
+  /**
+   * 事件绑定
+   *
+   * @param {String} event 事件名
+   * @param {Function} callBack 回调方法
+   */
+  on(event, callBack) {
+    this.onCallBacks[event] = callBack
+
+    return this
+  }
+
+  /**
+   * 加载 WebSocket
+   */
+  loadSocket() {
+    const url = this.urlCallBack()
+
+    const connect = new WebSocket(url)
+    connect.onerror = this.onError.bind(this)
+    connect.onopen = this.onOpen.bind(this)
+    connect.onmessage = this.onMessage.bind(this)
+    connect.onclose = this.onClose.bind(this)
+
+    this.connect = connect
+  }
+
+  /**
+   * 连接 Websocket
+   */
+  connection() {
+    this.connect == null && this.loadSocket()
+  }
+
+  /**
+   * 掉线重连 Websocket
+   */
+  reconnect() {
+    // 没连接上会一直重连,设置延迟避免请求过多
+    clearTimeout(this.config.reconnect.setTimeout)
+
+    this.config.reconnect.setTimeout = setTimeout(() => {
+      this.connection()
+
+      console.log(`网络连接已断开,正在尝试重新连接...`)
+    }, this.config.reconnect.time)
+  }
+
+  /**
+   * 解析接受的消息
+   *
+   * @param {Object} evt Websocket 消息
+   */
+  onParse(evt) {
+    const { event, content } = JSON.parse(evt.data)
+
+    return {
+      event: event,
+      data: content,
+      orginData: evt.data,
+    }
+  }
+
+  /**
+   * 打开连接
+   *
+   * @param {Object} evt Websocket 消息
+   */
+  onOpen(evt) {
+    this.lastTime = new Date().getTime()
+
+    this.events.onOpen(evt)
+
+    this.ping()
+  }
+
+  /**
+   * 关闭连接
+   *
+   * @param {Object} evt Websocket 消息
+   */
+  onClose(evt) {
+    this.events.onClose(evt)
+
+    this.connect.close()
+
+    this.connect = null
+
+    evt.code == 1006 && this.reconnect()
+  }
+
+  /**
+   * 连接错误
+   *
+   * @param {Object} evt Websocket 消息
+   */
+  onError(evt) {
+    this.events.onError(evt)
+    this.connect.close()
+    this.connect = null
+    this.reconnect()
+  }
+
+  /**
+   * 接收消息
+   *
+   * @param {Object} evt Websocket 消息
+   */
+  onMessage(evt) {
+    this.lastTime = new Date().getTime()
+
+    let result = this.onParse(evt)
+
+    // 判断消息事件是否被绑定
+    if (this.onCallBacks.hasOwnProperty(result.event)) {
+      this.onCallBacks[result.event](result.data, result.orginData)
+    } else {
+      console.warn(`WsSocket 消息事件[${result.event}]未绑定...`)
+    }
+  }
+
+  /**
+   * WebSocket 心跳检测
+   */
+  heartbeat() {
+    this.config.heartbeat.setInterval = setInterval(() => {
+      let t = new Date().getTime()
+
+      if (t - this.lastTime > this.config.heartbeat.pingTimeout) {
+        
+        if(this.connect){
+          this.connect.close()
+        }
+
+        this.reconnect()
+      } else {
+        this.ping()
+      }
+    }, this.config.heartbeat.pingInterval)
+  }
+
+  ping() {
+    this.connect.send('{"event":"heartbeat","content":"ping"}')
+  }
+
+  /**
+   * 聊天发送数据
+   *
+   * @param {Object} mesage
+   */
+  send(mesage) {
+    this.connect.send(JSON.stringify(mesage))
+  }
+
+  /**
+   * 关闭连接
+   */
+  close() {
+    this.connect.close()
+  }
+
+  /**
+   * 推送消息
+   *
+   * @param {String} event 事件名
+   * @param {Object} data 数据
+   */
+  emit(event, data) {
+    const content = JSON.stringify({ event, data })
+
+    if (this.connect && this.connect.readyState === 1) {
+      this.connect.send(content)
+    } else {
+      alert('WebSocket 连接已关闭...')
+      console.error('WebSocket 连接已关闭...', this.connect)
+    }
+  }
+}
+
+export default WsSocket

--
Gitblit v1.9.3