当前位置:   article > 正文

webSocket的使用_usewebsocket

usewebsocket

本文将一个webSocket封装成hooks的形式,便于使用。
主要思路:
1、根据一个ws/wss地址,创建并初始化一个socket;
2、通过心跳参数heartParam存在与否,判断是否需要对当前socket进行心跳检测;
3、监听异常,socket挂掉后重新创建socket,重复过程1;
4、返回webSocket对象ws和message接收的消息wsData。

/**
 * @name useWebSocket
 * @export
 * @param {url} -(必需)ws/wss地址
 * @param {info} -(不必需)socket运行过程中的一些参数,进房参数joinParams,心跳参数heartParams
 * @returns
 * {ws} -socket对象
 * {wsData} -接收的socket消息
 */
import { useEffect, useState, useRef } from 'react'
let lockReconnect = false // 避免重复连接
const heartCheckSecond = 30 * 1000 // 心跳检测间隔时长

function useWebSocket(url, info) {
  const [wsData, setWsData] = useState({}) // 接收的消息
  const wsRef = useRef(null)
  const { joinParams, heartParams } = info??{}

  useEffect(() => {
    if (!url) return
    createWebSocket()
  }, [url])

  const createWebSocket = () => { // 创建socket连接
    wsRef.current = new WebSocket(url)
    initWebSocket()
  }

  const reconnect = () => { // 创建连接,lockReconnect使当前项目只会存在一个socket
    if (lockReconnect) return
    lockReconnect = true

    setTimeout(function () { // 没连接上会一直重连,设置延迟避免请求过多
      createWebSocket()
      lockReconnect = false
    }, 2000)
  }

  const initWebSocket = () => { // 初始化socket
    wsRef.current.onclose = function (evt) { // 关闭
      console.log('断开连接code:' + evt.code)
      reconnect()
    }

    wsRef.current.onerror = function (evt) { // 连接错误
      console.log('连接失败code:' + evt.code)
      reconnect()
    }

    wsRef.current.onopen = function () {
      var dt = new Date()
      var str = dt.getFullYear() + '-' + (dt.getMonth() + 1) + '-' + dt.getDate() + ' ' + dt.getHours() + ':' + dt.getMinutes() + ':' + dt.getSeconds()
      console.log('连接成功:' + str)
      wsRef.current.send(joinParams) // 发起c.jr进房操作
      heartParams && heartCheck.reset().start()
    }

    wsRef.current.onmessage = function (evt) {
      var data = JSON.parse(evt.data) // 接收消息string=>json
      setWsData(data)
      heartParams && heartCheck.reset().start()
    }
  }

  let heartCheck = { // 心跳检测
    timeout: heartCheckSecond,
    timeoutObj: null,
    serverTimeoutObj: null,
    reset: function() {
      clearTimeout(this.timeoutObj)
      clearTimeout(this.serverTimeoutObj)
      return this
    },
    start: function() {
      this.timeoutObj = setTimeout(function() {
        // 这里发送一个心跳,后端收到后,返回一个心跳消息,
        wsRef.current.send(heartParams)
        this.serverTimeoutObj = setTimeout(function() { // 如果超过一定时间还没重置,说明后端主动断开了
          wsRef.current.close()
        }, this.timeout)
      }, this.timeout)
    }
  }

  return [wsRef.current, wsData]
}

export default useWebSocket
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
import useWebSocket from './useWebSocket'
const [ws, wsData] = useWebSocket(wsUrl, { joinParams: '' })

useEffect(() => {
    console.log('webSocket message:', wsData)
}, [wsData])

const handleSendMessage = (params) => { // 向socket发送消息,格式为string
	ws.send(JSON.stringify(params))
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/煮酒与君饮/article/detail/964217
推荐阅读
相关标签
  

闽ICP备14008679号