1. export default class WebSocketClass {
    2. /**
    3. * @description: 初始化实例属性,保存参数
    4. * @param {String} url ws的接口
    5. * @param {Function} msgCallback 服务器信息的回调传数据给函数
    6. * @param {String} name 可选值 用于区分ws,用于debugger
    7. */
    8. constructor(url, msgCallback, name = 'websocket') {
    9. this.url = url
    10. this.msgCallback = msgCallback
    11. this.name = name
    12. this.ws = null // websocket对象
    13. this.status = null // websocket是否关闭
    14. this.lockReconnect = false //是否真正建立连接
    15. this.reconnectTimer = null //断开 重连倒计时
    16. }
    17. /**
    18. * @description: 初始化 连接websocket或重连webSocket时调用
    19. * @param {*} 可选值 要传的数据
    20. */
    21. connect(data) {
    22. // 新建 WebSocket 实例
    23. this.ws = new WebSocket(this.url)
    24. this.ws.onopen = (e) => {
    25. // 连接ws成功回调
    26. this.status = 'open'
    27. console.log(`${this.name}连接成功`, e)
    28. // this.heartCheck();
    29. if (data !== undefined) {
    30. // 有要传的数据,就发给后端
    31. return this.ws.send(data)
    32. }
    33. }
    34. // 监听服务器端返回的信息
    35. this.ws.onmessage = (e) => {
    36. // 把数据传给回调函数,并执行回调
    37. // if (e.data === 'pong') {
    38. // this.pingPong = 'pong'; // 服务器端返回pong,修改pingPong的状态
    39. // }
    40. return this.msgCallback(e.data)
    41. }
    42. // ws关闭回调
    43. this.ws.onclose = (e) => {
    44. this.closeHandle(e) // 判断是否关闭
    45. }
    46. // ws出错回调
    47. this.onerror = (e) => {
    48. this.closeHandle(e) // 判断是否关闭
    49. }
    50. }
    51. heartCheck() {
    52. // 心跳机制的时间可以自己与后端约定
    53. this.pingPong = 'ping' // ws的心跳机制状态值
    54. this.pingInterval = setInterval(() => {
    55. if (this.ws.readyState === 1) {
    56. // 检查ws为链接状态 才可发送
    57. this.ws.send('ping') // 客户端发送ping
    58. }
    59. }, 10000)
    60. this.pongInterval = setInterval(() => {
    61. if (this.pingPong === 'ping') {
    62. this.closeHandle('pingPong没有改变为pong') // 没有返回pong 重启webSocket
    63. }
    64. // 重置为ping 若下一次 ping 发送失败 或者pong返回失败(pingPong不会改成pong),将重启
    65. console.log('返回pong')
    66. this.pingPong = 'ping'
    67. }, 20000)
    68. }
    69. // 发送信息给服务器
    70. sendHandle(data) {
    71. console.log(`${this.name}发送消息给服务器:`, data)
    72. return this.ws.send(data)
    73. }
    74. closeHandle(e = 'err') {
    75. // 因为webSocket并不稳定,规定只能手动关闭(调closeMyself方法),否则就重连
    76. if (this.status !== 'close') {
    77. console.log(`${this.name}断开,重连websocket`, e)
    78. this.reconnect() // 重连
    79. } else {
    80. console.log(`${this.name}websocket手动关闭`)
    81. }
    82. }
    83. // 手动关闭WebSocket
    84. closeMyself() {
    85. console.log(`关闭${this.name}`)
    86. this.status = 'close'
    87. return this.ws.close()
    88. }
    89. //重新连接 1s,设置延迟避免请求过多
    90. reconnect() {
    91. //设置lockReconnect变量避免重复连接
    92. if (this.lockReconnect) return
    93. this.lockReconnect = true
    94. this.reconnectTimer && clearTimeout(this.reconnectTimer)
    95. this.reconnectTimer = setTimeout(() => {
    96. this.connect()
    97. this.lockReconnect = false
    98. }, 1000)
    99. }
    100. }