ws.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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. this.reconnetCount && (this.reconnetCount = 0);
  64. } else {
  65. const { type, data } = JSON.parse(res.data);
  66. // console.log("ws 收到消息啦:" + type);
  67. if (callback) {
  68. callback(type, data);
  69. } else if (websocket.callback) {
  70. websocket.callback(type, data);
  71. }
  72. }
  73. });
  74. this.ws.onClose((res) => {
  75. this.connected = false;
  76. this.ws = null;
  77. // console.log('WebSocket 已关闭!');
  78. // this.reconnect();
  79. });
  80. } catch (e) {// 重连
  81. this.connected = false;
  82. this.ws = null;
  83. this.reconnect();
  84. }
  85. },
  86. reconnect() { // 重连
  87. if (this.lockReconnect) return;
  88. if (this.reconnetCount === 6) {
  89. this.close();
  90. return
  91. }
  92. this.lockReconnect = true;
  93. this.reconnetCount++;
  94. this.reconnectTimeId && clearTimeout(this.reconnectTimeId);
  95. this.reconnectTimeId = setTimeout(() => {//没连接上会一直重连,设置延迟避免请求过多
  96. this.createWebSocket(websocket.callback);
  97. this.lockReconnect = false;
  98. }, 3000);
  99. },
  100. close() { // 关闭
  101. if (this.ws && this.ws.close) {
  102. this.ws.close && this.ws.close();
  103. this.ws = null;
  104. }
  105. this.connected = false;
  106. this.connecting = false;
  107. this.lockReconnect = false;
  108. this.reconnetCount = 0;
  109. this.reconnectTimeId && clearTimeout(this.reconnectTimeId);
  110. heartCheck.timeoutObj && clearTimeout(heartCheck.timeoutObj);
  111. heartCheck.serverTimeoutObj && clearTimeout(heartCheck.serverTimeoutObj);
  112. }
  113. }
  114. export default websocket;