websocket.ts 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /**
  2. * @module initWebSocket 初始化
  3. * @module websocketOnopen 连接成功
  4. * @module websocketOnerror 连接失败
  5. * @module websocketClose 断开连接
  6. * @module resetHeart 重置心跳
  7. * @module sendSocketHeart 心跳发送
  8. * @module reconnect 重连
  9. * @module sendMsg 发送数据
  10. * @module websocketOnmessage 接收数据
  11. * @module test 测试收到消息传递
  12. * @description socket 通信
  13. * @param {any} url socket地址
  14. * @param {any} websocket websocket 实例
  15. * @param {any} heartTime 心跳定时器实例
  16. * @param {number} socketHeart 心跳次数
  17. * @param {number} HeartTimeOut 心跳超时时间
  18. * @param {number} socketError 错误次数
  19. */
  20. import { getToken } from '@/utils/token'
  21. import { ElNotification } from 'element-plus'
  22. import useNoticeStore from '@/stores/modules/notice'
  23. let socketUrl: any = '' // socket地址
  24. let websocket: any = null // websocket 实例
  25. let heartTime: any = null // 心跳定时器实例
  26. let socketHeart = 0 as number // 心跳次数
  27. const HeartTimeOut = 10000 // 心跳超时时间 10000 = 10s
  28. let socketError = 0 as number // 错误次数
  29. import { getTimeState } from '@/utils'
  30. // 初始化socket
  31. export const initWebSocket = (url: any) => {
  32. if (import.meta.env.VITE_APP_WEBSOCKET === 'false') {
  33. return
  34. }
  35. socketUrl = url
  36. // 初始化 websocket
  37. websocket = new WebSocket(url + '?Authorization=Bearer ' + getToken() + '&clientId=' + import.meta.env.VITE_APP_CLIENT_ID)
  38. websocketOnopen()
  39. websocketOnmessage()
  40. websocketOnerror()
  41. websocketClose()
  42. sendSocketHeart()
  43. return websocket
  44. }
  45. // socket 连接成功
  46. export const websocketOnopen = () => {
  47. websocket.onopen = function () {
  48. console.log('连接 websocket 成功')
  49. resetHeart()
  50. }
  51. }
  52. // socket 连接失败
  53. export const websocketOnerror = () => {
  54. websocket.onerror = function (e: any) {
  55. console.log('连接 websocket 失败', e)
  56. }
  57. }
  58. // socket 断开链接
  59. export const websocketClose = () => {
  60. websocket.onclose = function (e: any) {
  61. console.log('断开连接', e)
  62. }
  63. }
  64. // socket 重置心跳
  65. export const resetHeart = () => {
  66. socketHeart = 0
  67. socketError = 0
  68. clearInterval(heartTime)
  69. sendSocketHeart()
  70. }
  71. // socket心跳发送
  72. export const sendSocketHeart = () => {
  73. heartTime = setInterval(() => {
  74. // 如果连接正常则发送心跳
  75. if (websocket.readyState == 1) {
  76. // if (socketHeart <= 30) {
  77. websocket.send(
  78. JSON.stringify({
  79. type: 'ping'
  80. })
  81. )
  82. socketHeart = socketHeart + 1
  83. } else {
  84. // 重连
  85. reconnect()
  86. }
  87. }, HeartTimeOut)
  88. }
  89. // socket重连
  90. export const reconnect = () => {
  91. if (socketError <= 2) {
  92. clearInterval(heartTime)
  93. initWebSocket(socketUrl)
  94. socketError = socketError + 1
  95. // eslint-disable-next-line prettier/prettier
  96. console.log('socket重连', socketError)
  97. } else {
  98. // eslint-disable-next-line prettier/prettier
  99. console.log('重试次数已用完')
  100. clearInterval(heartTime)
  101. }
  102. }
  103. // socket 发送数据
  104. export const sendMsg = (data: any) => {
  105. websocket.send(data)
  106. }
  107. const playSound = () => {
  108. const audio = new Audio('src/assets/audio/tip.mp3')
  109. audio.play()
  110. }
  111. // socket 接收数据
  112. export const websocketOnmessage = () => {
  113. websocket.onmessage = function (e: any) {
  114. let title = '消息'
  115. if (e.data.indexOf('heartbeat') > 0) {
  116. resetHeart()
  117. }
  118. if (e.data.indexOf('ping') > 0) {
  119. return
  120. }
  121. useNoticeStore().addNotice({
  122. message: e.data,
  123. read: false,
  124. time: new Date().toLocaleString()
  125. })
  126. if (e.data.indexOf('欢迎') == 0) {
  127. title = getTimeState() as any
  128. }
  129. ElNotification({
  130. title,
  131. message: e.data,
  132. type: 'success',
  133. duration: 3000
  134. })
  135. playSound()
  136. return e.data
  137. }
  138. }