websocket_sdk.js 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. import packetCode from './PacketCodeC.js'
  2. import store from './store/index.js'
  3. import * as config from './config'
  4. export default class Websocket {
  5. constructor({
  6. heartCheck,
  7. isReconnection
  8. }) {
  9. // 是否连接
  10. this._isLogin = false;
  11. // 当前网络状态
  12. this._netWork = true;
  13. // 是否人为退出
  14. this._isClosed = false;
  15. // 心跳检测频率
  16. this._timeout = 3000;
  17. this._timeoutObj = null;
  18. // 当前重连次数
  19. this._connectNum = 0;
  20. // 心跳检测和断线重连开关,true为启用,false为关闭
  21. this._heartCheck = heartCheck;
  22. this._isReconnection = isReconnection;
  23. this._showLoginDialog = true
  24. // this._onSocketOpened();
  25. }
  26. // 心跳重置
  27. _reset() {
  28. clearTimeout(this._timeoutObj);
  29. return this;
  30. }
  31. // 心跳开始
  32. _start(options) {
  33. let _this = this;
  34. this._timeoutObj = setInterval(() => {
  35. //发送心跳
  36. _this.sendHeartbeatData(options);
  37. _this.getTips()
  38. }, this._timeout);
  39. }
  40. // 监听websocket连接关闭
  41. onSocketClosed(options) {
  42. uni.onSocketError(err => {
  43. console.log('当前websocket连接已关闭,错误信息为:' + JSON.stringify(err));
  44. // 停止心跳连接
  45. if (this._heartCheck) {
  46. this._reset();
  47. }
  48. // 关闭已登录开关
  49. this._isLogin = false;
  50. // 检测是否是用户自己退出小程序
  51. console.log('------------------开启重连--------------------------------')
  52. if (!this._isClosed) {
  53. // 进行重连
  54. if (this._isReconnection) {
  55. this._reConnect(options)
  56. }
  57. }
  58. })
  59. uni.onSocketClose(err => {
  60. })
  61. }
  62. // 检测网络变化
  63. onNetworkChange(options) {
  64. uni.onNetworkStatusChange(res => {
  65. console.log('当前网络状态:' + res.isConnected);
  66. if (!this._netWork) {
  67. this._isLogin = false;
  68. // 进行重连
  69. if (this._isReconnection) {
  70. this._reConnect(options)
  71. }
  72. }
  73. })
  74. }
  75. _onSocketOpened(options) {
  76. uni.onSocketOpen(res => {
  77. console.log('【websocket】已打开');
  78. // 打开已登录开关
  79. this._isLogin = true;
  80. // 发送心跳
  81. if (this._heartCheck) {
  82. this._reset()._start(options);
  83. }
  84. // 发送登录信息
  85. this.sendLoginData();
  86. // 打开网络开关
  87. this._netWork = true;
  88. })
  89. }
  90. // 接收服务器返回的消息
  91. onReceivedMsg(callBack) {
  92. uni.onSocketMessage(event => {
  93. if (typeof callBack == "function") {
  94. callBack(event)
  95. } else {
  96. console.log('参数的类型必须为函数')
  97. }
  98. })
  99. }
  100. // 建立websocket连接
  101. initWebSocket(options) {
  102. let _this = this;
  103. if (this._isLogin) {
  104. console.log("您已经登录了");
  105. } else {
  106. // 检查网络
  107. uni.getNetworkType({
  108. success(result) {
  109. if (result.networkType != 'none') {
  110. // 开始建立连接
  111. console.log('建立websocket连接' + options.url);
  112. uni.connectSocket({
  113. url: options.url,
  114. success(res) {
  115. if (typeof options.success == "function") {
  116. options.success(res)
  117. _this._onSocketOpened(options);
  118. } else {
  119. console.log('参数的类型必须为函数')
  120. }
  121. },
  122. fail(err) {
  123. if (typeof options.fail == "function") {
  124. options.fail(err)
  125. } else {
  126. console.log('参数的类型必须为函数')
  127. }
  128. }
  129. })
  130. } else {
  131. console.log('网络已断开');
  132. _this._netWork = false;
  133. // 网络断开后显示model
  134. uni.showModal({
  135. title: '网络错误',
  136. content: '请重新打开网络',
  137. showCancel: false,
  138. success: function(res) {
  139. if (res.confirm) {
  140. console.log('用户点击确定')
  141. }
  142. }
  143. })
  144. }
  145. }
  146. })
  147. }
  148. }
  149. // 发送websocket消息
  150. sendWebSocketMsg(options) {
  151. this.sendBinary(1,options);
  152. }
  153. //发送心跳连接
  154. sendHeartbeatData(options) {
  155. var that = this
  156. let packet = {
  157. version: 1,
  158. command: 17,
  159. token: store.state.userData.token
  160. }
  161. this.sendBinary(99, {
  162. data: packet,
  163. success(res) {
  164. // console.log('【websocket】心跳连接成功');
  165. if(!that._showLoginDialog){
  166. that._showLoginDialog= true
  167. }
  168. },
  169. fail(err) {
  170. console.log('【websocket】心跳连接失败');
  171. console.log(err)
  172. console.log('this._showLoginDialog',that._showLoginDialog )
  173. uni.hideLoading()
  174. that._isLogin = false
  175. that._reConnect(options)
  176. }
  177. });
  178. }
  179. //发送第一次连接数据
  180. sendLoginData() {
  181. this.sendBinary(99, {
  182. data: {},
  183. success(res) {
  184. console.log('【websocket】第一次连接成功')
  185. },
  186. fail(err) {
  187. console.log('【websocket】第一次连接失败')
  188. console.log(err)
  189. }
  190. });
  191. // this.sendBinary(99, {});
  192. // socket.sendSocketMessage({
  193. // // 这里是第一次建立连接所发送的信息,应由前后端商量后决定
  194. // data: JSON.stringify({
  195. // "key": 'value'
  196. // })
  197. // })
  198. }
  199. // 重连方法,会根据时间频率越来越慢
  200. _reConnect(options) {
  201. let timer, _this = this;
  202. if (this._connectNum < 20) {
  203. timer = setTimeout(() => {
  204. this.initWebSocket(options)
  205. }, 500)
  206. this._connectNum += 1;
  207. } else if (this._connectNum < 50) {
  208. timer = setTimeout(() => {
  209. this.initWebSocket(options)
  210. }, 1000)
  211. this._connectNum += 1;
  212. } else {
  213. timer = setTimeout(() => {
  214. this.initWebSocket(options)
  215. }, 3000)
  216. this._connectNum += 1;
  217. }
  218. }
  219. // 关闭websocket连接
  220. closeWebSocket() {
  221. uni.closeSocket();
  222. this._isClosed = true;
  223. }
  224. //发送二进制
  225. sendBinary(commendType, options) {
  226. uni.sendSocketMessage({
  227. data: packetCode.encode(options.data),
  228. success(res) {
  229. if (typeof options.success == "function") {
  230. options.success(res)
  231. } else {
  232. console.log('参数的类型必须为函数')
  233. }
  234. },
  235. fail(err) {
  236. if (typeof options.fail == "function") {
  237. options.fail(err)
  238. } else {
  239. console.log('参数的类型必须为函数')
  240. }
  241. }
  242. });
  243. }
  244. getTips(){
  245. return new Promise(resolve => {
  246. var userInfo
  247. if (!userInfo || !userInfo.accessToken) {
  248. userInfo = uni.getStorageSync('userInfo')
  249. }
  250. let accessToken = userInfo ? userInfo.accessToken : ''
  251. let baseUrl = config.def().baseUrl
  252. var data = {}
  253. var _mt = 'getTips'
  254. var _gp = 'integral'
  255. uni.request({
  256. url: baseUrl + '/m.api',
  257. data: {
  258. ...data,
  259. _gp,
  260. _mt
  261. },
  262. method: 'POST',
  263. header: {
  264. 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
  265. 'ACCESSTOKEN': accessToken
  266. },
  267. success: (res) => {
  268. if (res.statusCode === 200) {
  269. let name = 'myTip';
  270. let value = res.data.data.myTips;
  271. if(value > 0){
  272. uni.setTabBarBadge({
  273. index: 4,
  274. text: value+""
  275. })
  276. }
  277. store.commit('$uStore', {
  278. name,
  279. value
  280. });
  281. name = 'taskTip';
  282. value = res.data.data.task;
  283. store.commit('$uStore', {
  284. name,
  285. value
  286. });
  287. name = 'contractTip';
  288. value = res.data.data.contract;
  289. store.commit('$uStore', {
  290. name,
  291. value
  292. });
  293. }
  294. }
  295. })
  296. })
  297. }
  298. }