websocket【JS封装】

242 阅读2分钟

本篇文章将介绍如何使用 JavaScript 类来封装 WebSocket 通信的细节,我们通过一个 WS 类来封装 WebSocket 的所有操作。这个类不仅管理 WebSocket 的生命周期,包括连接、消息处理、断线重连,还处理心跳检测来保持连接的活跃性。

核心功能

1. 类定义与配置

WS 类通过一个接口 IConfig 接受外部配置,包括 WebSocket 服务器的 URL 和心跳检测的时间间隔。

    interface IConfig { url?: string time?: number }

2. 构造函数

类的构造函数使用默认参数设置 WebSocket 的 URL 和时间间隔。

3. 事件处理器

WS 类实现了四个核心的 WebSocket 事件处理器:onOpenonMessageonCloseonError

  • onOpen:连接打开时初始化心跳检测。
  • onMessage:接收消息并根据消息事件类型进行处理,如 heartCheck 或业务逻辑。
  • onClose:连接关闭时清理资源。
  • onError:出现错误时尝试重连。

4. 心跳检测

心跳机制通过 startHeartCheck 方法实现,确保客户端和服务器端的连接是活跃的。

5. 服务器检查

checkServer 方法用于检测服务器的响应,如果超时未响应,则触发重连逻辑。

6. 消息发送

send 方法允许用户通过 WS 类向服务器发送消息。

7. 重连机制

reconnect 方法封装了重连逻辑,通过调用 initWebsocket 函数实现。

8. WebSocket 创建和管理

create 方法创建 WebSocket 实例,并设置事件处理器。

实现细节

消息处理

onMessage 方法中,我们解析从服务器接收到的消息,并根据消息中的事件类型执行相应的业务逻辑。例如,如果收到心跳检测消息,将重置心跳检测和服务器检查的定时器。

状态管理

通过 Vuex store 管理 WebSocket 数据,确保应用的状态与 WebSocket 接收到的数据同步。

文本到语音

根据接收到的消息内容和应用状态,onMessage 方法还可能调用 sayTTS 函数,将文本转换为语音输出
TTS 可以看下我上一篇文章JS原生文字转语音(不需安装任何包和插件)

代码

// utils => websocket.ts
import store from '@/store'
import { sayTTS } from './sayTTS'
import { initWebsocket } from './commUtils'
interface IConfig {
  url?: string
  time?: number
}

class WS {
  url: string
  time: number
  ws: WebSocket
  createTimer: any
  heartCheckTimer: any
  constructor(config: IConfig = {}) {
    this.url = config.url || 'localhost'
    this.time = config.time || 30 * 1000
    this.ws = null
  }

  onOpen = () => {
    this.startHeartCheck()
  }
  onMessage = (e) => {
    const { event, data } = JSON.parse(e.data)
    if (event === 'heartCheck') {
      this.startHeartCheck()
      this.checkServer()
    } else {
      const newData = JSON.parse(data)
      newData && store.commit('setWsData', newData)
      if (newData.voiceType !== 0 && store.state.isPlay === 'play') {
        sayTTS(newData.content)
      }
    }
  }
  onClose = () => {
    clearTimeout(this.createTimer)
    this.ws.close()
  }
  onError = () => {
    setTimeout(() => {
      this.reconnect()
    }, 10000)
  }
  startHeartCheck = () => {
    this.heartCheckTimer = setTimeout(() => {
      if (this.ws.readyState !== 1) return
      this.ws.send(JSON.stringify({ event: 'heartCheck' }))
    }, this.time)
  }
  checkServer = () => {
    clearTimeout(this.createTimer)
    this.createTimer = setTimeout(() => {
      this.onClose()
      this.onError()
    }, this.time + 5000)
  }
  send = (message) => {
    this.ws.send(message)
  }
  reconnect = () => {
    initWebsocket()
  }
  create() {
    this.ws = new WebSocket(this.url)
    this.ws.onopen = this.onOpen
    this.ws.onmessage = this.onMessage
    this.ws.onclose = this.onClose
    this.ws.onerror = this.onError
  }
}
export default WS

最后

希望我分享的websocket封装可以帮到你!

水平有限,还不能写到尽善尽美,希望大家多多交流,跟春野一同进步!!!