IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> typescript + vue3 实现websocket+心跳机制写入 纯代码记录 -> 正文阅读

[网络协议]typescript + vue3 实现websocket+心跳机制写入 纯代码记录

代码(可直接使用)

/* eslint-disable @typescript-eslint/no-unused-vars */
import path from '_api/axios/addressConfig'

import { getStore } from '@/tools/session'

interface OnMessageIter {
  (event: MessageEvent):any
}
interface HeartbeatKey {
  [key:string]:any
}
interface HeartbeatIter extends HeartbeatKey {
  detectionTimer:number
  timeoutTimer:number
  reconnectTimer:number
  sendTimer:number
  isConnected:boolean
  stopReconnect:boolean
  clearTimer: (key:string) => void
  start: (instance:any) => void
  reconnect: (instance:any) => void
  resetHeart: (instance:any) => void
  sendMsg: (instance:any) => void
}
interface WebSocketIter {
  instance:WebSocket | null
  open:(this:WebSocket, event: Event) => any
  close:(this: WebSocket, event: CloseEvent) => any
  error:(this: WebSocket, event: Event) => any
  init:(message:OnMessageIter, url?:string) => void
  sendToken:() => boolean
  closeConnection: () => void
  heartbeat:HeartbeatIter
}
// 保存init入参的fn 在心跳机制中使用
let durableMessageFn:OnMessageIter | null = null

const middlewareSocket:WebSocketIter = {
  instance: null,
  open: function (this:WebSocket, event: Event) {
    console.log('webSocket连接成功 ...')
    middlewareSocket.sendToken()
    middlewareSocket.heartbeat.start(middlewareSocket)
    middlewareSocket.heartbeat.sendMsg(middlewareSocket)
  },
  close: function (this: WebSocket, event: CloseEvent) {
    console.log('webSocket 断开: ' + event.code + ' ' + event.reason + ' ' + event.wasClean)
    middlewareSocket.heartbeat.reconnect(middlewareSocket)
  },
  error: function (this: WebSocket, event: Event) {
    console.log('连接错误', event)
    middlewareSocket.heartbeat.reconnect(middlewareSocket)
  },
  init: function (message, url = `ws://${path.wsUrl}/ws`) {
    if (this.instance?.readyState === 1) {
      console.warn('已存在连接')
      return
    }
    durableMessageFn = message
    this.instance = new WebSocket(url)
    this.instance.onmessage = function (this:WebSocket, event:MessageEvent) {
      console.log(event, '数据')
      middlewareSocket.heartbeat.resetHeart(middlewareSocket)
      message(event)
    }
    this.instance.onopen = this.open
    this.instance.onclose = this.close
    this.instance.onerror = this.error
  },
  sendToken: function ():boolean {
    const token:string | null = getStore('token')
    if (this.instance?.readyState === 1 && token) {
      this.instance?.send(`token:"${token}`)
      return true
    }
    return false
  },
  closeConnection: function () {
    this.instance?.close()
  },
  heartbeat: {
    detectionTimer: 0,
    timeoutTimer: 0,
    reconnectTimer: 0,
    sendTimer: 0,
    isConnected: false,
    stopReconnect: false,
    clearTimer: function (key:string) {
      if (this[key] !== 0) {
        clearTimeout(this[key])
        this[key] = 0
      }
    },
    start: function (instance:WebSocketIter) {
      this.clearTimer('detectionTimer')
      this.clearTimer('timeoutTimer')
      this.detectionTimer = setTimeout(() => {
        this.isConnected = instance.sendToken()
        if (!this.isConnected) {
          // 重新连接
          this.reconnect(instance)
          this.timeoutTimer = setTimeout(() => {
            console.warn('websocket重连超时')
            instance.closeConnection()
          }, 30 * 1000)
        }
      }, 5 * 1000)
    },
    reconnect: function (instance:WebSocketIter) {
      if (this.stopReconnect) {
        return
      }
      this.stopReconnect = true
      instance.closeConnection()
      console.warn('尝试重新连接websocket')
      this.clearTimer('reconnectTimer')
      this.reconnectTimer = setTimeout(() => {
        instance.init(durableMessageFn as OnMessageIter)
        this.stopReconnect = false
      }, 20 * 1000)
    },
    resetHeart: function (instance:WebSocketIter) {
      this.clearTimer('detectionTimer')
      this.clearTimer('timeoutTimer')
      this.start(instance)
    },
    // 配合服务器做心跳机制
    sendMsg: function (instance:WebSocketIter) {
      clearInterval(this.sendTimer)
      this.sendTimer = setInterval(() => {
        if (!(instance.sendToken())) {
          this.reconnect(instance)
          clearInterval(this.sendTimer)
        }
      }, 10 * 1000)
    }
  }
}

export default middlewareSocket

use

middlewareSocket.init(function (event:MessageEvent) {
  console.log(event)
  console.log('收到服务器数据: ' + event.data)
})
  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-01-16 13:28:51  更:2022-01-16 13:29:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年10日历 -2024/10/5 9:25:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码