zby-live-sdk 1.0.49-beta-talrtc1014 → 1.0.49-beta-1222-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/.babelrc +5 -5
  2. package/.editorconfig +13 -13
  3. package/.eslintrc.js +29 -29
  4. package/CHANGELOG.md +419 -377
  5. package/README.md +276 -276
  6. package/dist/zby-live-sdk.cjs.js +3 -4
  7. package/dist/zby-live-sdk.esm.js +3 -4
  8. package/dist/zby-live-sdk.umd.js +3 -4
  9. package/package.json +1 -1
  10. package/src/channel/getSendMsgParams.js +66 -66
  11. package/src/channel/index.js +138 -138
  12. package/src/channel/pomelo/index.js +184 -184
  13. package/src/channel/pomelo/latestQueue.js +151 -151
  14. package/src/channel/pomelo/polemo.js +749 -749
  15. package/src/channel/pomelo/util.js +54 -54
  16. package/src/channel/sdk-cb.js +73 -73
  17. package/src/channel/stream-msg.js +97 -97
  18. package/src/channel/zby/index.js +74 -74
  19. package/src/channel/zby/interactWithChannel.js +4 -4
  20. package/src/channel/zby/interactWithChannelControl.js +1568 -1568
  21. package/src/channel/zby/interactWithChannelEntry.js +318 -318
  22. package/src/config/config.js +153 -153
  23. package/src/default/base.js +70 -70
  24. package/src/default/extend.js +36 -36
  25. package/src/default/index.js +9 -9
  26. package/src/live/base.js +42 -42
  27. package/src/live/call-method.js +9 -9
  28. package/src/live/extend.js +53 -53
  29. package/src/live/index.js +9 -9
  30. package/src/network/api.js +50 -50
  31. package/src/network/commonFetch.js +66 -66
  32. package/src/network/dataReport.js +429 -429
  33. package/src/notice.js +400 -394
  34. package/src/tool/base.js +74 -74
  35. package/src/tool/call-method.js +9 -9
  36. package/src/tool/extend.js +42 -42
  37. package/src/tool/index.js +9 -9
  38. package/src/util/bridge.js +87 -87
  39. package/src/util/bridge1.js +46 -46
  40. package/src/util/dict.js +51 -51
  41. package/src/util/sessionStorage.js +29 -29
  42. package/src/util/sha256.js +482 -482
  43. package/src/util/util.js +308 -308
  44. package/src/zby-av-sdk/agora-sdk.js +711 -711
  45. package/src/zby-av-sdk/device.js +145 -145
  46. package/src/zby-av-sdk/rtc-sdk.js +2845 -2839
  47. package/src/zby-av-sdk/talrtc-sdk.js +2394 -2392
  48. package/src/zby-av-sdk/trtc-sdk.js +1801 -1801
  49. package/src/zby-av-sdk/zby-av-sdk.js +1901 -1891
  50. package/src/zby-av-sdk/zego-sdk.js +3002 -2987
  51. package/src/zby-live-sdk.js +1564 -1561
