socket.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. export default class Websocket {
  2. constructor({
  3. heartCheck,
  4. isReconnection
  5. }) {
  6. // 是否连接
  7. this._isLogin = false;
  8. // 当前网络状态
  9. this._netWork = true;
  10. // 是否人为退出
  11. this._isClosed = false;
  12. // 心跳检测频率
  13. this._timeout = 3000;
  14. this._timeoutObj = null;
  15. // 当前重连次数
  16. this._connectNum = 0;
  17. // 心跳检测和断线重连开关,true为启用,false为关闭
  18. this._heartCheck = heartCheck;
  19. this._isReconnection = isReconnection;
  20. this._onSocketOpened();
  21. this.wsUrl = ""
  22. }
  23. // 心跳重置
  24. _reset() {
  25. clearTimeout(this._timeoutObj);
  26. return this;
  27. }
  28. // 心跳开始
  29. _start() {
  30. let _this = this;
  31. this._timeoutObj = setInterval(() => {
  32. wx.sendSocketMessage({
  33. // 心跳发送的信息应由前后端商量后决定
  34. data: JSON.stringify({
  35. "key": 'value'
  36. }),
  37. success(res) {
  38. // console.log(res)
  39. // console.log("发送心跳成功");
  40. },
  41. fail(err) {
  42. console.log(err)
  43. _this._reset()
  44. }
  45. });
  46. }, this._timeout);
  47. }
  48. // 监听websocket连接关闭
  49. onSocketClosed(options) {
  50. wx.onSocketClose(err => {
  51. console.log('当前websocket连接已关闭,错误信息为:' + JSON.stringify(err));
  52. // 停止心跳连接
  53. if (this._heartCheck) {
  54. this._reset();
  55. }
  56. // 关闭已登录开关
  57. this._isLogin = false;
  58. // 检测是否是用户自己退出小程序
  59. if (!this._isClosed) {
  60. // 进行重连
  61. if (this._isReconnection) {
  62. this._reConnect(options)
  63. }
  64. }
  65. })
  66. }
  67. // 检测网络变化
  68. onNetworkChange(options) {
  69. wx.onNetworkStatusChange(res => {
  70. console.log('当前网络状态:' + res.isConnected);
  71. if (!this._netWork) {
  72. this._isLogin = false;
  73. // 进行重连
  74. if (this._isReconnection) {
  75. this._reConnect(options)
  76. }
  77. }
  78. })
  79. }
  80. _onSocketOpened(callBack) {
  81. wx.onSocketOpen(res => {
  82. console.log('websocket已打开');
  83. // 打开已登录开关
  84. this._isLogin = true;
  85. // 发送心跳
  86. if (this._heartCheck) {
  87. this._reset()._start();
  88. }
  89. // 发送登录信息
  90. wx.sendSocketMessage({
  91. // 这里是第一次建立连接所发送的信息,应由前后端商量后决定
  92. data: JSON.stringify({
  93. "key": 'value'
  94. })
  95. })
  96. // 打开网络开关
  97. this._netWork = true;
  98. if (typeof callBack == "function") {
  99. callBack(res)
  100. } else {
  101. console.log('参数的类型必须为函数')
  102. }
  103. })
  104. }
  105. // 接收服务器返回的消息
  106. onReceivedMsg(callBack) {
  107. wx.onSocketMessage(msg => {
  108. if (typeof callBack == "function") {
  109. callBack(msg)
  110. } else {
  111. console.log('参数的类型必须为函数')
  112. }
  113. })
  114. }
  115. // 建立websocket连接
  116. initWebSocket(options) {
  117. let _this = this;
  118. this.wsUrl = options.url ? options.url : this.wsUrl
  119. if (this._isLogin) {
  120. console.log("您已经登录了");
  121. } else {
  122. // 检查网络
  123. wx.getNetworkType({
  124. success(result) {
  125. if (result.networkType != 'none') {
  126. // 开始建立连接
  127. wx.connectSocket({
  128. url: _this.wsUrl,
  129. success(res) {
  130. if (typeof options.success == "function") {
  131. options.success(res)
  132. } else {
  133. console.log('参数的类型必须为函数')
  134. }
  135. },
  136. fail(err) {
  137. if (typeof options.fail == "function") {
  138. options.fail(err)
  139. } else {
  140. console.log('参数的类型必须为函数')
  141. }
  142. }
  143. })
  144. } else {
  145. console.log('网络已断开');
  146. _this._netWork = false;
  147. }
  148. }
  149. })
  150. }
  151. }
  152. // 发送websocket消息
  153. sendWebSocketMsg(options) {
  154. // console.log("send参数:", options)
  155. wx.sendSocketMessage({
  156. data: options.data,
  157. success(res) {
  158. if (options.success && typeof options.success == "function") {
  159. options.success(res)
  160. }
  161. },
  162. fail(err) {
  163. if (options.fail && typeof options.fail == "function") {
  164. options.fail(err)
  165. }
  166. }
  167. })
  168. }
  169. // 重连方法,会根据时间频率越来越慢
  170. _reConnect(options) {
  171. let timer, _this = this;
  172. if (this._connectNum < 3) {
  173. timer = setTimeout(() => {
  174. this.initWebSocket(options)
  175. }, 3000)
  176. this._connectNum += 1;
  177. } else if (this._connectNum < 10) {
  178. timer = setTimeout(() => {
  179. this.initWebSocket(options)
  180. }, 10000)
  181. this._connectNum += 1;
  182. } else {
  183. timer = setTimeout(() => {
  184. this.initWebSocket(options)
  185. }, 450000)
  186. this._connectNum += 1;
  187. }
  188. }
  189. // 关闭websocket连接
  190. closeWebSocket() {
  191. wx.closeSocket();
  192. this._isClosed = true;
  193. }
  194. }