ws.ts 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. import user, { UserRole } from '~/store/user';
  2. export type TSocketRes<T> = {
  3. content?: T,
  4. client_name?: string
  5. client_id?: string
  6. from_client_id?: string
  7. from_client_name?: string
  8. time: string
  9. to_client_id?: string
  10. type: string
  11. }
  12. const CLIENT_NAME = `${user.user_id}|${user.user_realname}|${UserRole}`
  13. export function createSocket(
  14. options: { teacher: string, student: string },
  15. hooks: {
  16. message: Function,
  17. reload?: Function
  18. }
  19. ) {
  20. const ws: WebSocket & { LastPingTime?: number } = new WebSocket("wss://socket.bozedu.net")
  21. ws.LastPingTime = Date.now()
  22. setInterval(() => {
  23. const now = Date.now()
  24. console.log(`[SOCKET 心跳检测](${options.teacher}_${options.student}) :`);
  25. console.log(new Date(now).toLocaleString(), new Date(ws.LastPingTime!).toLocaleString(), `${(now - ws.LastPingTime!) / 1000}s`);
  26. if (ws.LastPingTime && now - ws.LastPingTime > 15000) {
  27. console.log(`[SOCKET PONG](${options.teacher}_${options.student}): ${CLIENT_NAME}`);
  28. // 重新连接
  29. hooks?.reload?.()
  30. ws.LastPingTime = Date.now()
  31. }
  32. }, 10000);
  33. ws.addEventListener('message', (e) => {
  34. if (e.data) {
  35. try {
  36. const data: TSocketRes<string> = JSON.parse(e.data)
  37. if (data.type === 'ping') {
  38. console.log(`[SOCKET PING](${options.teacher}_${options.student})`);
  39. ws.LastPingTime = Date.now()
  40. return
  41. }
  42. if (CLIENT_NAME === data.from_client_name) return
  43. if (!['ping'].includes(data.type)) {
  44. ws.LastPingTime = Date.now()
  45. console.groupCollapsed(`[SOCKET ${data.type.toLocaleUpperCase()}](${options.teacher}_${options.student}) ${data.time} : ${data.client_name ?? data.from_client_name}`)
  46. console.log(data);
  47. }
  48. if (data.type === 'login') {
  49. }
  50. if (data.type === 'say') {
  51. const content = {
  52. ...data,
  53. content: JSON.parse(decodeURIComponent(data.content!))
  54. }
  55. console.log(content);
  56. hooks.message(content)
  57. }
  58. } catch (error) {
  59. console.error(error);
  60. } finally {
  61. console.groupEnd();
  62. }
  63. }
  64. })
  65. ws.addEventListener('error', (err) => {
  66. console.error('ws error :>> ', ws, err);
  67. })
  68. ws.addEventListener('open', (e) => {
  69. console.log(`[ws open](${options.teacher}_${options.student})`);
  70. ws.send(JSON.stringify({
  71. "type": "login",
  72. "client_name": CLIENT_NAME,
  73. "room_id": `aiwen_consult_${options.teacher}_${options.student}`
  74. }))
  75. })
  76. ws.addEventListener('close', (e) => {
  77. console.log(`[ws close](${options.teacher}_${options.student})`);
  78. })
  79. return ws
  80. }
  81. export function socketSend(ws: WebSocket & { LastPingTime?: number }, content: unknown) {
  82. console.log('socketSend ws : ')
  83. ws.LastPingTime = Date.now()
  84. if (ws.readyState === WebSocket.OPEN) {
  85. // WebSocket 连接已建立
  86. ws.send(
  87. JSON.stringify({
  88. type: "say",
  89. to_client_id: 'all',
  90. content: encodeURIComponent(JSON.stringify(content))
  91. })
  92. )
  93. } else {
  94. ws.onopen = () => {
  95. ws.send(
  96. JSON.stringify({
  97. type: "say",
  98. to_client_id: 'all',
  99. content: encodeURIComponent(JSON.stringify(content))
  100. })
  101. )
  102. }
  103. }
  104. }