最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue3+Ts+Vite項(xiàng)目websoket封裝使用方式

 更新時(shí)間:2025年10月27日 09:48:20   作者:禮貌而已  
文章介紹了如何封裝WebSocket并進(jìn)行頁(yè)面使用,包括安裝npm、創(chuàng)建websocket.ts文件、配置請(qǐng)求地址、全局類(lèi)型聲明以及在頁(yè)面中引用和注冊(cè)

一、安裝

  • npm
npm install websocket --save-dev
  • pnpm
pnpm install websocket --save-dev

二、封裝

在 /src/utils 文件夾下創(chuàng)建 websocket.ts 文件,并放入如下代碼

import { onUnmounted } from 'vue'

//設(shè)置
interface SocketOptions {
  //心跳間隔
  heartbeatInterval?: number
  //超時(shí)重傳
  reconnectInterval?: number
  //最大重傳次數(shù)
  maxReconnectAttempts?: number
}

class Socket {
  //路徑
  url: string
  ws: WebSocket | null = null
  opts: SocketOptions
  //重傳次數(shù)
  reconnectAttempts: number = 0
  listeners: { [key: string]: Function[] } = {}
  //心跳間隔
  heartbeatInterval: number | null = null
  //構(gòu)造函數(shù)
  constructor(url: string, opts: SocketOptions = {}) {
    this.url = url
    this.opts = {
      //心跳間隔
      heartbeatInterval: 30000,
      //超時(shí)重傳
      reconnectInterval: 5000,
      //最大重傳次數(shù)
      maxReconnectAttempts: 5,
      ...opts
    }

    this.init()
  }
  //初始化
  init() {
    this.ws = new WebSocket(this.url)
    this.ws.onopen = this.onOpen.bind(this)
    this.ws.onmessage = this.onMessage.bind(this)
    this.ws.onerror = this.onError.bind(this)
    this.ws.onclose = this.onClose.bind(this)
  }
  //打開(kāi)
  onOpen(event: Event) {
    console.log('WebSocket opened:', event)
    this.reconnectAttempts = 0
    this.startHeartbeat()
    this.emit('open', event)
  }
  //收到的WebSocket消息
  onMessage(event: MessageEvent) {
    // console.log('WebSocket message received:', event.data);
    this.emit('message', event.data)
  }
  //錯(cuò)誤
  onError(event: Event) {
    console.error('WebSocket error:', event)
    this.emit('error', event)
  }
  //重連邏輯中,在連接失敗后自動(dòng)重新連接
  onClose(event: CloseEvent) {
    console.log('WebSocket closed:', event)
    this.stopHeartbeat()
    this.emit('close', event)
    //重連邏輯中,在連接失敗后自動(dòng)重新連接,但會(huì)限制重連的次數(shù)和每次重連之間的間隔時(shí)間
    if (this.opts.maxReconnectAttempts !== 0 && this.reconnectAttempts < this.opts.maxReconnectAttempts!) {
      setTimeout(() => {
        // console.log("我有錯(cuò)誤了1111111111111111111111111111111111111");
        this.reconnectAttempts++
        this.init()
      }, this.opts.reconnectInterval)
    }
  }
  //開(kāi)始心跳檢測(cè)
  startHeartbeat() {
    if (!this.opts.heartbeatInterval) return

    this.heartbeatInterval = window.setInterval(() => {
      if (this.ws?.readyState === WebSocket.OPEN) {
        this.ws.send('ping')
      }
    }, this.opts.heartbeatInterval)
  }
  //停止心跳檢測(cè)
  stopHeartbeat() {
    if (this.heartbeatInterval) {
      clearInterval(this.heartbeatInterval)
      this.heartbeatInterval = null
    }
  }
  //發(fā)送消息
  send(data: string) {
    if (this.ws?.readyState === WebSocket.OPEN) {
      this.ws.send(data)
    } else {
      console.error('WebSocket is not open. Cannot send:', data)
    }
  }
  //事件監(jiān)聽(tīng)器注冊(cè)功能的實(shí)現(xiàn)
  on(event: string, callback: Function) {
    if (!this.listeners[event]) {
      this.listeners[event] = []
    }
    this.listeners[event].push(callback)
  }
  //從事件監(jiān)聽(tīng)器中移除
  off(event: string) {
    if (this.listeners[event]) {
      delete this.listeners[event]
    }
  }
  //在事件監(jiān)聽(tīng)器中觸發(fā)一個(gè)指定的事件
  emit(event: string, data: any) {
    this.listeners[event]?.forEach(callback => callback(data))
  }
}

export function useSocket(url: string, opts?: SocketOptions) {
  const socket = new Socket(url, opts)

  onUnmounted(() => {
    socket.off('open')
    socket.off('message')
    socket.off('error')
    socket.off('close')
    socket.ws?.close() // 關(guān)閉WebSocket連接
  })

  return {
    socket,
    send: socket.send.bind(socket),
    on: socket.on.bind(socket),
    off: socket.off.bind(socket)
  }
}

三、請(qǐng)求地址配置

3.1 將接口地址放到 public

3.2 引入 ipconfig.js 文件

3.3 全局類(lèi)型聲明