@@ -1,749 +1,749 @@
1
- import Protocol from 'pomelo-protocol';
2
- import Protobuf from 'pomelo-protobuf';
3
- import LatestQueue from './latestQueue.js';
4
- import util from './util';
5
- import CHANNEL from '../index';
6
- import defaultApi from '../../default/extend';
7
- import dataReport from '../../network/dataReport';
8
-
9
- var _protocol = Protocol;
10
- var _protobuf = Protobuf;
11
- var _package = Protocol.Package;
12
- var _message = Protocol.Message;
13
- var _JS_WS_CLIENT_TYPE = 'js-websocket';
14
- var _JS_WS_CLIENT_VERSION = '1.0.0';
15
- // 重连间隔时间
16
- const reconnectInterval = 10 * 1000;
17
-
18
-
19
- class PomeloClient {
20
- constructor() {
21
- this.handshakeBuffer = {
22
- sys: {
23
- type: _JS_WS_CLIENT_TYPE,
24
- version: _JS_WS_CLIENT_VERSION
25
- },
26
- user: {}
27
- };
28
- this.pomeloData = {};
29
- this.heartbeatInterval = 5000;
30
- this.heartbeatTimeout = this.heartbeatInterval * 2;
31
- this.nextHeartbeatTimeout = 0;
32
- this.heartbeatId = null;
33
- this.heartbeatTimeoutId = null;
34
- this.handshakeCallback = null;
35
- this.socket = null;
36
- this.reqId = 0;
37
- this.callBacks = {};
38
- this.handlers = {};
39
- this.routeMap = {};
40
- this.initCallback = null;
41
- //自定义
42
- this.pomeloConfig = {};
43
- // 初始化参数
44
- this.indexChannelInfo = {};
45
- // 最后一条接收消息的uuid,用于消息恢复
46
- this.lastReceiveMsgUuid = '';
47
- // 是否正在获取缓存消息列表
48
- this.isGettingCacheMsgList = false;
49
- // 重连定时器
50
- this.reconnectTimer = null;
51
- // 是否在重连
52
- this.isReconnectting = false;
53
- // 是否连接成功
54
- this.isConnected = false;
55
- //是否在教室
56
- this.isInRoom = false;
57
- // 是否链接成功过
58
- this.hasConnected = false;
59
-
60
- this.latestQueueObj = new LatestQueue();
61
- this.deleteQueueTimer = setInterval(() => {
62
- this.latestQueueObj.delete.call(
63
- this.latestQueueObj,
64
- 5000 * 4,
65
- 1000
66
- );
67
- }, 1000);
68
-
69
- this.failTimes = 0;
70
- this.retryTimesWhenHeartBeatFailed = 100;
71
-
72
- this.EventType = {
73
- SOCKET_IO_ERROR: 'SOCKET_IO_ERROR'
74
- };
75
- }
76
-
77
- //初始化pomelo
78
- initPomelo(pomeloConfig, callBack) {
79
- this.pomeloConfig = pomeloConfig;
80
- let port = pomeloConfig.port ? `:${pomeloConfig.port}` : '';
81
- var url = `wss://${pomeloConfig.host}${port}`;
82
-
83
- this.handshakeBuffer.user = pomeloConfig.user;
84
- this.initCallback = callBack;
85
- // this.handshakeCallback = pomeloConfig.handshakeCallback;
86
- defaultApi.writeLog(`channel_log : ${url} ${JSON.stringify(pomeloConfig)} initPomelo ......`);
87
- //开始连接websocket
88
- this.initWebSocket(url, pomeloConfig.serverType);
89
- }
90
-
91
- joinRoom(pomeloConfig, callBack) {
92
- this.callback = callBack;
93
- this.isInRoom = true;
94
- pomeloConfig.port = '443';
95
- this.indexChannelInfo = pomeloConfig;
96
- defaultApi.writeLog(`channel_log :${JSON.stringify(pomeloConfig)} the first step to join pomelo ......`);
97
- try {
98
- dataReport.pomeloJoinRoom({pomeloConfig});
99
- } catch(e) {
100
- console.log('pomeloJoinRoom_error',e);
101
- }
102
- return this.connectGateServer(pomeloConfig);
103
- }
104
-
105
- initWebSocket(url, serverType) {
106
- var _this = this;
107
- defaultApi.writeLog(`channel_log : ${url} ${serverType} socket init......`);
108
- try {
109
- if (this.socket) {
110
- defaultApi.writeLog('channel_log : socket is closed......');
111
- this.socket.close();
112
- }
113
- } catch (e) {
114
- console.warn('pomelo socket close error', e);
115
- defaultApi.writeLog('pomelo socket close error');
116
- }
117
-
118
- //initSocket
119
- this.socket = new WebSocket(url);
120
- try {
121
- dataReport.pomeloInitWebSocket({url});
122
- } catch(e) {
123
- console.log('pomeloInitWebSocket_error',e);
124
- }
125
- defaultApi.writeLog('channel_log : new WebSocket......');
126
- this.socket.binaryType = 'arraybuffer';
127
-
128
- this.socket.onopen = evt => {
129
- _this.onSocketOpen(evt);
130
- defaultApi.writeLog(`channel_log : ${JSON.stringify(evt)} socket is onopen......`);
131
- };
132
-
133
- this.socket.onmessage = evt => {
134
- _this.onSocketMessage(evt);
135
- };
136
-
137
- this.socket.onerror = evt => {
138
- // new update start
139
- this.socket.onerror = null;
140
- this.socket.onclose = null;
141
- // new update end
142
- _this.onSocketError(evt);
143
- defaultApi.writeLog(`channel_log : ${JSON.stringify(evt)} socket is onerror......`);
144
- // 重连
145
- this.reconnect();
146
- };
147
-
148
- this.socket.onclose = evt => {
149
- // new update start
150
- this.socket.onerror = null;
151
- this.socket.onclose = null;
152
- // new update end
153
-
154
- defaultApi.writeLog(`channel_log : ${JSON.stringify(evt)} socket is onclose......`);
155
- if (serverType == 'chat') {
156
- // this.emit(SocketEventType.SOCKET_CLOSE, evt);
157
- console.log('[webSocket-state]:onClose---ErrorInfo: %j', evt);
158
- defaultApi.writeLog('[webSocket-state]:onClose---ErrorInfo: %j',evt);
159
- // 重连
160
- this.reconnect();
161
-
162
- if (this.heartbeatId) {
163
- clearTimeout(this.heartbeatId);
164
- this.heartbeatId = null;
165
- }
166
- if (this.heartbeatTimeoutId) {
167
- clearTimeout(this.heartbeatTimeoutId);
168
- this.heartbeatTimeoutId = null;
169
- }
170
- }
171
- };
172
- console.log(`===start-init-websocket${url}===`);
173
- defaultApi.writeLog(`===start-init-websocket${url}===`);
174
- }
175
- //onSocketOpen
176
- onSocketOpen(evt) {
177
- if (this.socket.readyState == 1) {
178
- var obj = _package.encode(
179
- _package.TYPE_HANDSHAKE,
180
- _protocol.strencode(JSON.stringify(this.handshakeBuffer))
181
- );
182
- this.send(obj);
183
- }
184
- }
185
-
186
- //request
187
- request(route, msg, cb) {
188
- msg = msg || {};
189
- route = route || msg.route;
190
- if (!route) {
191
- console.log('fail to send request without route.');
192
- defaultApi.writeLog('fail to send request without route.');
193
- return;
194
- }
195
- this.reqId++;
196
- this.sendMessage(this.reqId, route, msg);
197
- this.callBacks[this.reqId] = cb;
198
- this.routeMap[this.reqId] = route;
199
- }
200
-
201
- notify(route, msg) {
202
- msg = msg || {};
203
- this.sendMessage(0, route, msg);
204
- }
205
-
206
- //sendMessage
207
- sendMessage(reqId, route, msg) {
208
- var type = reqId ? _message.TYPE_REQUEST : _message.TYPE_NOTIFY;
209
- //compress message by protobuf
210
- var protos = this.pomeloData.protos
211
- ? this.pomeloData.protos.client
212
- : {};
213
- if (protos[route]) {
214
- msg = _protobuf.encode(route, msg);
215
- } else {
216
- msg = _protocol.strencode(JSON.stringify(msg));
217
- }
218
-
219
- var compressRoute = 0;
220
- msg = _message.encode(reqId, type, compressRoute, route, msg);
221
- var packet = _package.encode(_package.TYPE_DATA, msg);
222
- this.send(packet);
223
- }
224
-
225
- //onSocketMessage
226
- onSocketMessage(evt) {
227
- var msgData = _package.decode(evt.data);
228
- switch (msgData.type) {
229
- case _package.TYPE_HANDSHAKE:
230
- this.handshake(msgData.body);
231
- break;
232
- case _package.TYPE_HEARTBEAT:
233
- this.heartbeat(msgData.body);
234
- break;
235
- case _package.TYPE_DATA:
236
- // defaultApi.writeLog(`channel_log : ${JSON.stringify(msgData)} _package TYPE_DATA ......`);
237
- var msg = _message.decode(msgData.body);
238
-
239
- if (msg.id > 0) {
240
- msg.route = this.routeMap[msg.id];
241
- delete this.routeMap[msg.id];
242
- if (!msg.route) {
243
- return;
244
- }
245
- }
246
- msg.body = this.deCompose(msg);
247
- this.processMessage(msg);
248
- break;
249
- case _package.TYPE_KICK:
250
- defaultApi.writeLog('channel_log : _package TYPE_KICK ......');
251
- // this.emit(SocketEventType.POMELO_MESSAGE_KICK);
252
- break;
253
- }
254
- if (this.heartbeatTimeout) {
255
- this.nextHeartbeatTimeout = Date.now() + this.heartbeatTimeout;
256
- }
257
- }
258
- //onSocketError
259
- onSocketError(evt) {
260
- // this.emit(SocketEventType.SOCKET_IO_ERROR, evt);
261
- console.log('[webSocket-state]:onError---ErrorInfo: %j', evt);
262
- defaultApi.writeLog('[webSocket-state]:onError---ErrorInfo: %j', evt);
263
- }
264
- //onSocketClose
265
- onSocketClose(evt) {
266
- // this.emit(SocketEventType.SOCKET_CLOSE, evt);
267
- console.log('[webSocket-state]:onClose---ErrorInfo: %j', evt);
268
- defaultApi.writeLog('[webSocket-state]:onClose---ErrorInfo: %j', evt);
269
- }
270
- //handshake
271
- handshake(data) {
272
- var _this = this;
273
- data = JSON.parse(_protocol.strdecode(data));
274
- console.log(`[websocket-handshake-code:${data.code}]`);
275
- defaultApi.writeLog(`[websocket-handshake-code:${data.code}]`);
276
- // heartBeatConfig
277
- if (data.sys && data.sys.heartbeat) {
278
- this.heartbeatInterval = data.sys.heartbeat * 1000; // heartbeat interval
279
- this.heartbeatTimeout = this.heartbeatInterval * 2; // max heartbeat timeout
280
- } else {
281
- this.heartbeatInterval = 0;
282
- this.heartbeatTimeout = 0;
283
- }
284
-
285
- if (data.sys && data.sys['minHeartbeatInterval']) {
286
- this.minHeartbeatInterval = data.sys['minHeartbeatInterval'] * 1000; // heartbeat interval
287
- } else {
288
- this.minHeartbeatInterval = 3000;
289
- }
290
-
291
- if (data.sys && data.sys['retryTimesWhenHeartBeatFailed']) {
292
- this.retryTimesWhenHeartBeatFailed =
293
- data.sys['retryTimesWhenHeartBeatFailed'];
294
- }
295
-
296
- this.initPomeloData(data);
297
- // handshake-complete
298
- this.send(_package.encode(_package.TYPE_HANDSHAKE_ACK));
299
- if (this.initCallback) {
300
- this.initCallback(this.socket);
301
- this.initCallback = null;
302
- }
303
- }
304
- //heartbeat
305
- async heartbeat(data) {
306
- var _this = this;
307
- console.log('[websocket-heartbeat-state]:receive heartbeat...');
308
- defaultApi.writeLog('[websocket-heartbeat-state]:receive heartbeat...');
309
- var obj = _package.encode(_package.TYPE_HEARTBEAT);
310
-
311
- if (this.failTimes) {
312
- this.failTimes = 0;
313
- console.warn('重新连上了');
314
- defaultApi.writeLog('重新连上了');
315
- }
316
-
317
- if (this.heartbeatTimeoutId) {
318
- clearTimeout(this.heartbeatTimeoutId);
319
- this.heartbeatTimeoutId = null;
320
- }
321
-
322
- if (this.heartbeatId) {
323
- // already in a heartbeat interval
324
- return;
325
- }
326
- this.heartbeatId = setTimeout(() => {
327
- this.heartbeatId = null;
328
- this.send(obj);
329
- console.log('[pomeloclient.heartbeat]:send heartbeat...');
330
- defaultApi.writeLog('[pomeloclient.heartbeat]:send heartbeat...');
331
- this.nextHeartbeatTimeout = Date.now() + this.heartbeatTimeout;
332
- this.heartbeatTimeoutId = setTimeout(() => {
333
- this.heartbeatTimeoutCb(this);
334
- }, this.minHeartbeatInterval);
335
- }, this.heartbeatInterval);
336
- }
337
- //heartbeatTimeoutCb
338
- heartbeatTimeoutCb(that) {
339
- var self = this;
340
- console.log('heartbeatTimeoutCb log !!!');
341
- defaultApi.writeLog('heartbeatTimeoutCb log !!!');
342
- if (this.failTimes < this.retryTimesWhenHeartBeatFailed) {
343
- var obj = _package.encode(_package.TYPE_HEARTBEAT);
344
- self.send(obj);
345
- this.failTimes += 1;
346
- console.warn(`心跳重试第${this.failTimes}次`);
347
- defaultApi.writeLog(`心跳重试第${this.failTimes}次`);
348
- self.heartbeatTimeoutId = setTimeout(
349
- this.heartbeatTimeoutCb.bind(self),
350
- this.minHeartbeatInterval
351
- );
352
- } else {
353
- // update start
354
- // 超时前先断开监听事件
355
- self.socket.onmessage = null;
356
- self.socket.onerror = null;
357
- self.socket.onclose = null;
358
- // update end
359
-
360
- console.error('server heartbeat timeout');
361
- defaultApi.writeLog('server heartbeat timeout');
362
- // 重连
363
- this.reconnect();
364
- // update start
365
- // this.disconnect(true);
366
- // update end
367
- }
368
- }
369
- //processMessage
370
- processMessage(msg) {
371
- var _this = this;
372
- // eslint-disable-next-line no-extra-boolean-cast
373
- if (!!msg.body.msgId) {
374
- var replyRoute = 'connector.' + msg.route + '.ack';
375
- var replyMsg = {
376
- msgId: msg.body.msgId,
377
- ack: 1
378
- };
379
-
380
- this.notify(replyRoute, replyMsg);
381
- }
382
- if (!msg || !msg.id) {
383
- switch (msg.route) {
384
- case 'onChat':
385
- break;
386
- case 'onServer':
387
- try {
388
- const onServerMsg = JSON.parse(msg.body.msg);
389
- this.dealOnServerMsg(onServerMsg, msg.body.from);
390
- } catch (error) {
391
- }
392
- break;
393
- case 'onAdd':
394
- break;
395
- case 'onLeave':
396
- break;
397
- case 'onNotice':
398
- break;
399
- case 'onKick':
400
- this.disconnect(true);
401
- break;
402
- default:
403
- }
404
-
405
- return;
406
- }
407
- var cb = this.callBacks[msg.id];
408
- delete this.callBacks[msg.id];
409
- if (typeof cb !== 'function') {
410
- return;
411
- }
412
- cb(msg.body);
413
- return;
414
- }
415
- //deCompose
416
- deCompose(msg) {
417
- var protos = this.pomeloData.protos
418
- ? this.pomeloData.protos.server
419
- : {};
420
- var abbrs = this.pomeloData.abbrs;
421
- var route = msg.route;
422
- try {
423
- //Decompose route from dict
424
- if (msg.compressRoute) {
425
- if (!abbrs[route]) {
426
- console.error('illegal msg!');
427
- defaultApi.writeLog('illegal msg!');
428
- return {};
429
- }
430
- route = msg.route = abbrs[route];
431
- }
432
- if (protos[route]) {
433
- return _protobuf.decode(route, msg.body);
434
- }
435
- return JSON.parse(_protocol.strdecode(msg.body));
436
- } catch (ex) {
437
- console.error('route, body = ' + route + ', ' + msg.body);
438
- }
439
- return msg;
440
- }
441
- //handshakeInit
442
- initPomeloData(data) {
443
- if (!data || !data.sys) {
444
- return;
445
- }
446
- this.pomeloData = this.pomeloData || {};
447
- var dict = data.sys.dict;
448
- var protos = data.sys.protos;
449
- //Init compress dict
450
- if (dict) {
451
- this.pomeloData.dict = dict;
452
- this.pomeloData.abbrs = {};
453
- for (var route in dict) {
454
- this.pomeloData.abbrs[dict[route]] = route;
455
- }
456
- }
457
- //Init protobuf protos
458
- if (protos) {
459
- this.pomeloData.protos = {
460
- server: protos.server || {},
461
- client: protos.client || {}
462
- };
463
- if (_protobuf) {
464
- _protobuf.init({
465
- encoderProtos: protos.client,
466
- decoderProtos: protos.server
467
- });
468
- }
469
- }
470
- }
471
- //disconnect
472
- disconnect(isSelf) {
473
- if (this.socket) {
474
- this.socket.onmessage = null;
475
- this.socket.onerror = null;
476
- this.socket.onclose = null;
477
- this.isGettingCacheMsgList = false;
478
- this.isConnected = false;
479
- if (!isSelf) {
480
- this.hasConnected = false;
481
- this.isInRoom = false;
482
- if (this.reconnectTimer) {
483
- clearInterval(this.reconnectTimer);
484
- this.reconnectTimer = null;
485
- }
486
- }
487
-
488
- if (this.socket.disconnect) {
489
- this.socket.disconnect();
490
- }
491
- if (this.socket.close) {
492
- this.socket.close();
493
- }
494
- console.log('[webSocket-disconnect]');
495
- defaultApi.writeLog('[webSocket-disconnect]');
496
- }
497
- if (this.heartbeatId) {
498
- clearTimeout(this.heartbeatId);
499
- this.heartbeatId = null;
500
- }
501
- if (this.heartbeatTimeoutId) {
502
- clearTimeout(this.heartbeatTimeoutId);
503
- this.heartbeatTimeoutId = null;
504
- }
505
- if (this.deleteQueueTimer) {
506
- clearInterval(this.deleteQueueTimer);
507
- this.deleteQueueTimer = null;
508
- }
509
- }
510
- //send
511
- send(packet) {
512
- if (this.socket) {
513
- if (this.socket.readyState == 2 || this.socket.readyState == 3) {
514
- this.disconnect(true);
515
- return;
516
- }
517
- this.socket.send(packet.buffer || packet, {
518
- binary: true,
519
- mask: true
520
- });
521
- }
522
- }
523
- //发送消息
524
- sendChannelMessage(msgData, target = '*') {
525
- return new Promise((resolve, reject) => {
526
- this.request(
527
- 'chat.chatHandler.send',
528
- {
529
- // rid: this.indexChannelInfo.channelID,
530
- content: JSON.stringify(msgData),
531
- from: this.indexChannelInfo.userID,
532
- target: target || '*',
533
- route: 'onServer'
534
- },
535
- data => {
536
- if (data.error) {
537
- reject({code: -1});
538
- }
539
- resolve({code: 200});
540
- }
541
- );
542
- });
543
- }
544
- //连接gate服务器,获取chat连接地址
545
- async connectGateServer(channelInfo) {
546
- await new Promise((resolve, reject) => {
547
- this.initPomelo({
548
- serverType: 'gate',
549
- host: channelInfo.host,
550
- port: channelInfo.port,
551
- log: true
552
- }, () => {
553
- resolve(true);
554
- });
555
- });
556
- defaultApi.writeLog('channel_log : connectGateServer,the second step to join pomelo ......');
557
-
558
- const queryData = {
559
- uid: channelInfo.userId,
560
- rtype: 4,
561
- utype: 2,
562
- retrytime: new Date().getTime(),
563
- protocolVersion: '1.0',
564
- // uniqId: channelInfo.guid
565
- };
566
-
567
- console.log('gate', queryData, channelInfo);
568
- const _channelInfo = Object.assign({}, channelInfo);
569
-
570
- await new Promise((resolve, reject) => {
571
- this.request('gate.gateHandler.queryEntry', queryData, data => {
572
- try {
573
- this.socket.close();
574
- defaultApi.writeLog('channel_log :gate socket close......');
575
- } catch (error) {
576
- //
577
- }
578
- this.socket = null;
579
-
580
- if (data.code === 500) {
581
- defaultApi.writeLog(`channel_log : ${data.code} request-gateServerFailed......`);
582
- reject('gateServerFailed');
583
- }
584
-
585
- _channelInfo.host = data.host;
586
- _channelInfo.port = data.port;
587
- defaultApi.writeLog(`channel_log : ${data.code} request-gateServerSuccess ......`);
588
- try {
589
- dataReport.pomeloInitGate({gateRes:data});
590
- } catch(e) {
591
- console.log('pomeloInitGate_error',e);
592
- }
593
- resolve('gateServerSuccess');
594
- });
595
- });
596
- return this.connectChatServer(_channelInfo);
597
- }
598
- // 重连chat服务器
599
- reconnectChatServer(enterData) {
600
- this.request('connector.entryHandler.enter', enterData, data => {
601
- if (data.code === 500) {
602
- this.reconnectChatServer(enterData);
603
- return;
604
- }
605
- resolve(data);
606
- });
607
- }
608
- // 连接chat服务器
609
- async connectChatServer(channelInfo) {
610
- defaultApi.writeLog('channel_log : connectChatServer,the third step to join pomelo ......');
611
- await new Promise((resolve, reject) => {
612
- this.initPomelo({
613
- serverType: 'chat',
614
- host: channelInfo.host,
615
- port: channelInfo.port,
616
- log: true
617
- }, () => {
618
- resolve(true);
619
- });
620
- });
621
- const enterData = {
622
- uid: channelInfo.userId,
623
- rid: channelInfo.roomId,
624
- rtype: 4,
625
- username: channelInfo.userId,
626
- uname: channelInfo.userName,
627
- // ulevel: userInfo.level, //用户等级x
628
- role: channelInfo.role,
629
- classid: channelInfo.roomId,
630
- protocolVersion: '1.0',
631
- uniqId: channelInfo.guid
632
- };
633
-
634
- return new Promise(async (resolve, reject) => {
635
- this.request(
636
- 'connector.entryHandler.enter',
637
- enterData,
638
- async data => {
639
- if (data.code === 500) {
640
- reject(data);
641
- defaultApi.writeLog(`channel_log : ${data.code} request-chatServerFailed......`);
642
- return;
643
- }
644
- this.dealConnectSuccess();
645
- try {
646
- dataReport.pomeloInitChat({chatRes:data});
647
- } catch(e) {
648
- console.log('pomeloInitChat_error',e);
649
- }
650
- resolve(data);
651
- defaultApi.writeLog(`channel_log : ${data.code} request-chatServerSuccess......`);
652
- console.log('我是chat', data);
653
- }
654
- );
655
- });
656
- }
657
- // 处理连接成功
658
- async dealConnectSuccess() {
659
- // 获取历史列表
660
- if (this.lastReceiveMsgUuid) {
661
- try {
662
- this.isGettingCacheMsgList = true;
663
- console.log('msgRecoverStream--start');
664
- defaultApi.writeLog('msgRecoverStream--start');
665
- const res = JSON.parse(util.unzip(await this.msgRecoverStream()));
666
- console.log('msgRecoverStream--end', res);
667
- defaultApi.writeLog('msgRecoverStream--end');
668
- if (res.code === 200) {
669
- const recoverMsgList = res.result.cacheList;
670
- recoverMsgList.forEach(msg => {
671
- const _msg = JSON.parse(msg);
672
- this.dealOnServerMsg(_msg, _msg.from);
673
- });
674
- this.isGettingCacheMsgList = false;
675
- }
676
- } catch (error) {
677
-
678
- }
679
- }
680
- if (this.hasConnected) {
681
- // 处理公共重进逻辑
682
- CHANNEL.reJoin();
683
- }
684
- this.hasConnected = true;
685
- clearInterval(this.reconnectTimer);
686
- this.reconnectTimer = null;
687
- this.isReconnectting = false;
688
- this.isConnected = true;
689
- }
690
- // 消息恢复
691
- msgRecoverStream() {
692
- return new Promise((resolve, reject) => {
693
- const { userId, roomId } = this.indexChannelInfo;
694
- this.request(
695
- 'recover.recoverHandler.msgRecoverStream',
696
- {
697
- stuId: userId,
698
- rid: roomId,
699
- uuid: this.lastReceiveMsgUuid
700
- },
701
- data => {
702
- if (data.code === 500) {
703
- reject(data);
704
- return;
705
- }
706
- resolve(data);
707
- }
708
- );
709
- });
710
- }
711
- // 重连
712
- reconnect() {
713
- console.log('pomelo reconnect...');
714
- defaultApi.writeLog('pomelo reconnect...');
715
- if (this.isReconnectting) {
716
- return;
717
- }
718
- if (this.socket) {
719
- // 创建实例前断开
720
- this.disconnect(true);
721
- this.socket = null;
722
- }
723
- this.isReconnectting = true;
724
- if (!this.isConnected && this.isInRoom) {
725
- this.connectGateServer(this.indexChannelInfo);
726
- }
727
- this.reconnectTimer = setInterval(() => {
728
- if (!this.isConnected && this.isInRoom) {
729
- this.connectGateServer(this.indexChannelInfo);
730
- }
731
- }, reconnectInterval);
732
- }
733
- // 处理onserver消息
734
- dealOnServerMsg(onServerMsg, from) {
735
- if (from === 'sdkset') {
736
- this.callback(onServerMsg);
737
- } else if (from !== this.indexChannelInfo.userId) {
738
- if (this.latestQueueObj.isRepeat(onServerMsg.uuid)) {
739
- return;
740
- }
741
- this.latestQueueObj.insert(onServerMsg.uuid, Date.now());
742
- if (!this.isGettingCacheMsgList) {
743
- this.lastReceiveMsgUuid = onServerMsg.uuid;
744
- }
745
- this.callback(onServerMsg);
746
- }
747
- }
748
- }
749
- export default new PomeloClient();
1
+ import Protocol from 'pomelo-protocol';
2
+ import Protobuf from 'pomelo-protobuf';
3
+ import LatestQueue from './latestQueue.js';
4
+ import util from './util';
5
+ import CHANNEL from '../index';
6
+ import defaultApi from '../../default/extend';
7
+ import dataReport from '../../network/dataReport';
8
+
9
+ var _protocol = Protocol;
10
+ var _protobuf = Protobuf;
11
+ var _package = Protocol.Package;
12
+ var _message = Protocol.Message;
13
+ var _JS_WS_CLIENT_TYPE = 'js-websocket';
14
+ var _JS_WS_CLIENT_VERSION = '1.0.0';
15
+ // 重连间隔时间
16
+ const reconnectInterval = 10 * 1000;
17
+
18
+
19
+ class PomeloClient {
20
+ constructor() {
21
+ this.handshakeBuffer = {
22
+ sys: {
23
+ type: _JS_WS_CLIENT_TYPE,
24
+ version: _JS_WS_CLIENT_VERSION
25
+ },
26
+ user: {}
27
+ };
28
+ this.pomeloData = {};
29
+ this.heartbeatInterval = 5000;
30
+ this.heartbeatTimeout = this.heartbeatInterval * 2;
31
+ this.nextHeartbeatTimeout = 0;
32
+ this.heartbeatId = null;
33
+ this.heartbeatTimeoutId = null;
34
+ this.handshakeCallback = null;
35
+ this.socket = null;
36
+ this.reqId = 0;
37
+ this.callBacks = {};
38
+ this.handlers = {};
39
+ this.routeMap = {};
40
+ this.initCallback = null;
41
+ //自定义
42
+ this.pomeloConfig = {};
43
+ // 初始化参数
44
+ this.indexChannelInfo = {};
45
+ // 最后一条接收消息的uuid,用于消息恢复
46
+ this.lastReceiveMsgUuid = '';
47
+ // 是否正在获取缓存消息列表
48
+ this.isGettingCacheMsgList = false;
49
+ // 重连定时器
50
+ this.reconnectTimer = null;
51
+ // 是否在重连
52
+ this.isReconnectting = false;
53
+ // 是否连接成功
54
+ this.isConnected = false;
55
+ //是否在教室
56
+ this.isInRoom = false;
57
+ // 是否链接成功过
58
+ this.hasConnected = false;
59
+
60
+ this.latestQueueObj = new LatestQueue();
61
+ this.deleteQueueTimer = setInterval(() => {
62
+ this.latestQueueObj.delete.call(
63
+ this.latestQueueObj,
64
+ 5000 * 4,
65
+ 1000
66
+ );
67
+ }, 1000);
68
+
69
+ this.failTimes = 0;
70
+ this.retryTimesWhenHeartBeatFailed = 100;
71
+
72
+ this.EventType = {
73
+ SOCKET_IO_ERROR: 'SOCKET_IO_ERROR'
74
+ };
75
+ }
76
+
77
+ //初始化pomelo
78
+ initPomelo(pomeloConfig, callBack) {
79
+ this.pomeloConfig = pomeloConfig;
80
+ let port = pomeloConfig.port ? `:${pomeloConfig.port}` : '';
81
+ var url = `wss://${pomeloConfig.host}${port}`;
82
+
83
+ this.handshakeBuffer.user = pomeloConfig.user;
84
+ this.initCallback = callBack;
85
+ // this.handshakeCallback = pomeloConfig.handshakeCallback;
86
+ defaultApi.writeLog(`channel_log : ${url} ${JSON.stringify(pomeloConfig)} initPomelo ......`);
87
+ //开始连接websocket
88
+ this.initWebSocket(url, pomeloConfig.serverType);
89
+ }
90
+
91
+ joinRoom(pomeloConfig, callBack) {
92
+ this.callback = callBack;
93
+ this.isInRoom = true;
94
+ pomeloConfig.port = '443';
95
+ this.indexChannelInfo = pomeloConfig;
96
+ defaultApi.writeLog(`channel_log :${JSON.stringify(pomeloConfig)} the first step to join pomelo ......`);
97
+ try {
98
+ dataReport.pomeloJoinRoom({pomeloConfig});
99
+ } catch(e) {
100
+ console.log('pomeloJoinRoom_error',e);
101
+ }
102
+ return this.connectGateServer(pomeloConfig);
103
+ }
104
+
105
+ initWebSocket(url, serverType) {
106
+ var _this = this;
107
+ defaultApi.writeLog(`channel_log : ${url} ${serverType} socket init......`);
108
+ try {
109
+ if (this.socket) {
110
+ defaultApi.writeLog('channel_log : socket is closed......');
111
+ this.socket.close();
112
+ }
113
+ } catch (e) {
114
+ console.warn('pomelo socket close error', e);
115
+ defaultApi.writeLog('pomelo socket close error');
116
+ }
117
+
118
+ //initSocket
119
+ this.socket = new WebSocket(url);
120
+ try {
121
+ dataReport.pomeloInitWebSocket({url});
122
+ } catch(e) {
123
+ console.log('pomeloInitWebSocket_error',e);
124
+ }
125
+ defaultApi.writeLog('channel_log : new WebSocket......');
126
+ this.socket.binaryType = 'arraybuffer';
127
+
128
+ this.socket.onopen = evt => {
129
+ _this.onSocketOpen(evt);
130
+ defaultApi.writeLog(`channel_log : ${JSON.stringify(evt)} socket is onopen......`);
131
+ };
132
+
133
+ this.socket.onmessage = evt => {
134
+ _this.onSocketMessage(evt);
135
+ };
136
+
137
+ this.socket.onerror = evt => {
138
+ // new update start
139
+ this.socket.onerror = null;
140
+ this.socket.onclose = null;
141
+ // new update end
142
+ _this.onSocketError(evt);
143
+ defaultApi.writeLog(`channel_log : ${JSON.stringify(evt)} socket is onerror......`);
144
+ // 重连
145
+ this.reconnect();
146
+ };
147
+
148
+ this.socket.onclose = evt => {
149
+ // new update start
150
+ this.socket.onerror = null;
151
+ this.socket.onclose = null;
152
+ // new update end
153
+
154
+ defaultApi.writeLog(`channel_log : ${JSON.stringify(evt)} socket is onclose......`);
155
+ if (serverType == 'chat') {
156
+ // this.emit(SocketEventType.SOCKET_CLOSE, evt);
157
+ console.log('[webSocket-state]:onClose---ErrorInfo: %j', evt);
158
+ defaultApi.writeLog('[webSocket-state]:onClose---ErrorInfo: %j',evt);
159
+ // 重连
160
+ this.reconnect();
161
+
162
+ if (this.heartbeatId) {
163
+ clearTimeout(this.heartbeatId);
164
+ this.heartbeatId = null;
165
+ }
166
+ if (this.heartbeatTimeoutId) {
167
+ clearTimeout(this.heartbeatTimeoutId);
168
+ this.heartbeatTimeoutId = null;
169
+ }
170
+ }
171
+ };
172
+ console.log(`===start-init-websocket${url}===`);
173
+ defaultApi.writeLog(`===start-init-websocket${url}===`);
174
+ }
175
+ //onSocketOpen
176
+ onSocketOpen(evt) {
177
+ if (this.socket.readyState == 1) {
178
+ var obj = _package.encode(
179
+ _package.TYPE_HANDSHAKE,
180
+ _protocol.strencode(JSON.stringify(this.handshakeBuffer))
181
+ );
182
+ this.send(obj);
183
+ }
184
+ }
185
+
186
+ //request
187
+ request(route, msg, cb) {
188
+ msg = msg || {};
189
+ route = route || msg.route;
190
+ if (!route) {
191
+ console.log('fail to send request without route.');
192
+ defaultApi.writeLog('fail to send request without route.');
193
+ return;
194
+ }
195
+ this.reqId++;
196
+ this.sendMessage(this.reqId, route, msg);
197
+ this.callBacks[this.reqId] = cb;
198
+ this.routeMap[this.reqId] = route;
199
+ }
200
+
201
+ notify(route, msg) {
202
+ msg = msg || {};
203
+ this.sendMessage(0, route, msg);
204
+ }
205
+
206
+ //sendMessage
207
+ sendMessage(reqId, route, msg) {
208
+ var type = reqId ? _message.TYPE_REQUEST : _message.TYPE_NOTIFY;
209
+ //compress message by protobuf
210
+ var protos = this.pomeloData.protos
211
+ ? this.pomeloData.protos.client
212
+ : {};
213
+ if (protos[route]) {
214
+ msg = _protobuf.encode(route, msg);
215
+ } else {
216
+ msg = _protocol.strencode(JSON.stringify(msg));
217
+ }
218
+
219
+ var compressRoute = 0;
220
+ msg = _message.encode(reqId, type, compressRoute, route, msg);
221
+ var packet = _package.encode(_package.TYPE_DATA, msg);
222
+ this.send(packet);
223
+ }
224
+
225
+ //onSocketMessage
226
+ onSocketMessage(evt) {
227
+ var msgData = _package.decode(evt.data);
228
+ switch (msgData.type) {
229
+ case _package.TYPE_HANDSHAKE:
230
+ this.handshake(msgData.body);
231
+ break;
232
+ case _package.TYPE_HEARTBEAT:
233
+ this.heartbeat(msgData.body);
234
+ break;
235
+ case _package.TYPE_DATA:
236
+ // defaultApi.writeLog(`channel_log : ${JSON.stringify(msgData)} _package TYPE_DATA ......`);
237
+ var msg = _message.decode(msgData.body);
238
+
239
+ if (msg.id > 0) {
240
+ msg.route = this.routeMap[msg.id];
241
+ delete this.routeMap[msg.id];
242
+ if (!msg.route) {
243
+ return;
244
+ }
245
+ }
246
+ msg.body = this.deCompose(msg);
247
+ this.processMessage(msg);
248
+ break;
249
+ case _package.TYPE_KICK:
250
+ defaultApi.writeLog('channel_log : _package TYPE_KICK ......');
251
+ // this.emit(SocketEventType.POMELO_MESSAGE_KICK);
252
+ break;
253
+ }
254
+ if (this.heartbeatTimeout) {
255
+ this.nextHeartbeatTimeout = Date.now() + this.heartbeatTimeout;
256
+ }
257
+ }
258
+ //onSocketError
259
+ onSocketError(evt) {
260
+ // this.emit(SocketEventType.SOCKET_IO_ERROR, evt);
261
+ console.log('[webSocket-state]:onError---ErrorInfo: %j', evt);
262
+ defaultApi.writeLog('[webSocket-state]:onError---ErrorInfo: %j', evt);
263
+ }
264
+ //onSocketClose
265
+ onSocketClose(evt) {
266
+ // this.emit(SocketEventType.SOCKET_CLOSE, evt);
267
+ console.log('[webSocket-state]:onClose---ErrorInfo: %j', evt);
268
+ defaultApi.writeLog('[webSocket-state]:onClose---ErrorInfo: %j', evt);
269
+ }
270
+ //handshake
271
+ handshake(data) {
272
+ var _this = this;
273
+ data = JSON.parse(_protocol.strdecode(data));
274
+ console.log(`[websocket-handshake-code:${data.code}]`);
275
+ defaultApi.writeLog(`[websocket-handshake-code:${data.code}]`);
276
+ // heartBeatConfig
277
+ if (data.sys && data.sys.heartbeat) {
278
+ this.heartbeatInterval = data.sys.heartbeat * 1000; // heartbeat interval
279
+ this.heartbeatTimeout = this.heartbeatInterval * 2; // max heartbeat timeout
280
+ } else {
281
+ this.heartbeatInterval = 0;
282
+ this.heartbeatTimeout = 0;
283
+ }
284
+
285
+ if (data.sys && data.sys['minHeartbeatInterval']) {
286
+ this.minHeartbeatInterval = data.sys['minHeartbeatInterval'] * 1000; // heartbeat interval
287
+ } else {
288
+ this.minHeartbeatInterval = 3000;
289
+ }
290
+
291
+ if (data.sys && data.sys['retryTimesWhenHeartBeatFailed']) {
292
+ this.retryTimesWhenHeartBeatFailed =
293
+ data.sys['retryTimesWhenHeartBeatFailed'];
294
+ }
295
+
296
+ this.initPomeloData(data);
297
+ // handshake-complete
298
+ this.send(_package.encode(_package.TYPE_HANDSHAKE_ACK));
299
+ if (this.initCallback) {
300
+ this.initCallback(this.socket);
301
+ this.initCallback = null;
302
+ }
303
+ }
304
+ //heartbeat
305
+ async heartbeat(data) {
306
+ var _this = this;
307
+ console.log('[websocket-heartbeat-state]:receive heartbeat...');
308
+ defaultApi.writeLog('[websocket-heartbeat-state]:receive heartbeat...');
309
+ var obj = _package.encode(_package.TYPE_HEARTBEAT);
310
+
311
+ if (this.failTimes) {
312
+ this.failTimes = 0;
313
+ console.warn('重新连上了');
314
+ defaultApi.writeLog('重新连上了');
315
+ }
316
+
317
+ if (this.heartbeatTimeoutId) {
318
+ clearTimeout(this.heartbeatTimeoutId);
319
+ this.heartbeatTimeoutId = null;
320
+ }
321
+
322
+ if (this.heartbeatId) {
323
+ // already in a heartbeat interval
324
+ return;
325
+ }
326
+ this.heartbeatId = setTimeout(() => {
327
+ this.heartbeatId = null;
328
+ this.send(obj);
329
+ console.log('[pomeloclient.heartbeat]:send heartbeat...');
330
+ defaultApi.writeLog('[pomeloclient.heartbeat]:send heartbeat...');
331
+ this.nextHeartbeatTimeout = Date.now() + this.heartbeatTimeout;
332
+ this.heartbeatTimeoutId = setTimeout(() => {
333
+ this.heartbeatTimeoutCb(this);
334
+ }, this.minHeartbeatInterval);
335
+ }, this.heartbeatInterval);
336
+ }
337
+ //heartbeatTimeoutCb
338
+ heartbeatTimeoutCb(that) {
339
+ var self = this;
340
+ console.log('heartbeatTimeoutCb log !!!');
341
+ defaultApi.writeLog('heartbeatTimeoutCb log !!!');
342
+ if (this.failTimes < this.retryTimesWhenHeartBeatFailed) {
343
+ var obj = _package.encode(_package.TYPE_HEARTBEAT);
344
+ self.send(obj);
345
+ this.failTimes += 1;
346
+ console.warn(`心跳重试第${this.failTimes}次`);
347
+ defaultApi.writeLog(`心跳重试第${this.failTimes}次`);
348
+ self.heartbeatTimeoutId = setTimeout(
349
+ this.heartbeatTimeoutCb.bind(self),
350
+ this.minHeartbeatInterval
351
+ );
352
+ } else {
353
+ // update start
354
+ // 超时前先断开监听事件
355
+ self.socket.onmessage = null;
356
+ self.socket.onerror = null;
357
+ self.socket.onclose = null;
358
+ // update end
359
+
360
+ console.error('server heartbeat timeout');
361
+ defaultApi.writeLog('server heartbeat timeout');
362
+ // 重连
363
+ this.reconnect();
364
+ // update start
365
+ // this.disconnect(true);
366
+ // update end
367
+ }
368
+ }
369
+ //processMessage
370
+ processMessage(msg) {
371
+ var _this = this;
372
+ // eslint-disable-next-line no-extra-boolean-cast
373
+ if (!!msg.body.msgId) {
374
+ var replyRoute = 'connector.' + msg.route + '.ack';
375
+ var replyMsg = {
376
+ msgId: msg.body.msgId,
377
+ ack: 1
378
+ };
379
+
380
+ this.notify(replyRoute, replyMsg);
381
+ }
382
+ if (!msg || !msg.id) {
383
+ switch (msg.route) {
384
+ case 'onChat':
385
+ break;
386
+ case 'onServer':
387
+ try {
388
+ const onServerMsg = JSON.parse(msg.body.msg);
389
+ this.dealOnServerMsg(onServerMsg, msg.body.from);
390
+ } catch (error) {
391
+ }
392
+ break;
393
+ case 'onAdd':
394
+ break;
395
+ case 'onLeave':
396
+ break;
397
+ case 'onNotice':
398
+ break;
399
+ case 'onKick':
400
+ this.disconnect(true);
401
+ break;
402
+ default:
403
+ }
404
+
405
+ return;
406
+ }
407
+ var cb = this.callBacks[msg.id];
408
+ delete this.callBacks[msg.id];
409
+ if (typeof cb !== 'function') {
410
+ return;
411
+ }
412
+ cb(msg.body);
413
+ return;
414
+ }
415
+ //deCompose
416
+ deCompose(msg) {
417
+ var protos = this.pomeloData.protos
418
+ ? this.pomeloData.protos.server
419
+ : {};
420
+ var abbrs = this.pomeloData.abbrs;
421
+ var route = msg.route;
422
+ try {
423
+ //Decompose route from dict
424
+ if (msg.compressRoute) {
425
+ if (!abbrs[route]) {
426
+ console.error('illegal msg!');
427
+ defaultApi.writeLog('illegal msg!');
428
+ return {};
429
+ }
430
+ route = msg.route = abbrs[route];
431
+ }
432
+ if (protos[route]) {
433
+ return _protobuf.decode(route, msg.body);
434
+ }
435
+ return JSON.parse(_protocol.strdecode(msg.body));
436
+ } catch (ex) {
437
+ console.error('route, body = ' + route + ', ' + msg.body);
438
+ }
439
+ return msg;
440
+ }
441
+ //handshakeInit
442
+ initPomeloData(data) {
443
+ if (!data || !data.sys) {
444
+ return;
445
+ }
446
+ this.pomeloData = this.pomeloData || {};
447
+ var dict = data.sys.dict;
448
+ var protos = data.sys.protos;
449
+ //Init compress dict
450
+ if (dict) {
451
+ this.pomeloData.dict = dict;
452
+ this.pomeloData.abbrs = {};
453
+ for (var route in dict) {
454
+ this.pomeloData.abbrs[dict[route]] = route;
455
+ }
456
+ }
457
+ //Init protobuf protos
458
+ if (protos) {
459
+ this.pomeloData.protos = {
460
+ server: protos.server || {},
461
+ client: protos.client || {}
462
+ };
463
+ if (_protobuf) {
464
+ _protobuf.init({
465
+ encoderProtos: protos.client,
466
+ decoderProtos: protos.server
467
+ });
468
+ }
469
+ }
470
+ }
471
+ //disconnect
472
+ disconnect(isSelf) {
473
+ if (this.socket) {
474
+ this.socket.onmessage = null;
475
+ this.socket.onerror = null;
476
+ this.socket.onclose = null;
477
+ this.isGettingCacheMsgList = false;
478
+ this.isConnected = false;
479
+ if (!isSelf) {
480
+ this.hasConnected = false;
481
+ this.isInRoom = false;
482
+ if (this.reconnectTimer) {
483
+ clearInterval(this.reconnectTimer);
484
+ this.reconnectTimer = null;
485
+ }
486
+ }
487
+
488
+ if (this.socket.disconnect) {
489
+ this.socket.disconnect();
490
+ }
491
+ if (this.socket.close) {
492
+ this.socket.close();
493
+ }
494
+ console.log('[webSocket-disconnect]');
495
+ defaultApi.writeLog('[webSocket-disconnect]');
496
+ }
497
+ if (this.heartbeatId) {
498
+ clearTimeout(this.heartbeatId);
499
+ this.heartbeatId = null;
500
+ }
501
+ if (this.heartbeatTimeoutId) {
502
+ clearTimeout(this.heartbeatTimeoutId);
503
+ this.heartbeatTimeoutId = null;
504
+ }
505
+ if (this.deleteQueueTimer) {
506
+ clearInterval(this.deleteQueueTimer);
507
+ this.deleteQueueTimer = null;
508
+ }
509
+ }
510
+ //send
511
+ send(packet) {
512
+ if (this.socket) {
513
+ if (this.socket.readyState == 2 || this.socket.readyState == 3) {
514
+ this.disconnect(true);
515
+ return;
516
+ }
517
+ this.socket.send(packet.buffer || packet, {
518
+ binary: true,
519
+ mask: true
520
+ });
521
+ }
522
+ }
523
+ //发送消息
524
+ sendChannelMessage(msgData, target = '*') {
525
+ return new Promise((resolve, reject) => {
526
+ this.request(
527
+ 'chat.chatHandler.send',
528
+ {
529
+ // rid: this.indexChannelInfo.channelID,
530
+ content: JSON.stringify(msgData),
531
+ from: this.indexChannelInfo.userID,
532
+ target: target || '*',
533
+ route: 'onServer'
534
+ },
535
+ data => {
536
+ if (data.error) {
537
+ reject({code: -1});
538
+ }
539
+ resolve({code: 200});
540
+ }
541
+ );
542
+ });
543
+ }
544
+ //连接gate服务器,获取chat连接地址
545
+ async connectGateServer(channelInfo) {
546
+ await new Promise((resolve, reject) => {
547
+ this.initPomelo({
548
+ serverType: 'gate',
549
+ host: channelInfo.host,
550
+ port: channelInfo.port,
551
+ log: true
552
+ }, () => {
553
+ resolve(true);
554
+ });
555
+ });
556
+ defaultApi.writeLog('channel_log : connectGateServer,the second step to join pomelo ......');
557
+
558
+ const queryData = {
559
+ uid: channelInfo.userId,
560
+ rtype: 4,
561
+ utype: 2,
562
+ retrytime: new Date().getTime(),
563
+ protocolVersion: '1.0',
564
+ // uniqId: channelInfo.guid
565
+ };
566
+
567
+ console.log('gate', queryData, channelInfo);
568
+ const _channelInfo = Object.assign({}, channelInfo);
569
+
570
+ await new Promise((resolve, reject) => {
571
+ this.request('gate.gateHandler.queryEntry', queryData, data => {
572
+ try {
573
+ this.socket.close();
574
+ defaultApi.writeLog('channel_log :gate socket close......');
575
+ } catch (error) {
576
+ //
577
+ }
578
+ this.socket = null;
579
+
580
+ if (data.code === 500) {
581
+ defaultApi.writeLog(`channel_log : ${data.code} request-gateServerFailed......`);
582
+ reject('gateServerFailed');
583
+ }
584
+
585
+ _channelInfo.host = data.host;
586
+ _channelInfo.port = data.port;
587
+ defaultApi.writeLog(`channel_log : ${data.code} request-gateServerSuccess ......`);
588
+ try {
589
+ dataReport.pomeloInitGate({gateRes:data});
590
+ } catch(e) {
591
+ console.log('pomeloInitGate_error',e);
592
+ }
593
+ resolve('gateServerSuccess');
594
+ });
595
+ });
596
+ return this.connectChatServer(_channelInfo);
597
+ }
598
+ // 重连chat服务器
599
+ reconnectChatServer(enterData) {
600
+ this.request('connector.entryHandler.enter', enterData, data => {
601
+ if (data.code === 500) {
602
+ this.reconnectChatServer(enterData);
603
+ return;
604
+ }
605
+ resolve(data);
606
+ });
607
+ }
608
+ // 连接chat服务器
609
+ async connectChatServer(channelInfo) {
610
+ defaultApi.writeLog('channel_log : connectChatServer,the third step to join pomelo ......');
611
+ await new Promise((resolve, reject) => {
612
+ this.initPomelo({
613
+ serverType: 'chat',
614
+ host: channelInfo.host,
615
+ port: channelInfo.port,
616
+ log: true
617
+ }, () => {
618
+ resolve(true);
619
+ });
620
+ });
621
+ const enterData = {
622
+ uid: channelInfo.userId,
623
+ rid: channelInfo.roomId,
624
+ rtype: 4,
625
+ username: channelInfo.userId,
626
+ uname: channelInfo.userName,
627
+ // ulevel: userInfo.level, //用户等级x
628
+ role: channelInfo.role,
629
+ classid: channelInfo.roomId,
630
+ protocolVersion: '1.0',
631
+ uniqId: channelInfo.guid
632
+ };
633
+
634
+ return new Promise(async (resolve, reject) => {
635
+ this.request(
636
+ 'connector.entryHandler.enter',
637
+ enterData,
638
+ async data => {
639
+ if (data.code === 500) {
640
+ reject(data);
641
+ defaultApi.writeLog(`channel_log : ${data.code} request-chatServerFailed......`);
642
+ return;
643
+ }
644
+ this.dealConnectSuccess();
645
+ try {
646
+ dataReport.pomeloInitChat({chatRes:data});
647
+ } catch(e) {
648
+ console.log('pomeloInitChat_error',e);
649
+ }
650
+ resolve(data);
651
+ defaultApi.writeLog(`channel_log : ${data.code} request-chatServerSuccess......`);
652
+ console.log('我是chat', data);
653
+ }
654
+ );
655
+ });
656
+ }
657
+ // 处理连接成功
658
+ async dealConnectSuccess() {
659
+ // 获取历史列表
660
+ if (this.lastReceiveMsgUuid) {
661
+ try {
662
+ this.isGettingCacheMsgList = true;
663
+ console.log('msgRecoverStream--start');
664
+ defaultApi.writeLog('msgRecoverStream--start');
665
+ const res = JSON.parse(util.unzip(await this.msgRecoverStream()));
666
+ console.log('msgRecoverStream--end', res);
667
+ defaultApi.writeLog('msgRecoverStream--end');
668
+ if (res.code === 200) {
669
+ const recoverMsgList = res.result.cacheList;
670
+ recoverMsgList.forEach(msg => {
671
+ const _msg = JSON.parse(msg);
672
+ this.dealOnServerMsg(_msg, _msg.from);
673
+ });
674
+ this.isGettingCacheMsgList = false;
675
+ }
676
+ } catch (error) {
677
+
678
+ }
679
+ }
680
+ if (this.hasConnected) {
681
+ // 处理公共重进逻辑
682
+ CHANNEL.reJoin();
683
+ }
684
+ this.hasConnected = true;
685
+ clearInterval(this.reconnectTimer);
686
+ this.reconnectTimer = null;
687
+ this.isReconnectting = false;
688
+ this.isConnected = true;
689
+ }
690
+ // 消息恢复
691
+ msgRecoverStream() {
692
+ return new Promise((resolve, reject) => {
693
+ const { userId, roomId } = this.indexChannelInfo;
694
+ this.request(
695
+ 'recover.recoverHandler.msgRecoverStream',
696
+ {
697
+ stuId: userId,
698
+ rid: roomId,
699
+ uuid: this.lastReceiveMsgUuid
700
+ },
701
+ data => {
702
+ if (data.code === 500) {
703
+ reject(data);
704
+ return;
705
+ }
706
+ resolve(data);
707
+ }
708
+ );
709
+ });
710
+ }
711
+ // 重连
712
+ reconnect() {
713
+ console.log('pomelo reconnect...');
714
+ defaultApi.writeLog('pomelo reconnect...');
715
+ if (this.isReconnectting) {
716
+ return;
717
+ }
718
+ if (this.socket) {
719
+ // 创建实例前断开
720
+ this.disconnect(true);
721
+ this.socket = null;
722
+ }
723
+ this.isReconnectting = true;
724
+ if (!this.isConnected && this.isInRoom) {
725
+ this.connectGateServer(this.indexChannelInfo);
726
+ }
727
+ this.reconnectTimer = setInterval(() => {
728
+ if (!this.isConnected && this.isInRoom) {
729
+ this.connectGateServer(this.indexChannelInfo);
730
+ }
731
+ }, reconnectInterval);
732
+ }
733
+ // 处理onserver消息
734
+ dealOnServerMsg(onServerMsg, from) {
735
+ if (from === 'sdkset') {
736
+ this.callback(onServerMsg);
737
+ } else if (from !== this.indexChannelInfo.userId) {
738
+ if (this.latestQueueObj.isRepeat(onServerMsg.uuid)) {
739
+ return;
740
+ }
741
+ this.latestQueueObj.insert(onServerMsg.uuid, Date.now());
742
+ if (!this.isGettingCacheMsgList) {
743
+ this.lastReceiveMsgUuid = onServerMsg.uuid;
744
+ }
745
+ this.callback(onServerMsg);
746
+ }
747
+ }
748
+ }
749
+ export default new PomeloClient();