index.js 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. import {showToast} from "@/utils/app";
  2. import config from "@/utils/config";
  3. import {logs} from "@/utils/util";
  4. import store from "@/store";
  5. export class Socket {
  6. constructor() {
  7. this.socketTask = null
  8. this.connectRun = false
  9. this.isOpen = false //避免重复连接
  10. this.option = {
  11. connectNum: 1,// 重连次数
  12. connectMaxNum: 3,// 重连最大次数
  13. reconnectTime: 3000,// 重连最大间隔时间
  14. heartInterval: 15000, // 心跳间隔
  15. }
  16. this.followFlake = false // followFlake == true 重连
  17. //心跳检测
  18. this.heartbeatInterval = null //检测服务器端是否还活着
  19. this.reconnectTimeOut = null //重连之后多久再次重连
  20. this.connectList = {}
  21. this.openFun = {}
  22. this.messageFun = {}
  23. this.closeFun = {}
  24. }
  25. // 进入这个页面的时候创建websocket连接【整个页面随时使用】
  26. async connect() {
  27. return new Promise(async (resolve, reject) => {
  28. if (this.socketTask || this.connectRun) {
  29. resolve()
  30. return;
  31. }
  32. let that = this
  33. this.connectRun = true
  34. try {
  35. this.socketTask = uni.connectSocket({
  36. url: config.get('socketWss') + `?form=teacher&token=${store.getters['user/loginToken']}`,
  37. // header: {
  38. // // 'content-type': 'application/json',
  39. // form: 'teacher',
  40. // token: store.getters['user/loginToken'],
  41. // },
  42. success: () => {
  43. logs("正准备建立websocket中...");
  44. // 返回实例
  45. },
  46. fail: (err) => {
  47. logs("× 建立websocket失败");
  48. reject()
  49. // 返回实例
  50. },
  51. });
  52. this.socketTask.onOpen((res) => {
  53. console.log('onOpen', res)
  54. this.option.connectNum = 1
  55. logs("WebSocket连接正常!");
  56. clearInterval(this.reconnectTimeOut)
  57. clearInterval(this.heartbeatInterval)
  58. this.isOpen = true;
  59. this.start();
  60. resolve()
  61. })
  62. this.connectRun = false
  63. this.socketTask.onMessage(async (e) => {
  64. // 字符串转json
  65. let res = JSON.parse(e.data);
  66. // if (res.type != 'ping') logs("res---------->", res) // 这里 查看 推送过来的消息
  67. let k = res.type
  68. if (k) {
  69. let key = this.connectList[k]
  70. if (!key) return
  71. let fun = this.messageFun[key]
  72. if (fun) await fun(res)
  73. } else {
  74. console.log('未知内容', res)
  75. }
  76. });
  77. // 监听连接失败,这里代码我注释掉的原因是因为如果服务器关闭后,和下面的onclose方法一起发起重连操作,这样会导致重复连接
  78. this.socketTask.onError((res) => {
  79. logs('WebSocket连接打开失败,请检查!', res);
  80. // this.socketTask = null
  81. // this.isOpen = false;
  82. // uni.$off('getPositonsOrder')
  83. // if (!this.isOpen) {
  84. // if (this.option.connectNum < this.option.connectMaxNum) {
  85. // uni.showToast({
  86. // title: `WebSocket连接失败,正尝试第${this.option.connectNum}次连接`,
  87. // icon: "none"
  88. // })
  89. // this.reconnect();
  90. // this.option.connectNum += 1
  91. // } else {
  92. // // uni.$emit('connectError');
  93. // this.reconnect(false);
  94. // }
  95. // }
  96. });
  97. // 这里仅是事件监听【如果socket关闭了会执行】
  98. this.socketTask.onClose(async () => {
  99. logs("socketTask 已经被关闭了-------")
  100. clearInterval(this.heartbeatInterval)
  101. clearInterval(this.reconnectTimeOut)
  102. this.socketTask = null
  103. this.isOpen = false;
  104. for (const k in that.closeFun) {
  105. that.closeFun[k]()
  106. }
  107. })
  108. } catch (e) {
  109. }
  110. })
  111. }
  112. // 主动关闭socket连接
  113. close() {
  114. if (!this.socketTask) return
  115. this.socketTask.close({
  116. success() {
  117. showToast('SocketTask 关闭成功')
  118. }
  119. });
  120. }
  121. //发送消息
  122. send(data, success = null, fail = null) {
  123. // 注:只有连接正常打开中 ,才能正常成功发送消息
  124. if (this.socketTask && this.isOpen) {
  125. this.socketTask.send({
  126. data: JSON.stringify(data),
  127. async success() {
  128. if (success) success()
  129. },
  130. async fail(e) {
  131. console.error(`推送服务器失败:${e}`)
  132. if (fail) fail()
  133. },
  134. });
  135. }
  136. }
  137. //开启心跳检测
  138. start() {
  139. this.heartbeatInterval = setInterval(() => {
  140. this.send({
  141. "type": "ping"
  142. });
  143. }, this.option.heartInterval)
  144. // 重连
  145. for (const k in this.openFun) {
  146. this.openFun[k]()
  147. }
  148. }
  149. //重新连接
  150. reconnect(run = true) {
  151. //停止发送心跳
  152. clearInterval(this.heartbeatInterval)
  153. //如果不是人为关闭的话,进行重连
  154. clearTimeout(this.reconnectTimeOut)
  155. this.reconnectTimeOut = null
  156. if (run && !this.isOpen && !this.connectRun) {
  157. this.reconnectTimeOut = setTimeout(() => {
  158. this.connect();
  159. }, this.option.reconnectTime)
  160. } else if (!run) {
  161. this.option.connectNum = 1
  162. }
  163. }
  164. stopHeartRate() {
  165. clearInterval(this.heartbeatInterval)
  166. }
  167. addConnect(type, key) {
  168. this.connectList[type] = key
  169. }
  170. delConnect(deviceId) {
  171. if (this.connectList[deviceId]) delete this.connectList[deviceId]
  172. }
  173. // init() {
  174. // if (this.connectState) return;
  175. // let socketWss = config.get('socketWss')
  176. // if (!socketWss) return;
  177. // this.username = store.getters['user/username']
  178. // let that = this
  179. // let connectSocket = uni.connectSocket({
  180. // url: socketWss,
  181. // header: {
  182. // 'content-type': 'application/json'
  183. // },
  184. // });
  185. // uni.onSocketOpen(function (res) {
  186. // that.connect = connectSocket
  187. // that.connectState = !0
  188. // showSuccess('投影成功')
  189. // that.sendMessage({
  190. // cmd: 'login',
  191. // port: 'TeacherPc',
  192. // username: that.username,
  193. // })
  194. // });
  195. // uni.onSocketError(function (res) {
  196. // showToast('连接实时投影展示失败')
  197. // that.connectState = !1
  198. // });
  199. // uni.onSocketMessage(function (res) {
  200. // if (!res.data) return;
  201. // let {code, data, msg} = JSON.parse(res.data)
  202. // logs('onSocketMessage', res.data)
  203. // if (code == 50003) {
  204. // that.sendMessage({
  205. // cmd: 'online'
  206. // })
  207. // } else {
  208. // logs('onSocketMessage', code, data, msg)
  209. // }
  210. // });
  211. // }
  212. //
  213. // /**
  214. // * 发送信息
  215. // * @param data
  216. // */
  217. // sendMessage(data = {}) {
  218. // if (!this.connectState) return;
  219. // uni.sendSocketMessage({
  220. // data: JSON.stringify(data)
  221. // });
  222. // }
  223. //
  224. // /**
  225. // * 关闭连接
  226. // */
  227. // closeSocket() {
  228. // if (!this.connectState) return;
  229. // uni.closeSocket()
  230. // }
  231. }