declare global {
  /**
   * Window 的類(lèi)型提示
   */
  interface Window {
    __APP_INFO__: __APP_INFO__
    global_config: { wsURL: string }
  }
}

四、頁(yè)面使用

4.1 引用

import { useSocket } from '@/utils/websocket'

4.2 注冊(cè)

// 注意:此處 useSocket() 中用的就是我們配置的全局地址
// 開(kāi)發(fā)結(jié)束,打包給后端,后端同時(shí)可以自行修改 ipconfig.js 文件中 websokect 地址,這樣部署上線之后 websokect 也能正常運(yùn)行
const { socket, on } = useSocket((window as any).global_config.wsURL)

on('close', () => console.log('Socket closed!'))
//webSocket連接上服務(wù)器時(shí)
on('open', (event: any) => {
  console.log('webSocket連接上服務(wù)器時(shí)', event)
})
socket.on('message', (data: any) => {
  if (data) {
   // TODO: 此處拿到后端推送過(guò)來(lái)的數(shù)據(jù),進(jìn)行你后續(xù)的數(shù)據(jù)渲染邏輯
   console.log(JSON.parse(data))
  }
})

五、說(shuō)明

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Vue3中ref的用法舉例總結(jié)(避免混淆)

    Vue3中ref的用法舉例總結(jié)(避免混淆)

    這篇文章主要給大家介紹了關(guān)于Vue3中ref的用法舉例總結(jié)的相關(guān)資料,ref()接受一個(gè)內(nèi)部值,返回一個(gè)響應(yīng)式的可更改的ref對(duì)象,此對(duì)象只有一個(gè)指向其內(nèi)部值的屬性.value,需要的朋友可以參考下
    2023-10-10
  • Vue使得大屏自適應(yīng)的多種方法

    Vue使得大屏自適應(yīng)的多種方法

    這篇文章主要介紹了Vue使得大屏自適應(yīng)的多種方法,自適屏幕,始終保持16:9的比例,還一種是使用CSS scale屬性對(duì)大屏幕做自適應(yīng)處理,需要的朋友可以參考下
    2023-10-10
  • ElementUI中el-tree節(jié)點(diǎn)的操作的實(shí)現(xiàn)

    ElementUI中el-tree節(jié)點(diǎn)的操作的實(shí)現(xiàn)

    這篇文章主要介紹了ElementUI中el-tree節(jié)點(diǎn)的操作的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • 解決vue A對(duì)象賦值給B對(duì)象,修改B屬性會(huì)影響到A的問(wèn)題

    解決vue A對(duì)象賦值給B對(duì)象,修改B屬性會(huì)影響到A的問(wèn)題

    今天小編就為大家分享一篇解決vue A對(duì)象賦值給B對(duì)象,修改B屬性會(huì)影響到A的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09
  • Vue結(jié)合echarts實(shí)現(xiàn)繪制水滴圖

    Vue結(jié)合echarts實(shí)現(xiàn)繪制水滴圖

    這篇文章主要為大家詳細(xì)介紹了Vue如何結(jié)合echarts實(shí)現(xiàn)水滴圖的繪制,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-07-07
  • vue超時(shí)計(jì)算的組件實(shí)例代碼

    vue超時(shí)計(jì)算的組件實(shí)例代碼

    這篇文章主要介紹了vue超時(shí)計(jì)算的組件實(shí)例代碼,需要的朋友可以參考下
    2018-07-07
  • apache和nginx下vue頁(yè)面刷新404的解決方案

    apache和nginx下vue頁(yè)面刷新404的解決方案

    這篇文章主要介紹了apache和nginx下vue頁(yè)面刷新404的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • 簡(jiǎn)單的三步vuex入門(mén)

    簡(jiǎn)單的三步vuex入門(mén)

    通過(guò)簡(jiǎn)單的三步讓大家對(duì)VUEX快速的入門(mén),本文還介紹了VUEX的最基礎(chǔ)的函數(shù)以及相關(guān)知識(shí)點(diǎn),有興趣的學(xué)習(xí)下。
    2018-05-05
  • 使用Vite+Vue3+TypeScript?搭建開(kāi)發(fā)腳手架的詳細(xì)過(guò)程

    使用Vite+Vue3+TypeScript?搭建開(kāi)發(fā)腳手架的詳細(xì)過(guò)程

    這篇文章主要介紹了Vite+Vue3+TypeScript?搭建開(kāi)發(fā)腳手架的詳細(xì)過(guò)程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-02-02
  • Element-ui?Dialog對(duì)話框基本使用

    Element-ui?Dialog對(duì)話框基本使用

    這篇文章主要為大家介紹了Element-ui?Dialog對(duì)話框基本使用示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06

最新評(píng)論

祁阳县| 南阳市| 铜川市| 崇文区| 南皮县| 浮梁县| 左权县| 无极县| 德州市| 友谊县| 磐安县| 渭南市| 怀集县| 商河县| 壶关县| 儋州市| 黄石市| 肃宁县| 东阳市| 鹿泉市| 五寨县| 安宁市| 抚松县| 枞阳县| 邹平县| 大新县| 中江县| 仁寿县| 年辖:市辖区| 石阡县| 东海县| 东明县| 寿宁县| 贵溪市| 嘉荫县| 定襄县| 南投市| 拉孜县| 会同县| 星子县| 互助|