Browse Source

增加socket 配置

caner 2 years ago
parent
commit
a5b7cc3d85
4 changed files with 130 additions and 2 deletions
  1. 1 0
      .env.production
  2. 7 1
      src/pages/App.vue
  3. 1 1
      src/pages/store/index.ts
  4. 121 0
      src/services/socket.service.ts

+ 1 - 0
.env.production

@@ -1,2 +1,3 @@
 VITE_SERVER_URL=https://jkbj.scrbg.com:5013
 VITE_SERVER_URL=https://jkbj.scrbg.com:5013
+VITE_SOCKET_API=wss://eas.any8.cc:8010/websocket
 # VITE_SERVER_URL=https://eas.any8.cc:8010
 # VITE_SERVER_URL=https://eas.any8.cc:8010

+ 7 - 1
src/pages/App.vue

@@ -15,11 +15,17 @@
 <script setup lang='ts'>
 <script setup lang='ts'>
 import loading from '@/components/loading.vue'
 import loading from '@/components/loading.vue'
 import useStore from './store/index'
 import useStore from './store/index'
-import { computed } from 'vue'
+import { computed, onMounted } from 'vue'
 import { zhCN, dateZhCN } from 'naive-ui'
 import { zhCN, dateZhCN } from 'naive-ui'
 import Theme from '@/assets/naive-theme'
 import Theme from '@/assets/naive-theme'
 import '@/assets/global-style.scss'
 import '@/assets/global-style.scss'
+import SocketService from '@/services/socket.service'
+
+const socket = new SocketService()
 const store = useStore()
 const store = useStore()
 const show = computed(() => store.loading)
 const show = computed(() => store.loading)
 const themeOverrides = Theme
 const themeOverrides = Theme
+onMounted(()=>{
+  socket.connect()
+})
 </script>
 </script>

File diff suppressed because it is too large
+ 1 - 1
src/pages/store/index.ts


+ 121 - 0
src/services/socket.service.ts

@@ -0,0 +1,121 @@
+import useStore from '@/pages/store'
+import { injectable, Service } from './service'
+
+@injectable
+export default class SocketService extends Service {
+  private _socket: WebSocket | null = null
+
+  private _reconnectTimeout: string | number | NodeJS.Timeout | undefined = undefined
+
+  private _ping = JSON.stringify({ event: 'heartbeat', content: 'ping' })
+
+  private _reconnectTime = 3000
+
+  private _heartInterval: string | number | NodeJS.Timeout | undefined = undefined
+
+  private _messageTime = 0
+
+  private _store = useStore()
+
+  /**
+   *  连接
+   */
+  private _connect() {
+    const token = this._store.token
+    if (!token) return null
+    const url = `${import.meta.env.VITE_SOCKET_API}/${token}`
+    const socket = new WebSocket(url)
+    socket.onerror = this._onError.bind(this)
+    socket.onopen = this._onOpen.bind(this)
+    socket.onmessage = this._onMessage.bind(this)
+    socket.onclose = this._onClose.bind(this)
+    this._socket = socket
+    return socket
+  }
+
+  /**
+   * 重连
+   */
+  private _reConnect() {
+    this._onClose()
+    this._reconnectTimeout = setTimeout(() => {
+      this._socket = this._connect()
+      console.log('网络连接已断开,正在尝试重新连接...')
+    }, this._reconnectTime)
+  }
+
+  /**
+    * 连接错误,重连
+    */
+  private _onError() {
+    this._reConnect()
+  }
+
+  /**
+   * 连接打开,心跳检测
+   */
+  private _onOpen() {
+    this._socket?.send(this._ping)
+  }
+
+  /**
+    * 心跳检测
+    */
+  private _heartbeat(iTime: number, pTime: number) {
+    if (this._heartInterval) clearInterval(this._heartInterval)
+    return setInterval(() => {
+      const t = new Date().getTime()
+      if ((t - this._messageTime) > pTime) {
+        this._reConnect()
+      } else {
+        if (this._socket?.readyState === 1) this._socket?.send(this._ping)
+      }
+    }, iTime)
+  }
+
+  /**
+    * 接收消息
+    */
+  private _onMessage(evt: Any) {
+    this._messageTime = new Date().getTime()
+    const data = JSON.parse(evt.data)
+    if (data.event === 'connect') {
+      const iTime = data.content.ping_interval * 1000
+      const pTime = data.content.ping_timeout * 1000
+      this._heartInterval = this._heartbeat(iTime, pTime)
+    } else {
+      this._store.setSocketMSg(data)
+    }
+  }
+
+  /**
+    * 关闭连接
+    */
+  private _onClose() {
+    clearTimeout(this._reconnectTimeout)
+    clearInterval(this._heartInterval)
+    this._socket = null
+  }
+
+  /** 链接 */
+  public connect() {
+    return this._connect()
+  }
+
+  /** 关闭 */
+  public close() {
+    if (this._socket) this._socket.close()
+    this._store.setSocketMSg(null)
+    this._onClose()
+  }
+
+  /**
+   * 推送消息
+   *
+   */
+  public emit(event: string, data: object) {
+    const content = JSON.stringify({ event, data })
+    if (!this._socket && this._socket!.readyState !== 1) return
+    this._socket?.send(content)
+  }
+}

Some files were not shown because too many files changed in this diff