WebSocket使用

 

目录

一、新建WebSocket.ts文件

二、使用


一、新建WebSocket.ts文件

import { ref, onUnmounted } from 'vue'
interface SocketOptions {
  heartbeatInterval?: number
  reconnectInterval?: number
  maxReconnectAttempts?: number
}

class Socket {
  url: string
  ws: WebSocket | null = null
  opts: SocketOptions
  reconnectAttempts = 0
  listeners: { [key: string]: Function[] } = {}
  heartbeatInterval: number | null = null

  constructor(url: string, opts: SocketOptions = {}) {
    this.url = url
    this.opts = {
      heartbeatInterval: 30000, // 心跳
      reconnectInterval: 5000, // 重连时间
      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)
  }

  onOpen(event: Event) {
    console.log('WebSocket opened:', event)
    this.reconnectAttempts = 0
    this.startHeartbeat()
    this.emit('open', event)
  }

  onMessage(event: MessageEvent) {
    console.log('WebSocket message received:', event.data)
    this.emit('message', event.data)
  }

  onError(event: Event) {
    console.error('WebSocket error:', event)
    this.emit('error', event)
  }

  onClose(event: CloseEvent) {
    console.log('WebSocket closed:', event)
    this.stopHeartbeat()
    this.emit('close', event)

    if (this.reconnectAttempts < this.opts.maxReconnectAttempts!) {
      setTimeout(() => {
        this.reconnectAttempts++
        this.init()
      }, this.opts.reconnectInterval)
    }
  }

  startHeartbeat() {
    if (!this.opts.heartbeatInterval) return

    this.heartbeatInterval = window.setInterval(() => {
      if (this.ws?.readyState === WebSocket.OPEN) {
        this.ws.send('ping')
      }
    }, this.opts.heartbeatInterval)
  }

  stopHeartbeat() {
    if (this.heartbeatInterval) {
      clearInterval(this.heartbeatInterval)
      this.heartbeatInterval = null
    }
  }

  send(data: string) {
    console.log('给socket发送消息============>', data)
    if (this.ws?.readyState === WebSocket.OPEN) {
      this.ws.send(data)
    } else {
      console.error('WebSocket is not open. Cannot send:', data)
    }
  }

  on(event: string, callback: Function) {
    if (!this.listeners[event]) {
      this.listeners[event] = []
    }
    this.listeners[event].push(callback)
  }

  off(event: string) {
    if (this.listeners[event]) {
      delete this.listeners[event]
    }
  }

  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')
  })

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

二、使用

  let WebSocket = null
  const cookie = encodeURIComponent(document.cookie)
  const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
  const url = `xxxxxxxxx?token=${cookie}`
  if (
    window.location.hostname === 'localhost' ||
    window.location.hostname === '192.168.1.153' //本地ip调试使用
  ) {
    WebSocket = useSocket(`wss://${'xxx.xxx.com'}/${url}`)
  } else {
    WebSocket = useSocket(`${protocol}//${window.location.host}/${url}`)
  }
  const { socket, send, on, off } = WebSocket

  on('open', event => {
    console.log("Connected to server", event);
  });
  on('message', data => {
    console.log("Received data:", data);

  // base64解密
    const reader = new FileReader()
    reader.onload = function (e) {
      const base64Content = JSON.parse(e.target.result)
      console.log(base64Content)
    }
    reader.readAsText(data) // 以text文本显示
  });
  on('error', error => {
    console.error("WebSocket Error:", error);
  });
  on('close', event => {
    console.log("Connection closed", event);
  });
 
 //数据发送给后端
 send(
   JSON.stringify({
     type: 'upload',
     limit: 100000,
   })
 )

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天高任鸟飞dyz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值