ws.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. //心跳检测
  2. const heartCheck = {
  3. timeout: 10000, //10s发一次心跳
  4. timeoutObj: null,
  5. serverTimeoutObj: null,
  6. start(ws) {
  7. let self = this;
  8. this.timeoutObj && clearTimeout(this.timeoutObj);
  9. this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
  10. this.timeoutObj = setTimeout(() => {
  11. // 表示连接已经关闭或者连接不能打开。
  12. if (ws && ws.readyState === 3) return;
  13. //发送一个心跳,后端收到后,返回一个心跳消息,onmessage拿到返回的心跳就说明连接正常
  14. ws && ws.send({ data: "ping" });
  15. self.serverTimeoutObj = setTimeout(() => {
  16. ws && ws.close();
  17. websocket.reconnect();
  18. }, self.timeout + 3000);
  19. }, this.timeout);
  20. }
  21. };
  22. const websocket = {
  23. ws: null,
  24. url: '',
  25. connected: false,
  26. connecting: false,
  27. reconnectTimeId: null,
  28. callback: null, // 存放回调函数
  29. reconnetCount: 0, // 重连次数
  30. lockReconnect: false, // 避免ws重复连接
  31. createWebSocket(callback) {
  32. if (this.connected || this.connecting) { // 正在连接或者已经连接,请勿重复连接
  33. return false
  34. }
  35. try {
  36. if (callback) websocket.callback = callback;
  37. this.connecting = true;
  38. // 创建
  39. this.ws = uni.connectSocket({
  40. url: this.url,
  41. success(data) {
  42. console.log("websocket连接成功!");
  43. }
  44. });
  45. // 监听 Ws 连接打开
  46. this.ws.onOpen((res) => {
  47. this.connecting = false;
  48. this.connected = true;
  49. console.log("websocket连接打开正常!");
  50. //心跳检测重置
  51. heartCheck.start(this.ws);
  52. this.reconnetCount && (this.reconnetCount = 0);
  53. });
  54. this.ws.onError((res) => {
  55. this.connecting = false;
  56. this.connected = false;
  57. console.log("ws连接错误!", res);
  58. this.reconnect();
  59. });
  60. this.ws.onMessage((res) => {
  61. if (res.data === 'ping') {
  62. heartCheck.start(this.ws); //获取到消息,心跳检测重置
  63. // console.log("ws 没有收到消息");
  64. this.reconnetCount && (this.reconnetCount = 0);
  65. } else {
  66. // const { type, data } = JSON.parse(res.data);
  67. const { data } = res;
  68. // console.log("ws 收到消息啦:" + data);
  69. if (callback) {
  70. callback(data);
  71. } else if (websocket.callback) {
  72. websocket.callback(data);
  73. }
  74. }
  75. });
  76. this.ws.onClose((res) => {
  77. this.connected = false;
  78. this.ws = null;
  79. // console.log('WebSocket 已关闭!');
  80. // this.reconnect();
  81. });
  82. } catch (e) {// 重连
  83. this.connected = false;
  84. this.ws = null;
  85. this.reconnect();
  86. }
  87. },
  88. reconnect() { // 重连
  89. if (this.lockReconnect) return;
  90. if (this.reconnetCount === 6) {
  91. this.close();
  92. return
  93. }
  94. this.lockReconnect = true;
  95. this.reconnetCount++;
  96. this.reconnectTimeId && clearTimeout(this.reconnectTimeId);
  97. this.reconnectTimeId = setTimeout(() => {//没连接上会一直重连,设置延迟避免请求过多
  98. this.createWebSocket(websocket.callback);
  99. this.lockReconnect = false;
  100. }, 3000);
  101. },
  102. close() { // 关闭
  103. if (this.ws && this.ws.close) {
  104. this.ws.close && this.ws.close();
  105. this.ws = null;
  106. }
  107. this.connected = false;
  108. this.connecting = false;
  109. this.lockReconnect = false;
  110. this.reconnetCount = 0;
  111. this.reconnectTimeId && clearTimeout(this.reconnectTimeId);
  112. heartCheck.timeoutObj && clearTimeout(heartCheck.timeoutObj);
  113. heartCheck.serverTimeoutObj && clearTimeout(heartCheck.serverTimeoutObj);
  114. }
  115. }
  116. export default websocket;