new_chat.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. // +----------------------------------------------------------------------
  2. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  3. // +----------------------------------------------------------------------
  4. // | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
  5. // +----------------------------------------------------------------------
  6. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  7. // +----------------------------------------------------------------------
  8. // | Author: CRMEB Team <admin@crmeb.com>
  9. // +----------------------------------------------------------------------
  10. import $store from "@/store";
  11. import wechat from "@/libs/wechat";
  12. import {
  13. HTTP_REQUEST_URL,
  14. VUE_APP_WS_URL
  15. } from "@/config/app.js";
  16. import {
  17. getServerType
  18. } from '@/api/api.js';
  19. import {
  20. onNetworkStatusChange
  21. } from '@/libs/network.js';
  22. function wss(wsSocketUrl) {
  23. if (wsSocketUrl.indexOf('wss:') !== -1) {
  24. return wsSocketUrl;
  25. }
  26. // #ifdef H5
  27. let ishttps = document.location.protocol == 'https:';
  28. if (ishttps) {
  29. return wsSocketUrl.replace('ws:', 'wss:');
  30. } else {
  31. return wsSocketUrl.replace('wss:', 'ws:');
  32. }
  33. // #endif
  34. // #ifndef H5
  35. return wsSocketUrl.replace('ws:', 'wss:');
  36. //#endif
  37. }
  38. class Socket {
  39. constructor() {
  40. this.socketTask = null; //socket 任务
  41. this.timer = null; //心跳定时器
  42. this.connectStatus = false; //连接状态
  43. this.wsUrl = ''; //ws地址
  44. this.reconnectTimer = 2000; //重连
  45. this.handClse = false; //手动关闭
  46. this.reconnetime = null; //重连 定时器
  47. this.networkStatus = true;
  48. this.connectLing = false; //连接是否进行中
  49. this.defaultEvenv(); //执行默认事件
  50. this.networkEvent();
  51. }
  52. //网络状态变化监听
  53. networkEvent() {
  54. onNetworkStatusChange((res) => {
  55. this.networkStatus = true;
  56. if (this.socketTask) {
  57. this.socketTask.close();
  58. }
  59. uni.$on('timeout', this.timeoutEvent.bind(this))
  60. }, () => {
  61. this.networkStatus = false;
  62. this.connectStatus = false;
  63. clearInterval(this.timer);
  64. this.timer = null;
  65. uni.$off('timeout', this.timeoutEvent)
  66. });
  67. }
  68. //开始连接
  69. startConnect() {
  70. console.log('开始链接')
  71. this.handClse = false;
  72. if (!this.connectStatus) {
  73. this.init();
  74. this.connect();
  75. }
  76. }
  77. //默认事件
  78. defaultEvenv() {
  79. uni.$off('success', this.successEvent);
  80. uni.$off('timeout', this.timeoutEvent);
  81. uni.$on('success', this.successEvent.bind(this));
  82. uni.$on('timeout', this.timeoutEvent.bind(this));
  83. }
  84. timeoutEvent() {
  85. console.log('timeoutEvent')
  86. this.reconne();
  87. }
  88. successEvent() {
  89. console.log('success默认事件');
  90. // this.changOnline();
  91. }
  92. //发送用户状态
  93. changOnline() {
  94. let online = cache.get('kefu_online')
  95. if (online !== undefined && online !== '') {
  96. this.send({
  97. data: {
  98. online: online
  99. },
  100. type: 'online'
  101. });
  102. }
  103. }
  104. //连接websocket
  105. connect() {
  106. this.connectLing = true;
  107. this.socketTask = uni.connectSocket({
  108. url: this.wsUrl,
  109. complete: () => {}
  110. });
  111. this.socketTask.onOpen(this.onOpen.bind(this))
  112. this.socketTask.onError(this.onError.bind(this));
  113. this.socketTask.onMessage(this.onMessage.bind(this))
  114. this.socketTask.onClose(this.onClose.bind(this));
  115. }
  116. init() {
  117. let wsUrl = wss(`${VUE_APP_WS_URL}?type=user`),
  118. form_type = 3;
  119. //#ifdef MP || APP-PLUS
  120. form_type = 2
  121. //#endif
  122. //#ifdef H5
  123. form_type = wechat.isWeixin() ? 1 : 3
  124. //#endif
  125. this.wsUrl = `${wsUrl}&token=${$store.state.app.token}&form_type=${form_type}`
  126. }
  127. //断线重连
  128. reconne() {
  129. if (this.reconnetime || this.connectStatus) {
  130. return;
  131. }
  132. this.reconnetime = setInterval(() => {
  133. if (this.connectStatus) {
  134. return;
  135. }
  136. this.connectLing || this.connect();
  137. }, this.reconnectTimer);
  138. }
  139. onOpen() {
  140. clearInterval(this.reconnetime);
  141. this.reconnetime = null;
  142. this.connectLing = false;
  143. this.connectStatus = true;
  144. this.ping();
  145. }
  146. onError(error) {
  147. console.log('连接发生错误', error)
  148. this.connectStatus = false;
  149. this.connectLing = false;
  150. this.reconne();
  151. }
  152. onClose(err) {
  153. console.log(this.socketTask, err, '关闭连接')
  154. uni.$emit('close');
  155. //手动关闭不用重新连接
  156. if (this.handClse) {
  157. return;
  158. }
  159. clearInterval(this.timer);
  160. this.timer = null;
  161. this.connectStatus = false;
  162. this.connectLing = false;
  163. this.reconne();
  164. }
  165. ping() {
  166. this.timer = setInterval(() => {
  167. this.send({
  168. type: 'ping'
  169. })
  170. }, 10000)
  171. }
  172. onMessage(response) {
  173. let {
  174. type,
  175. data
  176. } = JSON.parse(response.data);
  177. uni.$emit(type, data);
  178. }
  179. send(data) {
  180. let that = this;
  181. //没有网络,或者没有连接
  182. if (!this.connectStatus || !this.networkStatus) {
  183. this.reconne();
  184. }
  185. return new Promise((reslove, reject) => {
  186. this.socketTask.send({
  187. data: JSON.stringify(data),
  188. success() {
  189. reslove();
  190. },
  191. fail(res) {
  192. console.log(res)
  193. if (res.errMsg ==
  194. 'sendSocketMessage:fail WebSocket is not connected' ||
  195. res.errMsg ==
  196. 'sendSocketMessage:fail Error: SocketTask.readyState is not OPEN'
  197. ) {
  198. that.reconne();
  199. }
  200. reject(res);
  201. },
  202. complete(res) {
  203. console.log(res)
  204. }
  205. })
  206. });
  207. }
  208. guid() {
  209. return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
  210. var r = Math.random() * 16 | 0,
  211. v = c == 'x' ? r : (r & 0x3 | 0x8);
  212. return v.toString(16);
  213. });
  214. }
  215. clearPing() {
  216. clearInterval(this.timer);
  217. this.timer = null;
  218. if (this.connectStatus) {
  219. this.socketTask.close();
  220. }
  221. this.handClse = true;
  222. this.connectStatus = false;
  223. this.connectLing = false;
  224. }
  225. setBadgeNumber(count) {
  226. //#ifdef APP-PLUS
  227. plus.runtime.setBadgeNumber(Number(count));
  228. //#endif
  229. }
  230. }
  231. export default Socket;