websocket.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. let isSocketClose = false; // 是否关闭socket
  2. let reconnectCount = 5; // 重连次数
  3. let heartbeatInterval = ""; // 心跳定时器
  4. let socketTask = null; // websocket对象
  5. let againTimer = null; //断线重连定时器
  6. let url = null;
  7. let onReFn = null;
  8. let onSucFn = null;
  9. let onErrFn = null;
  10. /**
  11. * sockeUrl:websocet的地址
  12. * onReceive:消息监听的回调
  13. * onErrorEvent:抛出错误的回调,且弹窗连接失败的提示框
  14. * onErrorSucceed:抛出成功回调,主要用于隐藏连接失败的提示框
  15. * */
  16. const sokcet = (sockeUrl, onReceive, onErrorEvent, onErrorSucceed) => {
  17. url = sockeUrl;
  18. onReFn = onReceive;
  19. onErrFn = onErrorEvent;
  20. onSucFn = onErrorSucceed;
  21. isSocketClose = false;
  22. //判断是否有websocet对象,有的话清空
  23. if (socketTask) {
  24. socketTask.close();
  25. socketTask = null;
  26. clearInterval(heartbeatInterval);
  27. }
  28. //WebSocket的地址
  29. // 【非常重要】必须确保你的服务器是成功的,如果是手机测试千万别使用ws://127.0.0.1:9099【特别容易犯的错误】
  30. let url = sockeUrl
  31. // 连接
  32. socketTask = uni.connectSocket({
  33. url: url,
  34. success(data) {
  35. console.log("websocket连接成功");
  36. clearInterval(againTimer) //断线重连定时器
  37. },
  38. fail: (err) => {
  39. console.log(url)
  40. console.log("报错", err);
  41. }
  42. });
  43. // 连接打开
  44. socketTask.onOpen((res) => {
  45. console.log('WebSocket打开');
  46. clearInterval(againTimer) //断线重连定时器
  47. onErrorSucceed({
  48. isShow: false
  49. }) // 用于提示框的隐藏
  50. heartbeatInterval && clearInterval(heartbeatInterval);
  51. // 10秒发送一次心跳
  52. heartbeatInterval = setInterval(() => {
  53. console.log('心跳')
  54. sendMsg('心跳ing')
  55. }, 1000 * 10)
  56. })
  57. // 监听连接失败
  58. socketTask.onError((err) => {
  59. console.log('WebSocket连接打开失败,请检查', err);
  60. //停止发送心跳
  61. clearInterval(heartbeatInterval)
  62. //如果不是人为关闭的话,进行重连
  63. if (!isSocketClose) {
  64. reconnect(url, onErrorEvent)
  65. }
  66. })
  67. // // 监听连接关闭 -
  68. socketTask.onClose((e) => {
  69. console.log('WebSocket连接关闭!'+JSON.stringify(e));
  70. clearInterval(heartbeatInterval)
  71. console.log('监听连接关闭'+isSocketClose)
  72. if (!isSocketClose) {
  73. reconnect(url, onErrorEvent)
  74. }
  75. })
  76. // 监听收到信息
  77. socketTask.onMessage((res) => {
  78. uni.hideLoading()
  79. let serverData = res.data
  80. //与后端规定好返回值分别代表什么,写业务逻辑
  81. serverData && onReceive(serverData);
  82. });
  83. }
  84. const reconnect = (url, onErrorEvent) => {
  85. console.log('进入断线重连', isSocketClose);
  86. clearInterval(againTimer) //断线重连定时器
  87. clearInterval(heartbeatInterval);
  88. socketTask && socketTask.close(); // 确保已经关闭后再重新打开
  89. socketTask = null;
  90. onErrorEvent({
  91. isShow: true,
  92. messge: '扫描头服务正在连接...'
  93. })
  94. // 连接 重新调用创建websocet方法
  95. againTimer = setInterval(() => {
  96. sokcet(url, onReFn, onErrFn, onSucFn)
  97. console.log('在重新连接中...');
  98. }, 1000 * 8)
  99. Vue.prototype.$againTimer =againTimer;
  100. }
  101. const sendMsg = (msg) => { //向后端发送命令
  102. msg = JSON.stringify(msg)
  103. try {
  104. //通过 WebSocket 连接发送数据
  105. socketTask.send({
  106. data: msg
  107. });
  108. } catch (e) {
  109. if (isSocketClose) {
  110. return
  111. } else {
  112. reconnect(url, onErrFn)
  113. }
  114. }
  115. }
  116. // 关闭websocket【必须在实例销毁之前关闭,否则会是underfined错误】beforeDestroy() {websocetObj.stop();}
  117. const stop = () => {
  118. isSocketClose = true;
  119. clearInterval(heartbeatInterval);
  120. clearInterval(againTimer) //断线重连定时器
  121. socketTask.close(); // 确保已经关闭后再重新打开
  122. socketTask = null;
  123. }
  124. const $debounce = function(fn, wait) {
  125. let timer = null;
  126. return function() {
  127. if (timer !== null) {
  128. clearTimeout(timer);
  129. }
  130. timer = setTimeout(fn, wait);
  131. }
  132. }
  133. export const MyWebSokcet = {
  134. sokcet,
  135. stop,
  136. sendMsg,
  137. socketTask
  138. };