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,1568 +1,1568 @@
1
- import CHANNEL from '../index';
2
- import zbysdk from '../../zby-live-sdk.js';
3
- import ENTRY from './interactWithChannelEntry.js';
4
- import io from 'socket.io-client';
5
- import dataReport from '../../network/dataReport';
6
- import dealReceiveStreamMsg from '../stream-msg';
7
- // import {getApiCloudBaseUrl} from '../../config/config';
8
-
9
- let w = window;
10
- let CONTROL = {
11
- socket: null,
12
- //连接保持相关
13
- enterInit: false, //是否发起过登录,leaveRoom后置为false
14
- enterSuccessed: false, //是否进入房间成功过,leaveRoom或主动disconnect后置为false
15
- isConnect: false, //连接服务器成功的标志
16
- isInRoom: false, //当前是否在房间中,掉线后为false
17
- isReconnect: false, //是否是自动重连,控制“进入教室”的显示
18
- isOffline: false, //是否网络断线
19
- joindelaytimer: null, //连接建立后,延迟发起登录请求
20
- jointimeouttimer: null, //登录超时time
21
- connecttimeouttimer: null,
22
- connecttimeCount: 0, //初次连接时已尝试连接服务器的次数(用于connect超时检查)
23
- connecttimeout: 20000, //连接服务器超时,第一次设置20秒 之后变为30秒
24
- authorizefailedcount: 0, //授权失败的次数
25
-
26
- //设置相关
27
- address: '', //以下为客户端传入的变量
28
- token: '',
29
- code: '', //口令课时的口令,此时token应为空
30
- role: '1', //'1=teacher'/'2=student'/'3=assistant'/'4=parent'
31
- username: '', //显示用户相关信息时使用username
32
- userid: '', //消息后台识别用户使用userid
33
- avatar: '',
34
- conn_origin: '',
35
- language: 0, //0=中文,1=英文
36
- classmode: 1, ////1=1对1模式;2=1对多模式;3=大班课模式;5=互动大班课
37
- playmode: 1, ////1=正常上课;2=回放
38
- roomid: '',
39
- institutionid: '',
40
-
41
- //确保消息发送成功相关的
42
- streamIndex: 0,
43
- normalMsgIndex: 0, //不需要保序的消息的id
44
- checkInterval: 3000, //检查“消息发送超时”的时间间隔(超时时间在检查函数中)
45
- maxAckDelay: 8000, //消息回复的最大时间延迟,超过最大延迟还没收到回复,认为没发送成功
46
- checkSendSucessTimer: null,
47
- sendCheckList: null, //发送确认队列
48
- sendCacheList: null, //发送缓存队列
49
- recvmsgKeys: null, //接收消息的缓存队列
50
- recvmsgTimes: null, //接收消息的缓存队列每条消息对应的时间
51
- cacheReqSend: false, //请求服务器端缓存的命令是否发送了
52
- recvCacheList: null, //断线重连后,请求缓存队列后,保存缓存的消息
53
- recvTmpList: null, //断线重连后,在获取服务器到服务器端的缓存队列前,先缓存收到的消息,不上抛
54
- timedeviation: 0, //本地时间与服务器时间的差值,毫秒:服务器时间-本地时间
55
- orderCheck: null, //保序验证
56
- lastRecvMsgId: null, //保序验证 //测试添加
57
- testrecvcount: null, //保序验证,统计接收消息数 //测试添加
58
- delaycheckList: null, //保序、丢消息、延迟验证 //测试添加
59
- delayList: null, //延迟列表
60
- lastcheckindex: 0, //上一个收到的echo回复的
61
- dealChannelMsg: null, // 业务层传入的消息处理器,作为回调使用
62
- pingPongArr: [],
63
- //public 进入教室
64
- enterRoom: function (dealChannelMsg) {
65
- CONTROL.dealChannelMsg = dealChannelMsg;
66
- if (!this.enterInInitparas()) {
67
- return;
68
- }
69
- ENTRY.recordLogToFile('info', 'enter room info');
70
- //通知宿主,页面开始连接了
71
- if (w.controlObj && w.controlObj.onStartConnect) {
72
- w.controlObj.onStartConnect();
73
- }
74
- this.startEnter();
75
- },
76
-
77
- //public 退出,断开连接
78
- leaveRoom: function () {
79
- CONTROL.otherChannelleaveRoom();
80
-
81
- ENTRY.recordLogToFile('info', 'control: leaveRoom');
82
-
83
- if (!this.enterInit) {
84
- return;
85
- }
86
- CONTROL.enterInit = false;
87
-
88
- this.sendleaveRoomMsg();
89
- if (this.socket) {
90
- this.socket.disconnect();
91
- }
92
-
93
- this.leaveRoomReset();
94
- },
95
-
96
- //其它通道离开房间
97
- otherChannelleaveRoom: function () {
98
- try {
99
- //其他通道
100
- if (ENTRY.channeltype == 0) {
101
- if (w.CHAT) {
102
- w.CHAT.leaveRoom();
103
- }
104
- }
105
- } catch (e) {
106
- ENTRY.recordException(e);
107
- }
108
- },
109
-
110
- //开始登录过程 连接-验证身份-进入教室
111
- startEnter: function () {
112
- CONTROL.enterInit = true;
113
- ENTRY.recordLogToFile('info', 'enter channel room start');
114
- var logmsg = 'control:connect ';
115
- logmsg += this.address;
116
- CONTROL.displayLogMsg(logmsg);
117
- ENTRY.recordLogToFile('info', logmsg);
118
-
119
- //连接
120
- this.socketConnect();
121
-
122
- //超时检查
123
- this.startCheckConnectTimer();
124
- },
125
-
126
- //socket 开始连接
127
- socketConnect: function () {
128
-
129
- //开始连接时,如果存在已有socket,先断开连接
130
- if (CONTROL.socket) {
131
- CONTROL.socket.disconnect();
132
- }
133
- var opt = new Object();
134
- opt.transports = ['websocket'];
135
- ENTRY.recordLogToFile('info', 'channel start connect ' + this.address);
136
- CONTROL.socket = io.connect(this.address, opt);
137
- this.setEventListeners();
138
- },
139
-
140
- //注册监听事件
141
- setEventListeners: function () {
142
- console.log('websocket: 设置监听');
143
- //监听连接成功 01步
144
- this.socket.on('connect', function (o) {
145
- ENTRY.recordLogToFile('info', 'channel connect success');
146
- CONTROL.dealConnectSuccess();
147
- try {
148
- dataReport.joinRoomResult({
149
- code: '0',
150
- // cloud_api_response: JSON.stringify(window.zby_sdk_cloud_data),
151
- cloud_api_response: window.zby_sdk_cloud_data,
152
- cloud_api_url: `${getApiCloudBaseUrl()}/rtccloud/class/init`,
153
- chat_url: window.zby_sdk_cloud_data.chatUrl
154
- });
155
- } catch (e) {};
156
- });
157
-
158
- //授权成功 02步
159
- this.socket.on('authenticated', function () {
160
- console.log('websocket: 授权成功');
161
- CONTROL.displayLogMsg('control:authenticated!');
162
- ENTRY.recordLogToFile('info', 'control:authenticated succeessful');
163
- CONTROL.stopCheckConnectTimer();
164
- CONTROL.joindelaytimer = window.setTimeout(CONTROL.sendJoinInMsg, 100); //延迟100毫秒登录
165
- });
166
-
167
- //授权不成功
168
- this.socket.on('unauthenticated', function () {
169
- ENTRY.recordLogToFile('info', 'control:authenticated failed');
170
- CONTROL.dealAuthorizeFailed();
171
- try {
172
- dataReport.joinRoomResult({
173
- code: '4',
174
- cloud_api_response: window.zby_sdk_cloud_data,
175
- cloud_api_url: `${getApiCloudBaseUrl()}/rtccloud/class/init`,
176
- chat_url: window.zby_sdk_cloud_data.chatUrl
177
- });
178
- } catch (e) {};
179
- });
180
-
181
- //监听连接断开,禁用网卡/主动disconnect,会回调这个
182
- this.socket.on('disconnect', function () {
183
- CONTROL.isOffline = true;
184
- CONTROL.dealDisconnect();
185
-
186
- });
187
- this.socket.on('pong', function (data) {
188
- // console.log(data + ' - pong');
189
- CONTROL.pingPongArr.push(data);
190
- });
191
- this.OnUserDefineMsg();
192
- },
193
-
194
- //发送验证权限消息
195
- sendAuthenMsg: function () {
196
- try {
197
- if (CONTROL.token != '') {
198
- CONTROL.socket.emit('authenticate', {
199
- token: CONTROL.token,
200
- room: CONTROL.roomid,
201
- instid: CONTROL.institutionid,
202
- userid: CONTROL.userid
203
- });
204
- } else if (CONTROL.code != '') {
205
- CONTROL.socket.emit('authenticate', {
206
- code: CONTROL.code,
207
- room: CONTROL.roomid,
208
- instid: CONTROL.institutionid,
209
- userid: CONTROL.userid
210
- });
211
-
212
- var logmsg = 'control sendAuthenMsg:with code:' + CONTROL.code;
213
- ENTRY.recordLogToFile('info', logmsg);
214
- } else {
215
- ENTRY.recordLogToFile('error', 'control auth para wrong');
216
- }
217
- } catch (e) {
218
- ENTRY.recordException(e);
219
- }
220
- },
221
-
222
- //连接授权成功后发送:进入房间消息发送
223
- sendJoinInMsg: function () {
224
- // 销毁延迟登录timer
225
- CONTROL.stopDelayJoinTimer();
226
-
227
- try {
228
- var obj = {};
229
- obj.username = CONTROL.username;
230
- obj.room = CONTROL.roomid;
231
- obj.avatar = CONTROL.avatar;
232
- obj.userid = CONTROL.userid;
233
- obj.role = CONTROL.role;
234
- obj.playmode = CONTROL.playmode;
235
- obj.device = 1; //0 - 默认;1 - PC客户端;2 - PC web;3 - 移动 web;4 - 移动 APP;
236
- obj.instid = CONTROL.institutionid;
237
- obj.conn_origin = CONTROL.conn_origin;
238
- obj.classmode = ENTRY.getClassTypeInDb();
239
- ENTRY.recordLogToFile('info', 'control:emit join_room');
240
- CONTROL.socket.emit('join_room', obj, function (param) {
241
- CONTROL.dealJoinMsgAck(param);
242
- var logmsg = 'control:join_room ack' + JSON.stringify(param);
243
- ENTRY.recordLogToFile('info', logmsg);
244
- });
245
- CONTROL.isOffline = false;
246
-
247
- } catch (e) {
248
- ENTRY.recordException(e);
249
- }
250
-
251
- // 超时后检查进入房间是否成功
252
- CONTROL.startCheckJoinInTimer();
253
- },
254
-
255
- //退出登录消息发送
256
- sendleaveRoomMsg: function () {
257
- if (CONTROL.socket == null) {
258
- return;
259
- }
260
- try {
261
- ENTRY.recordLogToFile('info', 'control:emit leave room');
262
- CONTROL.socket.emit('leave_room', {}, function (param) {});
263
- } catch (e) {
264
- ENTRY.recordException(e);
265
- }
266
- },
267
-
268
- //进入房间是否成功的检查,在进入房间尚未成功时,重新启动进入过程
269
- checkAndReEnter: function () {
270
- CONTROL.stopAllTimeoutTimer();
271
-
272
- // 离开教室 / 进入房间成功后,不用再检查了
273
- // 掉线重连,不走这儿,这儿是尚未连接成功过,或主动disconnect后的重连;掉线后,socket.io库会自动重连,并回调connect
274
- if (!CONTROL.enterInit || CONTROL.enterSuccessed) {
275
- var logmsg = 'control:checkAndReEnter not needed:' + CONTROL.enterInit + ',' + CONTROL.enterSuccessed;
276
- ENTRY.recordLogToFile('info', logmsg);
277
- return;
278
- }
279
- ENTRY.recordLogToFile('info', 'control:checkAndReEnter');
280
-
281
- if (CONTROL.connecttimeCount < ENTRY.enterMaxCount) {
282
- CONTROL.reEnterRoom();
283
- } else {
284
- //上报客户端
285
- if (w.controlObj && w.controlObj.loginFailed) {
286
- w.controlObj.loginFailed();
287
- }
288
- // channel_join 信道连接 进入房间失败
289
- ENTRY.recordLogToFile('info', 'channel reenter failed');
290
- }
291
- },
292
-
293
- //重新连接并进入房间
294
- reEnterRoom: function () {
295
- CONTROL.reenterReset();
296
- if (CONTROL.enterSuccessed) {
297
- CONTROL.isReconnect = true;
298
- }
299
- CONTROL.connecttimeCount++;
300
- CONTROL.startEnter();
301
- },
302
-
303
- //连接超时检查
304
- checkConnectTimeout: function () {
305
- CONTROL.stopCheckConnectTimer();
306
- if (!CONTROL.isConnect) {
307
- ENTRY.recordLogToFile('info', 'control:check connect failed,reenter');
308
- CONTROL.checkAndReEnter();
309
- }
310
- },
311
-
312
- //处理连接成功的事件
313
- dealConnectSuccess: function () {
314
- ENTRY.recordLogToFile('info', 'control:connect success');
315
-
316
- //没有执行过登录操作
317
- if (!this.enterInit) {
318
- ENTRY.recordLogToFile('error', 'control:recve connect,not init yet!');
319
- return;
320
- }
321
-
322
- this.isConnect = true;
323
-
324
- //发送验证
325
- this.sendAuthenMsg(); //回调 authenticated
326
-
327
- //上报客户端
328
- if (w.controlObj && controlObj.connectSuccess) {
329
- controlObj.connectSuccess();
330
- }
331
- },
332
-
333
- //处理断开连接事件
334
- dealDisconnect: function () {
335
- ENTRY.recordLogToFile('info', 'control:channel disconnect');
336
- if (!CONTROL.enterInit) {
337
- ENTRY.recordLogToFile('info', 'control:recve disconnect,already logout');
338
- return;
339
- }
340
-
341
- try {
342
- CONTROL.displayLogMsg('control: disconnect');
343
- CONTROL.isConnect = false;
344
- CONTROL.isInRoom = false;
345
- if (CONTROL.enterSuccessed) {
346
- //自己掉线通知
347
- if (w.controlObj && controlObj.disconnect) {
348
- controlObj.disconnect();
349
- }
350
- CONTROL.dealChannelMsg({
351
- type: 'channel_disconnect',
352
- data: {
353
- message: 'Channel disconnect'
354
- }
355
- });
356
-
357
- }
358
- } catch (e) {}
359
- },
360
-
361
- //处理授权失败
362
- dealAuthorizeFailed: function () {
363
- try {
364
- if (CONTROL.enterSuccessed) {
365
- //进入房间成功过,但掉线重连时,验证授权失败了
366
- ENTRY.recordLogToFile('info', 'control:authenticated failed when reconect');
367
- if (CONTROL.authorizefailedcount < 8) {
368
- ENTRY.recordLogToFile('error', 'control:authenticated failed socketConnect');
369
- CONTROL.socketConnect();
370
- }
371
-
372
- } else {
373
- //尚未进入房间成功,且授权失败了
374
- ENTRY.recordLogToFile('error', 'control:authenticated failed when connect first time');
375
- CONTROL.checkAndReEnter();
376
- }
377
- ++CONTROL.authorizefailedcount;
378
- } catch (e) {
379
- ENTRY.recordException(e);
380
- }
381
- },
382
- //处理登录消息
383
- dealJoinMsgAck: function (msgobj) {
384
- //{'code':0,'message':'join ok'}
385
- if (!msgobj) {
386
- return;
387
- }
388
- if (msgobj.code == 0) {
389
- if (!this.enterSuccessed) {
390
- CONTROL.otherChannelEnter(); //其它通道进入房间,免身份验证
391
- }
392
-
393
- this.stopCheckJoinInTimer();
394
-
395
- if (!this.isInRoom) {
396
- if (this.enterSuccessed) {
397
- CONTROL.dealReconnectSuccess();
398
- this.displayLogMsg('control: reenter room success'); //重新登录成功
399
- ENTRY.recordLogToFile('info', 'reenter room success');
400
- CONTROL.dealChannelMsg({
401
- type: 'channel_reconnect',
402
- data: {
403
- message: 'Channel reconnect'
404
- }
405
- });
406
- //如果之前登入过,且现在没在房间内,代表当次连接为断线重连,重连成功须重新发送音视频 join 消息
407
- CHANNEL.reJoin();
408
- } else {
409
- //请求历史消息
410
- this.getHistoryList();
411
- this.displayLogMsg('control: enter room success'); //已进入房间的话就不要提示了
412
- ENTRY.recordLogToFile('info', 'control: enter room success');
413
- }
414
- }
415
- this.isInRoom = true;
416
- this.enterSuccessed = true; //设置进房间已经成功过了
417
-
418
- if (w.controlObj && w.controlObj.loginResponse) {
419
- w.controlObj.loginResponse();
420
- }
421
-
422
- //测试添加
423
- //this.getOnlineList();
424
-
425
- //在线人数
426
- this.notifyMembernumChanged(msgobj.data);
427
-
428
- CONTROL.timedeviation = msgobj.data.unixtime - (new Date().getTime());
429
- } else {
430
- this.checkAndReEnter();
431
- }
432
- },
433
-
434
- //其它通道进行连接
435
- otherChannelEnter: function () {
436
- try {
437
- if (ENTRY.channeltype == 0) {
438
- if (w.CHAT) {
439
- w.CHAT.enterRoom();
440
- }
441
- }
442
- } catch (e) {
443
- ENTRY.recordException(e);
444
- }
445
- },
446
-
447
- //登录前,初始化参数
448
- enterInInitparas: function () {
449
- try {
450
- var config = ENTRY.getConfigInfo();
451
- var roominfo = ENTRY.getRoomInfo();
452
- if (!config || !roominfo) {
453
- ENTRY.recordLogToFile('info', 'enter room:room info is empty or user info is empty');
454
- return false;
455
- }
456
- this.address = config.address + 'control';
457
-
458
- //兼容一下老的客户端,老的客户端使用的是url编码
459
- // if(config.hasOwnProperty('encodetype') && config.encodetype=='base64'){
460
- // var b64decoder = new w.Base64();
461
- // this.username = b64decoder.decode(config.user.username);
462
- // this.avatar = b64decoder.decode(config.user.avatar);
463
- // ENTRY.recordLogToFile('i','control enterInInitparas:use base64 decode:'+this.username);
464
- // }
465
- // else{
466
- this.username = decodeURIComponent(config.user.username);
467
- this.avatar = decodeURIComponent(config.user.avatar);
468
- ENTRY.recordLogToFile('info', 'control enterInInitparas:use url decode:' + this.username);
469
- // }
470
- this.userid = config.user.userid;
471
-
472
- if (config.user.hasOwnProperty('token')) {
473
- this.token = config.user.token;
474
- }
475
- if (config.user.hasOwnProperty('code')) {
476
- this.code = config.user.code;
477
- }
478
- this.role = config.user.role;
479
- this.language = config.language;
480
- this.roomid = roominfo.roomid;
481
- this.classmode = roominfo.classmode;
482
- this.playmode = roominfo.playmode;
483
- this.institutionid = roominfo.institutionid;
484
- this.conn_origin = roominfo.conn_origin;
485
- if (this.roomid == '' || this.userid == '') {
486
- ENTRY.recordLogToFile('error', 'enter room:roomid is empty or userid is empty');
487
- return false;
488
- }
489
-
490
- this.isReconnect = false; //重连标志,重连一次就算重连了
491
- this.connecttimeCount = 0;
492
- this.initCacheList();
493
- } catch (e) {
494
- ENTRY.recordException(e);
495
- return false;
496
- }
497
-
498
- return true;
499
- },
500
-
501
- //重启进入教室过程前,对某些变量进行重置
502
- reenterReset: function () {
503
- this.isInRoom = false;
504
- this.isConnect = false;
505
-
506
- if (this.userstate == null) {
507
- this.userstate = new Array();
508
- } else {
509
- this.userstate.length = 0;
510
- }
511
- if (this.socket) {
512
- this.socket.disconnect();
513
- }
514
- this.stopAllTimeoutTimer();
515
- },
516
-
517
- leaveRoomReset: function () {
518
- this.reenterReset();
519
-
520
- //停一下timer
521
- this.stopAllTimeoutTimer();
522
-
523
- this.unInitCacheList();
524
-
525
- this.connecttimeCount = 0;
526
- this.enterInit = false;
527
- this.enterSuccessed = false;
528
- this.socket = null;
529
- },
530
-
531
- //启动 连接超时检查
532
- startCheckConnectTimer: function () {
533
- this.connecttimeouttimer = window.setTimeout(CONTROL.checkConnectTimeout, CONTROL.connecttimeout);
534
- CONTROL.connecttimeout = 30000;
535
- },
536
-
537
- //关闭 连接超时检查
538
- stopCheckConnectTimer: function () {
539
- if (this.connecttimeouttimer) {
540
- w.clearTimeout(this.connecttimeouttimer);
541
- this.connecttimeouttimer = null;
542
- }
543
- },
544
-
545
- //关闭 延迟join的timer
546
- stopDelayJoinTimer: function () {
547
- if (CONTROL.joindelaytimer != null) {
548
- window.clearTimeout(CONTROL.joindelaytimer);
549
- CONTROL.joindelaytimer = null;
550
- }
551
- },
552
-
553
- //启动 进入房间超时的检查
554
- startCheckJoinInTimer: function () {
555
- this.jointimeouttimer = window.setTimeout(CONTROL.checkAndReEnter, CONTROL.connecttimeout);
556
- },
557
-
558
- //关闭 进入房间超时的检查
559
- stopCheckJoinInTimer: function () {
560
- if (this.jointimeouttimer) {
561
- w.clearTimeout(this.jointimeouttimer);
562
- this.jointimeouttimer = null;
563
- }
564
- },
565
-
566
- //停止所有计时器
567
- stopAllTimeoutTimer: function () {
568
- this.stopCheckConnectTimer();
569
- this.stopCheckJoinInTimer();
570
- this.stopDelayJoinTimer();
571
- },
572
-
573
- displayLogMsg: function (msg) {
574
- if (w.CHATDIS) {
575
- w.CHATDIS.displayLogMsg(msg);
576
- }
577
- },
578
-
579
- //////////////////////以上为进入房间/离开房间 过程的通用处理/////////////////////////////////////
580
- //发送流控制消息 string string string string
581
- sendStreamMsg: function (subtype, content, targetid, save) {
582
- //subtype : stream / class(save)
583
- var obj = {};
584
- obj.index = this.streamIndex++; //int
585
- obj.uuid = ENTRY.getMsgKey(obj.index); //string
586
- obj.mtype = subtype; //消息子类型
587
- obj.targetid = targetid;
588
- obj.trace_id = `sdk_1.0_${(new Date().getTime()).toString().padStart(16, '123456')}`;
589
- obj.message = content;
590
- obj.save = save;
591
-
592
- if (this.isInRoom) {
593
- this.sendStreamMsgInner(obj);
594
- } else {
595
- this.cachedSendMsg(obj);
596
- }
597
- },
598
-
599
- //发送可以丢失的消息
600
- sendUnimportantStreamMsg: function (subtype, content, targetid, save) {
601
- //subtype : stream / class(save)
602
- if (!this.isInRoom || !this.socket) {
603
- return;
604
- }
605
- var obj = {};
606
- obj.index = this.normalMsgIndex++; //int 不关心
607
- obj.uuid = ENTRY.getMsgKey(obj.index); //string
608
- obj.mtype = 'lowquality'; //消息子类型
609
- obj.targetid = targetid;
610
- obj.message = content;
611
- obj.save = save;
612
- this.socket.emit('stream', obj, function (status) {});
613
- },
614
-
615
- sendStreamMsgInner: function (obj) {
616
- try {
617
- var logmsg = 'send:' + obj.index;
618
- logmsg += ',msg:';
619
- logmsg += obj.message;
620
- logmsg += ',uuid:';
621
- logmsg += obj.uuid;
622
- ENTRY.recordLogToFile('info', logmsg);
623
-
624
- this.addToCheckList(obj);
625
- this.socket.emit('stream', obj, function (status) {
626
- if (status.code == 0) {
627
- CONTROL.setSendSuccess(obj);
628
-
629
- //提示开始上课/结束上课
630
- var curtime = new Date();
631
- var timeseconds = curtime.getTime() + CONTROL.timedeviation;
632
- var timestr = '';
633
- timestr += timeseconds;
634
- obj.unixtime = timestr;
635
- CONTROL.displayClassOperate(obj);
636
- }
637
- var logmsg = 'control:send ack:' + obj.index;
638
- ENTRY.recordLogToFile('info', logmsg);
639
- });
640
- } catch (e) {
641
- ENTRY.recordException(e);
642
- }
643
-
644
- //CONTROL.displayLogMsg(logmsg1);//删掉
645
- },
646
-
647
- //发送普通控制消息 string string string 暂时没有使用此事件
648
- sendCommonMsg: function (subtype, content, targetid) {
649
- //subtype:netstate
650
- var obj = {};
651
- obj.index = ENTRY.getMsgIndex(); //int
652
- obj.mtype = subtype; //消息子类型
653
- obj.targetid = targetid;
654
- obj.message = content;
655
- //obj.save = save;//暂时没有save字段
656
- this.socket.emit('common', obj, function (status) {});
657
- },
658
-
659
- //发送可以丢失的消息
660
- sendLowQualityMsg: function (subtype, content, targetid) {
661
- //subtype : stream / class(save)
662
- if (!this.isInRoom || !this.socket) {
663
- return;
664
- }
665
- var obj = {};
666
- obj.index = this.normalMsgIndex++; //int 不关心
667
- obj.uuid = ENTRY.getMsgKey(obj.index); //string
668
- obj.mtype = subtype; //消息子类型
669
- obj.targetid = targetid;
670
- obj.message = content;
671
- this.socket.emit('netstate', obj, function (status) {});
672
- },
673
-
674
- //获取当前在线列表 老师身份的才有效
675
- getOnlineList: function () {
676
- try {
677
- this.socket.emit('listeners', {}, function (status) {
678
- if (status.code != 0) {
679
- //if(w.onlinemeber && w.onlinemeber.onRecvMemberDataFinished){
680
- // w.onlinemeber.onRecvMemberDataFinished();
681
- //}
682
-
683
- ENTRY.recordLogToFile('error', 'get online list failed!');
684
- }
685
- });
686
- } catch (e) {
687
- ENTRY.recordException(e);
688
- }
689
- },
690
-
691
- //请求stream历史消息
692
- getHistoryList: function () {
693
- try {
694
- ENTRY.recordLogToFile('info', 'emit history_message!');
695
- this.socket.emit('history_message', {}, function (para) {
696
- ENTRY.recordLogToFile('info', 'history_message ret!');
697
- if (para.code == 0) {
698
- try {
699
- //只处理开始上课、结束上课消息
700
- var length = para.data.history_list.length;
701
- for (var i = 0; i < length; ++i) {
702
- var msgobj = para.data.history_list[i];
703
- CONTROL.displayClassOperate(msgobj);
704
- } //end of for
705
-
706
- //通知学生端 最后一条课程状态消息
707
- if (length > 0 && CONTROL.role == '2' && w.controlObj && w.controlObj.onReciveStream) {
708
- for (var j = length - 1; j >= 0; j--) {
709
- var msgobjclass = para.data.history_list[j];
710
- if (msgobjclass.mtype == 'class') {
711
- w.controlObj.onReciveStream(msgobjclass.mtype, msgobjclass.message);
712
- break;
713
- }
714
- }
715
- }
716
-
717
- //通知老师端,开始上课和结束上课有没有
718
- var startclassExist = 'false';
719
- var endclassExist = 'false';
720
- if (w.controlObj && w.controlObj.onKeyMessageSent) {
721
- for (var i = 0; i < length; i++) {
722
- var msgobjclass = para.data.history_list[i];
723
- if (msgobjclass.mtype == 'class') {
724
- var cmdobj = JSON.parse(msgobjclass.message);
725
- if (cmdobj && cmdobj.cmdtype == 'start') {
726
- startclassExist = 'true';
727
- }
728
- if (cmdobj && cmdobj.cmdtype == 'end') {
729
- endclassExist = 'true';
730
- }
731
- }
732
- }
733
- w.controlObj.onKeyMessageSent('startClass', startclassExist);
734
- w.controlObj.onKeyMessageSent('endClass', endclassExist);
735
- } //end of if
736
- } catch (e) {
737
- ENTRY.recordException(e);
738
- }
739
- } //end of if
740
- });
741
- } catch (e) {
742
- ENTRY.recordException(e);
743
- }
744
- },
745
-
746
- //监听消息
747
- OnUserDefineMsg: function (msg) {
748
- //进入教室成功
749
- this.socket.on('join_room', function (obj) {
750
- CONTROL.dealJoinMsg(obj);
751
- });
752
-
753
- //离开教室
754
- this.socket.on('leave_room', function (obj) {
755
- CONTROL.dealleaveRoomMsg(obj);
756
- });
757
-
758
- //监测网络状态
759
- this.socket.on('pong', function (time) {
760
- if (w.controlObj && controlObj.onPong) {
761
- controlObj.onPong('' + time);
762
- }
763
- });
764
-
765
- //接收流控制消息
766
- this.socket.on('stream', function (obj) {
767
- CONTROL.dealStreamMsg(obj, false);
768
- });
769
-
770
- this.socket.on('netstate', function (obj) {
771
- CONTROL.dealNetStateMsg(obj);
772
- });
773
-
774
- this.socket.on('award', function (obj) {
775
- CONTROL.dealAwardMsg(obj); //奖励通知
776
- });
777
-
778
- this.socket.on('streamservicetype', function (obj) {
779
- CONTROL.dealStreamServiceTypeMsg(obj); //切换SDK通知
780
- });
781
-
782
- this.socket.on('force_exit', function (obj) {
783
- //被踢通知
784
- CONTROL.displayLogMsg('force_exit'); //删掉
785
- CONTROL.dealForceExit(obj);
786
- });
787
-
788
- this.socket.on('room_expired', function (obj) {
789
- //房间过期
790
- CONTROL.dealRoomExpired(obj);
791
- });
792
-
793
- //接收监课状态消息
794
- this.socket.on('supervisor', function (obj) {
795
- CONTROL.dealSupervisorMsg(obj);
796
- });
797
-
798
- //收到在线列表消息
799
- this.socket.on('listeners', function (obj) {
800
- if (w.onlinemeber && w.onlinemeber.onRecvOnlinMemberData) {
801
- var objstr = JSON.stringify(obj);
802
- w.onlinemeber.onRecvOnlinMemberData(objstr);
803
- }
804
- });
805
-
806
- //掉线通知
807
- this.socket.on('offline', function (obj) {
808
- CONTROL.dealOfflineMsg(obj);
809
- CONTROL.isOffline = true;
810
- //channel_disconnect 信道离线,退出房间
811
- CONTROL.dealChannelMsg({
812
- type: 'user_disconnect',
813
- data: {
814
- userId: +obj.userid,
815
- userName: obj.username,
816
- role: obj.role
817
- }
818
- });
819
- ENTRY.recordLogToFile('info', `sdk notice user_disconnect role: ${obj.role} userId : ${obj.userid} userName: ${obj.username}`);
820
- ENTRY.recordLogToFile('info', `offline ${JSON.stringify(obj)}`);
821
- });
822
-
823
- //收到异常状态消息
824
- this.socket.on('unusual', function (obj) {
825
- if (obj && w.controlObj && w.controlObj.onRecvUnusualNOtify) {
826
- w.controlObj.onRecvUnusualNOtify(JSON.stringify(obj));
827
- }
828
- });
829
-
830
-
831
- //供参考,实测并不完全符合:客户端socket发起连接时的顺序。当第一次连接时,事件触发顺序为:connecting->connect;
832
- // 当失去连接时,事件触发顺序为:disconnect->reconnecting(可能进行多次)->connecting->reconnect->connect。
833
- this.socket.on('reconnecting', function () {
834
- CONTROL.displayLogMsg('control: reconnecting!');
835
- });
836
-
837
- //并不会回调这个
838
- this.socket.on('connecting', function () {
839
- CONTROL.displayLogMsg('control: connecting!');
840
- });
841
-
842
- //监听连接失败
843
- this.socket.on('connect_failed', function (o) {
844
- CONTROL.displayLogMsg('control:connectfailed');
845
- try {
846
- dataReport.joinRoomResult({
847
- code: '3',
848
- cloud_api_response: window.zby_sdk_cloud_data,
849
- cloud_api_url: `${getApiCloudBaseUrl()}/rtccloud/class/init`,
850
- chat_url: window.zby_sdk_cloud_data.chatUrl
851
- });
852
- } catch (e) {};
853
- });
854
-
855
- //目前没发现,什么情况下会回调这个
856
- this.socket.on('error', function () {
857
- CONTROL.displayLogMsg('control:soceket错误!');
858
- });
859
-
860
- //并不会回调这个:自动重连成功后,会调用connect
861
- this.socket.on('reconnect', function () {
862
- CONTROL.displayLogMsg('control:reconnect!');
863
- });
864
-
865
- //并不会回调这个
866
- this.socket.on('reconnect_failed', function () {
867
- CONTROL.displayLogMsg('control:reconnect_failed!');
868
- });
869
- },
870
-
871
- //处理登录消息
872
- dealJoinMsg: function (msgobj) {
873
- if (w.onlinemeber && w.onlinemeber.onRecvMemberStateChange) {
874
- try {
875
- var objuser = {};
876
- objuser.online = 'login';
877
- objuser.username = msgobj.username;
878
- objuser.userid = msgobj.userid;
879
- objuser.role = ENTRY.translateRoleBack(msgobj.role);
880
- if (msgobj.hasOwnProperty('avatar')) {
881
- objuser.avatar = msgobj.avatar;
882
- }
883
- if (msgobj.hasOwnProperty('device')) {
884
- objuser.device = msgobj.device;
885
- }
886
- var jsonstr = JSON.stringify(objuser);
887
- w.onlinemeber.onRecvMemberStateChange(jsonstr);
888
- } catch (e) {
889
- ENTRY.recordException(e);
890
- }
891
- }
892
-
893
- var logmsg = 'control:收到join_room:' + msgobj.userid;
894
- ENTRY.recordLogToFile('info', logmsg);
895
- this.displayLogMsg(logmsg);
896
-
897
- CONTROL.notifyMembernumChanged(msgobj);
898
- },
899
-
900
- //处理退出登录消息
901
- dealleaveRoomMsg: function (msgobj) {
902
- try {
903
- //{'unixtime':'32435435','userid':'username','username':'Falcon','role':'1'}
904
- var logmsg = 'control:收到leaveRoom_message:';
905
- logmsg += JSON.stringify(msgobj);
906
- CONTROL.displayLogMsg(logmsg);
907
- ENTRY.recordLogToFile('info', logmsg);
908
-
909
- var isme = ENTRY.isMyMsg(msgobj);
910
- if (isme) {
911
- //这个应该不会发生
912
- ENTRY.recordLogToFile('error', 'receive self leaveroom ack');
913
- } else {
914
- if (w.onlinemeber && w.onlinemeber.onRecvMemberStateChange) {
915
- var objuser = {};
916
- objuser.online = 'logout';
917
- objuser.userid = msgobj.userid;
918
- objuser.role = ENTRY.translateRoleBack(msgobj.role);
919
- var jsonstr = JSON.stringify(objuser);
920
- w.onlinemeber.onRecvMemberStateChange(jsonstr);
921
- }
922
- }
923
- } catch (e) {
924
- ENTRY.recordException(e);
925
- }
926
-
927
- CONTROL.notifyMembernumChanged(msgobj);
928
- },
929
-
930
- notifyMembernumChanged: function (obj) {
931
- try {
932
- //非一对一模式下,需要通知应用层成员数量
933
- if (obj.hasOwnProperty('onlinecounts')) {
934
- if (w.controlObj && controlObj.onMemberChanged && ENTRY.isLargeClass()) {
935
- controlObj.onMemberChanged(obj.onlinecounts);
936
- }
937
-
938
- var logmsg = 'control:online count:';
939
- logmsg += obj.onlinecounts;
940
- this.displayLogMsg(logmsg);
941
- }
942
- } catch (e) {
943
- ENTRY.recordException(e);
944
- }
945
- },
946
-
947
- //处理断开连接消息
948
- dealOfflineMsg: function (msgobj) {
949
- try {
950
- var logmsg = 'control:收到disconnect_message';
951
- logmsg += JSON.stringify(msgobj);
952
- CONTROL.displayLogMsg(logmsg);
953
- ENTRY.recordLogToFile('info', logmsg);
954
-
955
- var isme = ENTRY.isMyMsg(msgobj);
956
- if (!isme) {
957
- if (w.onlinemeber && w.onlinemeber.onRecvMemberStateChange) {
958
- var objuser = {};
959
- objuser.online = 'offline';
960
- objuser.userid = msgobj.userid;
961
- objuser.role = ENTRY.translateRoleBack(msgobj.role);
962
- var jsonstr = JSON.stringify(objuser);
963
- w.onlinemeber.onRecvMemberStateChange(jsonstr);
964
- }
965
-
966
- CONTROL.notifyMembernumChanged(msgobj);
967
- }
968
- } catch (e) {
969
- ENTRY.recordException(e);
970
- }
971
- },
972
-
973
- //处理流控制消息
974
- dealStreamMsg: function (obj, history) {
975
- if (!obj) {
976
- return;
977
- }
978
-
979
- if (CONTROL.judgeAlreadyRecv(obj, history)) {
980
- var logmsg = 'recv repeat msg:' + JSON.stringify(obj);
981
- ENTRY.recordLogToFile('info', logmsg);
982
-
983
- CONTROL.displayLogMsg(logmsg); //删除
984
- return;
985
- }
986
-
987
- //如果现在正在请求缓存队列,先缓存收到的正常消息
988
- if (this.cacheReqSend) {
989
- obj.history = history;
990
- if (obj.hasOwnProperty('cache') && obj.cache == 1) {
991
- this.recvCacheList.push(obj);
992
-
993
- var logmsg1 = 'recv:cache msg' + JSON.stringify(obj);
994
- ENTRY.recordLogToFile('info', logmsg1);
995
- CONTROL.displayLogMsg(logmsg1); //删除
996
- } else {
997
- this.recvTmpList.push(obj);
998
-
999
- var logmsg2 = 'recv:cache normal msg' + JSON.stringify(obj);
1000
- ENTRY.recordLogToFile('info', logmsg2);
1001
- CONTROL.displayLogMsg(logmsg2); //删除
1002
- }
1003
- return;
1004
- }
1005
-
1006
- CONTROL.dealStreamMsgInner(obj, history);
1007
-
1008
- this.checkToIntException(obj);
1009
- },
1010
-
1011
- //消息去重处理
1012
- judgeAlreadyRecv: function (obj, history) {
1013
- //缓存队列
1014
- if (!history && obj.hasOwnProperty('uuid') && obj.uuid != '') {
1015
- if (this.recvmsgKeys.indexOf(obj.uuid) != -1) {
1016
- return true;
1017
- } else {
1018
- this.recvmsgKeys.push(obj.uuid);
1019
- var timenow = new Date();
1020
- this.recvmsgTimes.push(timenow);
1021
-
1022
- //var logmsg = 'recv msg,time now:'+timenow.getTime();
1023
- //CONTROL.displayLogMsg(logmsg);
1024
- }
1025
-
1026
- CONTROL.reduceRecvMsgList();
1027
- }
1028
- return false;
1029
- },
1030
-
1031
- //缩减接收消息列表的长度,防止超长
1032
- reduceRecvMsgList: function () {
1033
- try {
1034
- if (this.recvmsgTimes.length < 1000) {
1035
- return;
1036
- }
1037
- var timenow = new Date();
1038
- var timeex = 3 * 60 * 1000;
1039
- var index = 0;
1040
- for (index = 0; index < this.recvmsgTimes.length; ++index) {
1041
- if ((timenow.getTime() - this.recvmsgTimes[index].getTime()) < timeex) {
1042
- break;
1043
- }
1044
- }
1045
-
1046
- if (index >= 1) {
1047
- this.recvmsgTimes.splice(0, index);
1048
- this.recvmsgKeys.splice(0, index);
1049
-
1050
- //var logmsg = 'reduce key list: index';
1051
- //logmsg += index;
1052
- //logmsg += ',left:';
1053
- //logmsg += this.recvmsgKeys.length;
1054
- //CONTROL.displayLogMsg(logmsg);//删除
1055
- }
1056
- } catch (e) {
1057
- ENTRY.recordException(e);
1058
- }
1059
- },
1060
-
1061
- //处理流控制消息
1062
- dealStreamMsgInner: function (obj, history) {
1063
- try {
1064
- ////测试丢消息、保序和时延
1065
- //if(!history){
1066
- // this.checkechobacktest(obj);
1067
- //}
1068
-
1069
- //var logmsg1 = 'deal stream:'+obj.index + ' '+obj.userid;
1070
- if (obj.mtype != 'lowquality') {
1071
- var logmsg1 = 'recv:' + obj.index;
1072
- logmsg1 += ',msg:';
1073
- logmsg1 += obj.message;
1074
- logmsg1 += ',uuid:';
1075
- logmsg1 += obj.uuid;
1076
- logmsg1 += ',utime:';
1077
- logmsg1 += obj.unixtime;
1078
- ENTRY.recordLogToFile('info', logmsg1);
1079
- }
1080
- /*******专用处理信道中流信息相关功能 start ********/
1081
- if (!history) {
1082
- const data = JSON.parse(obj.message);
1083
- // window.zby_sdk_init_params为用户初始化sdk传递的基础参数
1084
- const baseInfo = {
1085
- roomId: window.zby_sdk_init_params.roomId,
1086
- userId: CONTROL.userid,
1087
- userName: CONTROL.username,
1088
- institutionId: window.zby_sdk_init_params.institutionId,
1089
- targetId: data.actorId,
1090
- role: CONTROL.role === '1' ? 'teacher' : 'student'
1091
- };
1092
- dealReceiveStreamMsg(data, baseInfo);
1093
- }
1094
- /*******专用处理信道中流信息相关功能 end ********/
1095
-
1096
-
1097
- if (!history && w.controlObj && controlObj.onReciveStream) {
1098
- controlObj.onReciveStream(obj.mtype, obj.message);
1099
- }
1100
-
1101
- //提示上下课
1102
- CONTROL.displayClassOperate(obj);
1103
-
1104
- if (w.CHATEST && w.CHATEST.checkorder == 1) {
1105
- CONTROL.checkOrder(obj);
1106
- }
1107
-
1108
- } catch (e) {
1109
- ENTRY.recordException(e);
1110
- }
1111
- },
1112
-
1113
- //处理监课消息
1114
- dealSupervisorMsg: function (obj) {
1115
- if (!obj) {
1116
- return;
1117
- }
1118
-
1119
- try {
1120
- if (obj.mtype == 'help_state') {
1121
- //var message = obj.message;
1122
- var helpobj = obj.message;
1123
- if (this.roomid != helpobj.lessonid || this.userid != helpobj.userid) {
1124
- return;
1125
- }
1126
-
1127
- //求助,机构后台处理后,推送此消息,收到后上报客户端
1128
- if (w.controlObj && w.controlObj.onSupervisorState) {
1129
- var objformat = {};
1130
- objformat.mtype = 'help_state';
1131
- objformat.status = helpobj.supervisorStatus;
1132
- objformat.resolve = helpobj.supervisorResolve;
1133
- w.controlObj.onSupervisorState(JSON.stringify(objformat));
1134
- }
1135
- }
1136
- } catch (e) {
1137
- ENTRY.recordException(e);
1138
- }
1139
- },
1140
-
1141
- //处理网络状态消息
1142
- dealNetStateMsg: function (obj) {
1143
- if (obj && w.controlObj && w.controlObj.onReciveLowQualityMsg) {
1144
- w.controlObj.onReciveLowQualityMsg(obj.mtype, obj.message);
1145
- }
1146
- },
1147
- //处理奖励消息
1148
- dealAwardMsg: function (obj) {
1149
- if (obj && w.controlObj && w.controlObj.onServerPushMessage) {
1150
- w.controlObj.onServerPushMessage('award', JSON.stringify(obj.message));
1151
- }
1152
- },
1153
-
1154
- //处理切换SDK消息
1155
- dealStreamServiceTypeMsg: function (obj) {
1156
- console.log('%c接收到信道广播的切换SDK消息,切换到:' + obj.message.data, 'color:blue');
1157
- ENTRY.recordLogToFile('info', 'channel msg: streamservicetype, change sdk to ' + obj.message.data);
1158
- const data = obj.message;
1159
- if (window.current_sdk_type !== data.data) {
1160
- zbysdk.changeSDK();
1161
- } else {
1162
- console.log('%c接收到信道广播目标SDK和本地一致,不切换:' + obj.message.data, 'color:blue');
1163
- ENTRY.recordLogToFile('info', 'channel target sdk type is the same as the local sdk ,will not change sdk to :' + obj.message.data);
1164
- }
1165
- },
1166
-
1167
- //处理被踢消息
1168
- dealForceExit: function (obj) {
1169
- if (ENTRY.istestFromhtml == 1) {
1170
- CONTROL.displayLogMsg('您已被踢');
1171
- ENTRY.recordLogToFile('info', 'deal with force exit');
1172
- CONTROL.leaveRoom();
1173
- if (w.CHAT && ENTRY.channeltype == 0) {
1174
- w.CHAT.leaveRoom();
1175
- }
1176
- }
1177
-
1178
- if (w.controlObj && w.controlObj.onServerPushMessage) {
1179
- w.controlObj.onServerPushMessage('force_exit', '');
1180
- }
1181
- },
1182
-
1183
- //处理房间过期消息
1184
- dealRoomExpired: function (obj) {
1185
- if (w.controlObj && w.controlObj.onServerPushMessage) {
1186
- w.controlObj.onServerPushMessage('room_expired', '');
1187
- }
1188
- },
1189
-
1190
- //处理断线后重连
1191
- dealReconnectSuccess: function () {
1192
- ENTRY.recordLogToFile('info', 'deal reconnect success');
1193
- CONTROL.displayLogMsg('deal reconnect success'); //删掉
1194
- CONTROL.resendMessages();
1195
- CONTROL.requestCachedMsg();
1196
- },
1197
-
1198
- //断线重连后,请求缓存队列
1199
- requestCachedMsg: function () {
1200
- var uuid = '';
1201
- if (this.recvmsgKeys.length > 0) {
1202
- uuid = this.recvmsgKeys[this.recvmsgKeys.length - 1];
1203
- }
1204
- this.cacheReqSend = true;
1205
- var obj = {};
1206
- obj.uuid = uuid;
1207
- var logmsg = 'requestCachedMsg:' + obj.uuid;
1208
- CONTROL.displayLogMsg(logmsg); //删除
1209
- ENTRY.recordLogToFile('info', logmsg);
1210
- this.socket.emit('cache_message', obj, function (para) {
1211
- logmsg = 'requestCachedMsg: ack ' + para.code;
1212
- CONTROL.displayLogMsg(logmsg); //删除
1213
- ENTRY.recordLogToFile('info', logmsg);
1214
-
1215
- CONTROL.cacheReqSend = false;
1216
- if (para.code == 0) {
1217
- CONTROL.dealRecvCache();
1218
- } else {
1219
- ENTRY.recordLogToFile('error', 'request cache msg ret failed!');
1220
- }
1221
- });
1222
- },
1223
-
1224
- //处理缓存的收到但未处理的消息
1225
- dealRecvCache: function () {
1226
- var reportobj = {};
1227
- reportobj.count = this.recvCacheList.length;
1228
- for (var i = 0; i < this.recvCacheList.length; ++i) {
1229
- CONTROL.dealStreamMsgInner(this.recvCacheList[i], this.recvCacheList[i].history);
1230
- }
1231
- ENTRY.recordLogToFile('info', 'dealRecvCache:server cached num:' + this.recvCacheList.length);
1232
- this.recvCacheList.length = 0;
1233
-
1234
- for (var j = 0; j < this.recvTmpList.length; ++j) {
1235
- CONTROL.dealStreamMsgInner(this.recvTmpList[j], false);
1236
- }
1237
- ENTRY.recordLogToFile('info', 'dealRecvCache:local cached num:' + this.recvTmpList.length);
1238
- this.recvTmpList.length = 0;
1239
-
1240
- //上报积压消息情况
1241
- if (w.controlObj && w.controlObj.onSelfHealthReport) {
1242
- w.controlObj.onSelfHealthReport('servercachedcount', JSON.stringify(reportobj));
1243
- }
1244
- },
1245
-
1246
- //保序验证
1247
- checkOrder: function (obj) {
1248
- //CONTROL.displayLogMsg('recv:'+obj.index);
1249
- if (CONTROL.lastRecvMsgId == null) {
1250
- CONTROL.lastRecvMsgId = new Array();
1251
- }
1252
-
1253
- ++CONTROL.testrecvcount;
1254
- var curtime = new Date();
1255
- CONTROL.displayLogMsg('recv:' + curtime.toTimeString() + ',' + CONTROL.testrecvcount);
1256
-
1257
- var userFind = false;
1258
- for (var i = 0; i < CONTROL.lastRecvMsgId.length; ++i) {
1259
- if (CONTROL.lastRecvMsgId[i].userid == obj.userid) {
1260
- userFind = true;
1261
- if (CONTROL.lastRecvMsgId[i].index > obj.index) {
1262
- CONTROL.displayLogMsg('control msg disorder,userid:' + obj.userid + ',' + obj.index);
1263
-
1264
- if (w.CHATEST) {
1265
- w.CHATEST.setOrderCheckResult('message disorder');
1266
- }
1267
- }
1268
- if (CONTROL.lastRecvMsgId[i].index + 1 != obj.index) {
1269
- CONTROL.displayLogMsg('control msg lost,userid:' + obj.userid + ',' + CONTROL.lastRecvMsgId[i].index + ' to ' + obj.index);
1270
- if (w.CHATEST) {
1271
- w.CHATEST.setOrderCheckResult('message lost');
1272
- }
1273
- }
1274
-
1275
- if (obj.index % 30 == 0) {
1276
- CONTROL.displayLogMsg('recv,useri:' + obj.userid + ',' + obj.index);
1277
- }
1278
-
1279
- CONTROL.lastRecvMsgId[i].index = obj.index;
1280
- break;
1281
- }
1282
- }
1283
- if (!userFind) {
1284
- var tmpobj = {};
1285
- tmpobj.index = obj.index;
1286
- tmpobj.userid = obj.userid;
1287
- CONTROL.lastRecvMsgId.push(tmpobj);
1288
- }
1289
- },
1290
-
1291
- //初始化缓存队列相关
1292
- initCacheList: function () {
1293
- try {
1294
- this.streamIndex = 0;
1295
- this.normalMsgIndex = 0;
1296
- if (!this.sendCheckList) {
1297
- this.sendCheckList = new Array();
1298
- } else {
1299
- this.sendCheckList.length = 0;
1300
- }
1301
- if (!this.sendCacheList) {
1302
- this.sendCacheList = new Array();
1303
- } else {
1304
- this.sendCacheList.length = 0;
1305
- }
1306
- this.cacheReqSend = false;
1307
- if (!this.recvCacheList) {
1308
- this.recvCacheList = new Array();
1309
- } else {
1310
- this.recvCacheList.length = 0;
1311
- }
1312
- if (!this.recvTmpList) {
1313
- this.recvTmpList = new Array();
1314
- } else {
1315
- this.recvTmpList.length = 0;
1316
- }
1317
- if (!this.recvmsgKeys) {
1318
- this.recvmsgKeys = new Array();
1319
- } else {
1320
- this.recvmsgKeys.length = 0;
1321
- }
1322
- if (!this.recvmsgTimes) {
1323
- this.recvmsgTimes = new Array();
1324
- } else {
1325
- this.recvmsgTimes.length = 0;
1326
- }
1327
- if (!this.orderCheck) {
1328
- this.orderCheck = new Array();
1329
- } else {
1330
- this.orderCheck.length = 0;
1331
- }
1332
- if (!this.delaycheckList) {
1333
- this.delaycheckList = new Array();
1334
- } else {
1335
- this.delaycheckList.length = 0;
1336
- }
1337
- if (!this.delayList) {
1338
- this.delayList = new Array();
1339
- } else {
1340
- this.delayList.length = 0;
1341
- }
1342
- this.checkSendSucessTimer = w.setInterval(this.checkStreamMsgSendSuccess, this.checkInterval);
1343
- } catch (e) {
1344
- ENTRY.recordException(e);
1345
- }
1346
- },
1347
-
1348
- //反初始化缓存队列相关
1349
- unInitCacheList: function () {
1350
- this.streamIndex = 0;
1351
- this.normalMsgIndex = 0;
1352
- this.sendCacheList = null;
1353
- this.cacheReqSend = false;
1354
- this.recvCacheList = null;
1355
- this.recvTmpList = null;
1356
- this.recvmsgKeys = null;
1357
- this.recvmsgTimes = null;
1358
- this.orderCheck = null;
1359
- this.delaycheckList = null;
1360
- this.delayList = null;
1361
- if (this.checkSendSucessTimer) {
1362
- w.clearInterval(this.checkSendSucessTimer);
1363
- this.checkSendSucessTimer = null;
1364
- }
1365
- this.sendCheckList = null;
1366
- },
1367
-
1368
- //缓存要发送的消息
1369
- cachedSendMsg: function (obj) {
1370
- try {
1371
- this.sendCacheList.push(obj);
1372
- } catch (e) {
1373
- ENTRY.recordException(e);
1374
- }
1375
- },
1376
-
1377
- //添加到确认队列
1378
- addToCheckList: function (obj) {
1379
- try {
1380
- var checkobj = {};
1381
- checkobj.data = obj;
1382
- checkobj.time = new Date();
1383
- checkobj.success = false;
1384
- this.sendCheckList.push(checkobj);
1385
- } catch (e) {
1386
- ENTRY.recordException(e);
1387
- }
1388
- },
1389
-
1390
- //收到确认
1391
- setSendSuccess: function (obj) {
1392
- try {
1393
- for (var i = 0; i < CONTROL.sendCheckList.length; ++i) {
1394
- if (CONTROL.sendCheckList[i].data.index == obj.index) {
1395
- CONTROL.sendCheckList[i].success = true;
1396
- break;
1397
- }
1398
- }
1399
-
1400
- //缓存队列:清理
1401
- var length = CONTROL.sendCheckList.length;
1402
- while (length > 0 && CONTROL.sendCheckList[0].success) {
1403
- CONTROL.sendCheckList.splice(0, 1);
1404
- length = CONTROL.sendCheckList.length;
1405
- }
1406
- } catch (e) {
1407
- ENTRY.recordException(e);
1408
- }
1409
- },
1410
-
1411
- //检查消息是否发送成功
1412
- checkStreamMsgSendSuccess: function () {
1413
- try {
1414
- var length = CONTROL.sendCheckList.length;
1415
- if (length > 0 && this.isInRoom) {
1416
- var curtime = new Date();
1417
- if (curtime.getTime() - CONTROL.sendCheckList[length - 1].time.getTime() > CONTROL.maxAckDelay) {
1418
- CONTROL.resendMessages();
1419
-
1420
- ////todo 缓存队列过长的话,断开重新连接
1421
- if (length > 200) {
1422
- var logmsg01 = 'check message to much:' + length;
1423
- ENTRY.recordLogToFile('error', logmsg01);
1424
- }
1425
-
1426
- var logmsg = 'resend messages withou ack:' + length;
1427
- ENTRY.recordLogToFile('info', logmsg);
1428
- CONTROL.displayLogMsg(logmsg); //删掉
1429
- ENTRY.reportHintInfo(logmsg);
1430
- }
1431
- }
1432
- } catch (e) {
1433
- ENTRY.recordException(e);
1434
- }
1435
- },
1436
-
1437
- //重新发送缓存的消息
1438
- resendMessages: function () {
1439
- try {
1440
- var reportobj = {};
1441
- var length = CONTROL.sendCheckList.length;
1442
- reportobj.unconfirmcount = length;
1443
- if (length > 0) {
1444
- var sendlist = CONTROL.sendCheckList.slice(0);
1445
- CONTROL.sendCheckList.length = 0;
1446
- for (var i = 0; i < sendlist.length; ++i) {
1447
- this.sendStreamMsgInner(sendlist[i].data);
1448
- }
1449
- }
1450
-
1451
- var cachedlenth = this.sendCacheList.length;
1452
- reportobj.count = length + this.sendCacheList.length;
1453
- for (var i = 0; i < this.sendCacheList.length; ++i) {
1454
- this.sendStreamMsgInner(this.sendCacheList[i]);
1455
- }
1456
- this.sendCacheList.length = 0;
1457
-
1458
- //上报积压消息情况
1459
- if (w.controlObj && w.controlObj.onSelfHealthReport) {
1460
- w.controlObj.onSelfHealthReport('resendcount', JSON.stringify(reportobj));
1461
- }
1462
-
1463
- var logmsg = 'resent message,checklist:';
1464
- logmsg += length;
1465
- logmsg += ',cached:';
1466
- logmsg += cachedlenth;
1467
- ENTRY.recordLogToFile('info', logmsg);
1468
- CONTROL.displayLogMsg(logmsg); //删掉
1469
- } catch (e) {
1470
- ENTRY.recordException(e);
1471
- }
1472
- },
1473
-
1474
- //显示开始上课/结束上课消息
1475
- displayClassOperate: function (msgobj) {
1476
- try {
1477
- if (msgobj.mtype == 'class') {
1478
- var classobj = JSON.parse(msgobj.message);
1479
- if (!msgobj.hasOwnProperty('unixtime')) {
1480
- return;
1481
- }
1482
-
1483
- //只用control通道的话,需要通知chat通道去显示,否则直接在聊天页面显示
1484
- if (ENTRY.channeltype == 1) {
1485
- if (w.controlObj && w.controlObj.onDisplayClassOperate) {
1486
- w.controlObj.onDisplayClassOperate(classobj.cmdtype, msgobj.unixtime);
1487
- }
1488
- } else {
1489
- if (w.CHATDIS) {
1490
- w.CHATDIS.disClassStatusHint(classobj.cmdtype, msgobj.unixtime);
1491
- }
1492
- }
1493
-
1494
- } //end of if
1495
- } catch (e) {
1496
- ENTRY.recordException(e);
1497
- }
1498
- },
1499
-
1500
- //检查异常
1501
- checkToIntException: function (obj) {
1502
- try {
1503
- var uttime = obj.unixtime.substr(0, obj.unixtime.length - 3);
1504
- var timeint = parseInt(uttime); //todo 检查到底怎么回事
1505
- var timeint = ENTRY.parseIntMySimple(uttime);
1506
- if (!(timeint.toString() == uttime)) {
1507
- ENTRY.recordLogToFile('error', 'parseint error');
1508
- CONTROL.displayLogMsg('parseint error'); //删掉
1509
- }
1510
- } catch (e) {}
1511
- },
1512
-
1513
- //发送流控制消息 string string string string
1514
- sendStreamMsgTest: function (subtype, content, targetid, save) {
1515
- //subtype : stream / class(save)
1516
- var curtime = new Date();
1517
- var obj = {};
1518
- obj.index = this.streamIndex++; //int
1519
- obj.uuid = ENTRY.getMsgKey(obj.index); //string
1520
- obj.mtype = subtype; //消息子类型
1521
- obj.targetid = targetid;
1522
- obj.message = content;
1523
- obj.save = save;
1524
- obj.echotest = 1;
1525
- obj.sendtime = curtime.getTime();
1526
- obj.checkindex = obj.index;
1527
-
1528
- var objtest = {};
1529
- objtest.checkindex = obj.index;
1530
- objtest.sendtime = obj.sendtime;
1531
- this.delaycheckList.push(objtest);
1532
-
1533
- if (this.isInRoom) {
1534
- this.sendStreamMsgInner(obj);
1535
- } else {
1536
- this.cachedSendMsg(obj);
1537
- }
1538
- },
1539
-
1540
- checkechobacktest: function (obj) {
1541
- //subtype : stream / class(save)
1542
- var curtime = new Date();
1543
- var index = 0;
1544
- if (!obj.hasOwnProperty('echotest')) {
1545
- return;
1546
- }
1547
-
1548
-
1549
- for (index = 0; index < this.delaycheckList.length; ++index) {
1550
- if (obj.checkindex > this.delaycheckList[index].checkindex) {
1551
- break;
1552
- }
1553
-
1554
- if (obj.checkindex == this.delaycheckList[index].checkindex) {
1555
- ;
1556
- }
1557
- }
1558
- },
1559
- getPingPongArr: function () {
1560
- setTimeout(function () {
1561
- CONTROL.pingPongArr = [];
1562
- }, 1);
1563
- return CONTROL.pingPongArr;
1564
- }
1565
- };
1566
-
1567
- export default CONTROL;
1568
- // })();
1
+ import CHANNEL from '../index';
2
+ import zbysdk from '../../zby-live-sdk.js';
3
+ import ENTRY from './interactWithChannelEntry.js';
4
+ import io from 'socket.io-client';
5
+ import dataReport from '../../network/dataReport';
6
+ import dealReceiveStreamMsg from '../stream-msg';
7
+ // import {getApiCloudBaseUrl} from '../../config/config';
8
+
9
+ let w = window;
10
+ let CONTROL = {
11
+ socket: null,
12
+ //连接保持相关
13
+ enterInit: false, //是否发起过登录,leaveRoom后置为false
14
+ enterSuccessed: false, //是否进入房间成功过,leaveRoom或主动disconnect后置为false
15
+ isConnect: false, //连接服务器成功的标志
16
+ isInRoom: false, //当前是否在房间中,掉线后为false
17
+ isReconnect: false, //是否是自动重连,控制“进入教室”的显示
18
+ isOffline: false, //是否网络断线
19
+ joindelaytimer: null, //连接建立后,延迟发起登录请求
20
+ jointimeouttimer: null, //登录超时time
21
+ connecttimeouttimer: null,
22
+ connecttimeCount: 0, //初次连接时已尝试连接服务器的次数(用于connect超时检查)
23
+ connecttimeout: 20000, //连接服务器超时,第一次设置20秒 之后变为30秒
24
+ authorizefailedcount: 0, //授权失败的次数
25
+
26
+ //设置相关
27
+ address: '', //以下为客户端传入的变量
28
+ token: '',
29
+ code: '', //口令课时的口令,此时token应为空
30
+ role: '1', //'1=teacher'/'2=student'/'3=assistant'/'4=parent'
31
+ username: '', //显示用户相关信息时使用username
32
+ userid: '', //消息后台识别用户使用userid
33
+ avatar: '',
34
+ conn_origin: '',
35
+ language: 0, //0=中文,1=英文
36
+ classmode: 1, ////1=1对1模式;2=1对多模式;3=大班课模式;5=互动大班课
37
+ playmode: 1, ////1=正常上课;2=回放
38
+ roomid: '',
39
+ institutionid: '',
40
+
41
+ //确保消息发送成功相关的
42
+ streamIndex: 0,
43
+ normalMsgIndex: 0, //不需要保序的消息的id
44
+ checkInterval: 3000, //检查“消息发送超时”的时间间隔(超时时间在检查函数中)
45
+ maxAckDelay: 8000, //消息回复的最大时间延迟,超过最大延迟还没收到回复,认为没发送成功
46
+ checkSendSucessTimer: null,
47
+ sendCheckList: null, //发送确认队列
48
+ sendCacheList: null, //发送缓存队列
49
+ recvmsgKeys: null, //接收消息的缓存队列
50
+ recvmsgTimes: null, //接收消息的缓存队列每条消息对应的时间
51
+ cacheReqSend: false, //请求服务器端缓存的命令是否发送了
52
+ recvCacheList: null, //断线重连后,请求缓存队列后,保存缓存的消息
53
+ recvTmpList: null, //断线重连后,在获取服务器到服务器端的缓存队列前,先缓存收到的消息,不上抛
54
+ timedeviation: 0, //本地时间与服务器时间的差值,毫秒:服务器时间-本地时间
55
+ orderCheck: null, //保序验证
56
+ lastRecvMsgId: null, //保序验证 //测试添加
57
+ testrecvcount: null, //保序验证,统计接收消息数 //测试添加
58
+ delaycheckList: null, //保序、丢消息、延迟验证 //测试添加
59
+ delayList: null, //延迟列表
60
+ lastcheckindex: 0, //上一个收到的echo回复的
61
+ dealChannelMsg: null, // 业务层传入的消息处理器,作为回调使用
62
+ pingPongArr: [],
63
+ //public 进入教室
64
+ enterRoom: function (dealChannelMsg) {
65
+ CONTROL.dealChannelMsg = dealChannelMsg;
66
+ if (!this.enterInInitparas()) {
67
+ return;
68
+ }
69
+ ENTRY.recordLogToFile('info', 'enter room info');
70
+ //通知宿主,页面开始连接了
71
+ if (w.controlObj && w.controlObj.onStartConnect) {
72
+ w.controlObj.onStartConnect();
73
+ }
74
+ this.startEnter();
75
+ },
76
+
77
+ //public 退出,断开连接
78
+ leaveRoom: function () {
79
+ CONTROL.otherChannelleaveRoom();
80
+
81
+ ENTRY.recordLogToFile('info', 'control: leaveRoom');
82
+
83
+ if (!this.enterInit) {
84
+ return;
85
+ }
86
+ CONTROL.enterInit = false;
87
+
88
+ this.sendleaveRoomMsg();
89
+ if (this.socket) {
90
+ this.socket.disconnect();
91
+ }
92
+
93
+ this.leaveRoomReset();
94
+ },
95
+
96
+ //其它通道离开房间
97
+ otherChannelleaveRoom: function () {
98
+ try {
99
+ //其他通道
100
+ if (ENTRY.channeltype == 0) {
101
+ if (w.CHAT) {
102
+ w.CHAT.leaveRoom();
103
+ }
104
+ }
105
+ } catch (e) {
106
+ ENTRY.recordException(e);
107
+ }
108
+ },
109
+
110
+ //开始登录过程 连接-验证身份-进入教室
111
+ startEnter: function () {
112
+ CONTROL.enterInit = true;
113
+ ENTRY.recordLogToFile('info', 'enter channel room start');
114
+ var logmsg = 'control:connect ';
115
+ logmsg += this.address;
116
+ CONTROL.displayLogMsg(logmsg);
117
+ ENTRY.recordLogToFile('info', logmsg);
118
+
119
+ //连接
120
+ this.socketConnect();
121
+
122
+ //超时检查
123
+ this.startCheckConnectTimer();
124
+ },
125
+
126
+ //socket 开始连接
127
+ socketConnect: function () {
128
+
129
+ //开始连接时,如果存在已有socket,先断开连接
130
+ if (CONTROL.socket) {
131
+ CONTROL.socket.disconnect();
132
+ }
133
+ var opt = new Object();
134
+ opt.transports = ['websocket'];
135
+ ENTRY.recordLogToFile('info', 'channel start connect ' + this.address);
136
+ CONTROL.socket = io.connect(this.address, opt);
137
+ this.setEventListeners();
138
+ },
139
+
140
+ //注册监听事件
141
+ setEventListeners: function () {
142
+ console.log('websocket: 设置监听');
143
+ //监听连接成功 01步
144
+ this.socket.on('connect', function (o) {
145
+ ENTRY.recordLogToFile('info', 'channel connect success');
146
+ CONTROL.dealConnectSuccess();
147
+ try {
148
+ dataReport.joinRoomResult({
149
+ code: '0',
150
+ // cloud_api_response: JSON.stringify(window.zby_sdk_cloud_data),
151
+ cloud_api_response: window.zby_sdk_cloud_data,
152
+ cloud_api_url: `${getApiCloudBaseUrl()}/rtccloud/class/init`,
153
+ chat_url: window.zby_sdk_cloud_data.chatUrl
154
+ });
155
+ } catch (e) {};
156
+ });
157
+
158
+ //授权成功 02步
159
+ this.socket.on('authenticated', function () {
160
+ console.log('websocket: 授权成功');
161
+ CONTROL.displayLogMsg('control:authenticated!');
162
+ ENTRY.recordLogToFile('info', 'control:authenticated succeessful');
163
+ CONTROL.stopCheckConnectTimer();
164
+ CONTROL.joindelaytimer = window.setTimeout(CONTROL.sendJoinInMsg, 100); //延迟100毫秒登录
165
+ });
166
+
167
+ //授权不成功
168
+ this.socket.on('unauthenticated', function () {
169
+ ENTRY.recordLogToFile('info', 'control:authenticated failed');
170
+ CONTROL.dealAuthorizeFailed();
171
+ try {
172
+ dataReport.joinRoomResult({
173
+ code: '4',
174
+ cloud_api_response: window.zby_sdk_cloud_data,
175
+ cloud_api_url: `${getApiCloudBaseUrl()}/rtccloud/class/init`,
176
+ chat_url: window.zby_sdk_cloud_data.chatUrl
177
+ });
178
+ } catch (e) {};
179
+ });
180
+
181
+ //监听连接断开,禁用网卡/主动disconnect,会回调这个
182
+ this.socket.on('disconnect', function () {
183
+ CONTROL.isOffline = true;
184
+ CONTROL.dealDisconnect();
185
+
186
+ });
187
+ this.socket.on('pong', function (data) {
188
+ // console.log(data + ' - pong');
189
+ CONTROL.pingPongArr.push(data);
190
+ });
191
+ this.OnUserDefineMsg();
192
+ },
193
+
194
+ //发送验证权限消息
195
+ sendAuthenMsg: function () {
196
+ try {
197
+ if (CONTROL.token != '') {
198
+ CONTROL.socket.emit('authenticate', {
199
+ token: CONTROL.token,
200
+ room: CONTROL.roomid,
201
+ instid: CONTROL.institutionid,
202
+ userid: CONTROL.userid
203
+ });
204
+ } else if (CONTROL.code != '') {
205
+ CONTROL.socket.emit('authenticate', {
206
+ code: CONTROL.code,
207
+ room: CONTROL.roomid,
208
+ instid: CONTROL.institutionid,
209
+ userid: CONTROL.userid
210
+ });
211
+
212
+ var logmsg = 'control sendAuthenMsg:with code:' + CONTROL.code;
213
+ ENTRY.recordLogToFile('info', logmsg);
214
+ } else {
215
+ ENTRY.recordLogToFile('error', 'control auth para wrong');
216
+ }
217
+ } catch (e) {
218
+ ENTRY.recordException(e);
219
+ }
220
+ },
221
+
222
+ //连接授权成功后发送:进入房间消息发送
223
+ sendJoinInMsg: function () {
224
+ // 销毁延迟登录timer
225
+ CONTROL.stopDelayJoinTimer();
226
+
227
+ try {
228
+ var obj = {};
229
+ obj.username = CONTROL.username;
230
+ obj.room = CONTROL.roomid;
231
+ obj.avatar = CONTROL.avatar;
232
+ obj.userid = CONTROL.userid;
233
+ obj.role = CONTROL.role;
234
+ obj.playmode = CONTROL.playmode;
235
+ obj.device = 1; //0 - 默认;1 - PC客户端;2 - PC web;3 - 移动 web;4 - 移动 APP;
236
+ obj.instid = CONTROL.institutionid;
237
+ obj.conn_origin = CONTROL.conn_origin;
238
+ obj.classmode = ENTRY.getClassTypeInDb();
239
+ ENTRY.recordLogToFile('info', 'control:emit join_room');
240
+ CONTROL.socket.emit('join_room', obj, function (param) {
241
+ CONTROL.dealJoinMsgAck(param);
242
+ var logmsg = 'control:join_room ack' + JSON.stringify(param);
243
+ ENTRY.recordLogToFile('info', logmsg);
244
+ });
245
+ CONTROL.isOffline = false;
246
+
247
+ } catch (e) {
248
+ ENTRY.recordException(e);
249
+ }
250
+
251
+ // 超时后检查进入房间是否成功
252
+ CONTROL.startCheckJoinInTimer();
253
+ },
254
+
255
+ //退出登录消息发送
256
+ sendleaveRoomMsg: function () {
257
+ if (CONTROL.socket == null) {
258
+ return;
259
+ }
260
+ try {
261
+ ENTRY.recordLogToFile('info', 'control:emit leave room');
262
+ CONTROL.socket.emit('leave_room', {}, function (param) {});
263
+ } catch (e) {
264
+ ENTRY.recordException(e);
265
+ }
266
+ },
267
+
268
+ //进入房间是否成功的检查,在进入房间尚未成功时,重新启动进入过程
269
+ checkAndReEnter: function () {
270
+ CONTROL.stopAllTimeoutTimer();
271
+
272
+ // 离开教室 / 进入房间成功后,不用再检查了
273
+ // 掉线重连,不走这儿,这儿是尚未连接成功过,或主动disconnect后的重连;掉线后,socket.io库会自动重连,并回调connect
274
+ if (!CONTROL.enterInit || CONTROL.enterSuccessed) {
275
+ var logmsg = 'control:checkAndReEnter not needed:' + CONTROL.enterInit + ',' + CONTROL.enterSuccessed;
276
+ ENTRY.recordLogToFile('info', logmsg);
277
+ return;
278
+ }
279
+ ENTRY.recordLogToFile('info', 'control:checkAndReEnter');
280
+
281
+ if (CONTROL.connecttimeCount < ENTRY.enterMaxCount) {
282
+ CONTROL.reEnterRoom();
283
+ } else {
284
+ //上报客户端
285
+ if (w.controlObj && w.controlObj.loginFailed) {
286
+ w.controlObj.loginFailed();
287
+ }
288
+ // channel_join 信道连接 进入房间失败
289
+ ENTRY.recordLogToFile('info', 'channel reenter failed');
290
+ }
291
+ },
292
+
293
+ //重新连接并进入房间
294
+ reEnterRoom: function () {
295
+ CONTROL.reenterReset();
296
+ if (CONTROL.enterSuccessed) {
297
+ CONTROL.isReconnect = true;
298
+ }
299
+ CONTROL.connecttimeCount++;
300
+ CONTROL.startEnter();
301
+ },
302
+
303
+ //连接超时检查
304
+ checkConnectTimeout: function () {
305
+ CONTROL.stopCheckConnectTimer();
306
+ if (!CONTROL.isConnect) {
307
+ ENTRY.recordLogToFile('info', 'control:check connect failed,reenter');
308
+ CONTROL.checkAndReEnter();
309
+ }
310
+ },
311
+
312
+ //处理连接成功的事件
313
+ dealConnectSuccess: function () {
314
+ ENTRY.recordLogToFile('info', 'control:connect success');
315
+
316
+ //没有执行过登录操作
317
+ if (!this.enterInit) {
318
+ ENTRY.recordLogToFile('error', 'control:recve connect,not init yet!');
319
+ return;
320
+ }
321
+
322
+ this.isConnect = true;
323
+
324
+ //发送验证
325
+ this.sendAuthenMsg(); //回调 authenticated
326
+
327
+ //上报客户端
328
+ if (w.controlObj && controlObj.connectSuccess) {
329
+ controlObj.connectSuccess();
330
+ }
331
+ },
332
+
333
+ //处理断开连接事件
334
+ dealDisconnect: function () {
335
+ ENTRY.recordLogToFile('info', 'control:channel disconnect');
336
+ if (!CONTROL.enterInit) {
337
+ ENTRY.recordLogToFile('info', 'control:recve disconnect,already logout');
338
+ return;
339
+ }
340
+
341
+ try {
342
+ CONTROL.displayLogMsg('control: disconnect');
343
+ CONTROL.isConnect = false;
344
+ CONTROL.isInRoom = false;
345
+ if (CONTROL.enterSuccessed) {
346
+ //自己掉线通知
347
+ if (w.controlObj && controlObj.disconnect) {
348
+ controlObj.disconnect();
349
+ }
350
+ CONTROL.dealChannelMsg({
351
+ type: 'channel_disconnect',
352
+ data: {
353
+ message: 'Channel disconnect'
354
+ }
355
+ });
356
+
357
+ }
358
+ } catch (e) {}
359
+ },
360
+
361
+ //处理授权失败
362
+ dealAuthorizeFailed: function () {
363
+ try {
364
+ if (CONTROL.enterSuccessed) {
365
+ //进入房间成功过,但掉线重连时,验证授权失败了
366
+ ENTRY.recordLogToFile('info', 'control:authenticated failed when reconect');
367
+ if (CONTROL.authorizefailedcount < 8) {
368
+ ENTRY.recordLogToFile('error', 'control:authenticated failed socketConnect');
369
+ CONTROL.socketConnect();
370
+ }
371
+
372
+ } else {
373
+ //尚未进入房间成功,且授权失败了
374
+ ENTRY.recordLogToFile('error', 'control:authenticated failed when connect first time');
375
+ CONTROL.checkAndReEnter();
376
+ }
377
+ ++CONTROL.authorizefailedcount;
378
+ } catch (e) {
379
+ ENTRY.recordException(e);
380
+ }
381
+ },
382
+ //处理登录消息
383
+ dealJoinMsgAck: function (msgobj) {
384
+ //{'code':0,'message':'join ok'}
385
+ if (!msgobj) {
386
+ return;
387
+ }
388
+ if (msgobj.code == 0) {
389
+ if (!this.enterSuccessed) {
390
+ CONTROL.otherChannelEnter(); //其它通道进入房间,免身份验证
391
+ }
392
+
393
+ this.stopCheckJoinInTimer();
394
+
395
+ if (!this.isInRoom) {
396
+ if (this.enterSuccessed) {
397
+ CONTROL.dealReconnectSuccess();
398
+ this.displayLogMsg('control: reenter room success'); //重新登录成功
399
+ ENTRY.recordLogToFile('info', 'reenter room success');
400
+ CONTROL.dealChannelMsg({
401
+ type: 'channel_reconnect',
402
+ data: {
403
+ message: 'Channel reconnect'
404
+ }
405
+ });
406
+ //如果之前登入过,且现在没在房间内,代表当次连接为断线重连,重连成功须重新发送音视频 join 消息
407
+ CHANNEL.reJoin();
408
+ } else {
409
+ //请求历史消息
410
+ this.getHistoryList();
411
+ this.displayLogMsg('control: enter room success'); //已进入房间的话就不要提示了
412
+ ENTRY.recordLogToFile('info', 'control: enter room success');
413
+ }
414
+ }
415
+ this.isInRoom = true;
416
+ this.enterSuccessed = true; //设置进房间已经成功过了
417
+
418
+ if (w.controlObj && w.controlObj.loginResponse) {
419
+ w.controlObj.loginResponse();
420
+ }
421
+
422
+ //测试添加
423
+ //this.getOnlineList();
424
+
425
+ //在线人数
426
+ this.notifyMembernumChanged(msgobj.data);
427
+
428
+ CONTROL.timedeviation = msgobj.data.unixtime - (new Date().getTime());
429
+ } else {
430
+ this.checkAndReEnter();
431
+ }
432
+ },
433
+
434
+ //其它通道进行连接
435
+ otherChannelEnter: function () {
436
+ try {
437
+ if (ENTRY.channeltype == 0) {
438
+ if (w.CHAT) {
439
+ w.CHAT.enterRoom();
440
+ }
441
+ }
442
+ } catch (e) {
443
+ ENTRY.recordException(e);
444
+ }
445
+ },
446
+
447
+ //登录前,初始化参数
448
+ enterInInitparas: function () {
449
+ try {
450
+ var config = ENTRY.getConfigInfo();
451
+ var roominfo = ENTRY.getRoomInfo();
452
+ if (!config || !roominfo) {
453
+ ENTRY.recordLogToFile('info', 'enter room:room info is empty or user info is empty');
454
+ return false;
455
+ }
456
+ this.address = config.address + 'control';
457
+
458
+ //兼容一下老的客户端,老的客户端使用的是url编码
459
+ // if(config.hasOwnProperty('encodetype') && config.encodetype=='base64'){
460
+ // var b64decoder = new w.Base64();
461
+ // this.username = b64decoder.decode(config.user.username);
462
+ // this.avatar = b64decoder.decode(config.user.avatar);
463
+ // ENTRY.recordLogToFile('i','control enterInInitparas:use base64 decode:'+this.username);
464
+ // }
465
+ // else{
466
+ this.username = decodeURIComponent(config.user.username);
467
+ this.avatar = decodeURIComponent(config.user.avatar);
468
+ ENTRY.recordLogToFile('info', 'control enterInInitparas:use url decode:' + this.username);
469
+ // }
470
+ this.userid = config.user.userid;
471
+
472
+ if (config.user.hasOwnProperty('token')) {
473
+ this.token = config.user.token;
474
+ }
475
+ if (config.user.hasOwnProperty('code')) {
476
+ this.code = config.user.code;
477
+ }
478
+ this.role = config.user.role;
479
+ this.language = config.language;
480
+ this.roomid = roominfo.roomid;
481
+ this.classmode = roominfo.classmode;
482
+ this.playmode = roominfo.playmode;
483
+ this.institutionid = roominfo.institutionid;
484
+ this.conn_origin = roominfo.conn_origin;
485
+ if (this.roomid == '' || this.userid == '') {
486
+ ENTRY.recordLogToFile('error', 'enter room:roomid is empty or userid is empty');
487
+ return false;
488
+ }
489
+
490
+ this.isReconnect = false; //重连标志,重连一次就算重连了
491
+ this.connecttimeCount = 0;
492
+ this.initCacheList();
493
+ } catch (e) {
494
+ ENTRY.recordException(e);
495
+ return false;
496
+ }
497
+
498
+ return true;
499
+ },
500
+
501
+ //重启进入教室过程前,对某些变量进行重置
502
+ reenterReset: function () {
503
+ this.isInRoom = false;
504
+ this.isConnect = false;
505
+
506
+ if (this.userstate == null) {
507
+ this.userstate = new Array();
508
+ } else {
509
+ this.userstate.length = 0;
510
+ }
511
+ if (this.socket) {
512
+ this.socket.disconnect();
513
+ }
514
+ this.stopAllTimeoutTimer();
515
+ },
516
+
517
+ leaveRoomReset: function () {
518
+ this.reenterReset();
519
+
520
+ //停一下timer
521
+ this.stopAllTimeoutTimer();
522
+
523
+ this.unInitCacheList();
524
+
525
+ this.connecttimeCount = 0;
526
+ this.enterInit = false;
527
+ this.enterSuccessed = false;
528
+ this.socket = null;
529
+ },
530
+
531
+ //启动 连接超时检查
532
+ startCheckConnectTimer: function () {
533
+ this.connecttimeouttimer = window.setTimeout(CONTROL.checkConnectTimeout, CONTROL.connecttimeout);
534
+ CONTROL.connecttimeout = 30000;
535
+ },
536
+
537
+ //关闭 连接超时检查
538
+ stopCheckConnectTimer: function () {
539
+ if (this.connecttimeouttimer) {
540
+ w.clearTimeout(this.connecttimeouttimer);
541
+ this.connecttimeouttimer = null;
542
+ }
543
+ },
544
+
545
+ //关闭 延迟join的timer
546
+ stopDelayJoinTimer: function () {
547
+ if (CONTROL.joindelaytimer != null) {
548
+ window.clearTimeout(CONTROL.joindelaytimer);
549
+ CONTROL.joindelaytimer = null;
550
+ }
551
+ },
552
+
553
+ //启动 进入房间超时的检查
554
+ startCheckJoinInTimer: function () {
555
+ this.jointimeouttimer = window.setTimeout(CONTROL.checkAndReEnter, CONTROL.connecttimeout);
556
+ },
557
+
558
+ //关闭 进入房间超时的检查
559
+ stopCheckJoinInTimer: function () {
560
+ if (this.jointimeouttimer) {
561
+ w.clearTimeout(this.jointimeouttimer);
562
+ this.jointimeouttimer = null;
563
+ }
564
+ },
565
+
566
+ //停止所有计时器
567
+ stopAllTimeoutTimer: function () {
568
+ this.stopCheckConnectTimer();
569
+ this.stopCheckJoinInTimer();
570
+ this.stopDelayJoinTimer();
571
+ },
572
+
573
+ displayLogMsg: function (msg) {
574
+ if (w.CHATDIS) {
575
+ w.CHATDIS.displayLogMsg(msg);
576
+ }
577
+ },
578
+
579
+ //////////////////////以上为进入房间/离开房间 过程的通用处理/////////////////////////////////////
580
+ //发送流控制消息 string string string string
581
+ sendStreamMsg: function (subtype, content, targetid, save) {
582
+ //subtype : stream / class(save)
583
+ var obj = {};
584
+ obj.index = this.streamIndex++; //int
585
+ obj.uuid = ENTRY.getMsgKey(obj.index); //string
586
+ obj.mtype = subtype; //消息子类型
587
+ obj.targetid = targetid;
588
+ obj.trace_id = `sdk_1.0_${(new Date().getTime()).toString().padStart(16, '123456')}`;
589
+ obj.message = content;
590
+ obj.save = save;
591
+
592
+ if (this.isInRoom) {
593
+ this.sendStreamMsgInner(obj);
594
+ } else {
595
+ this.cachedSendMsg(obj);
596
+ }
597
+ },
598
+
599
+ //发送可以丢失的消息
600
+ sendUnimportantStreamMsg: function (subtype, content, targetid, save) {
601
+ //subtype : stream / class(save)
602
+ if (!this.isInRoom || !this.socket) {
603
+ return;
604
+ }
605
+ var obj = {};
606
+ obj.index = this.normalMsgIndex++; //int 不关心
607
+ obj.uuid = ENTRY.getMsgKey(obj.index); //string
608
+ obj.mtype = 'lowquality'; //消息子类型
609
+ obj.targetid = targetid;
610
+ obj.message = content;
611
+ obj.save = save;
612
+ this.socket.emit('stream', obj, function (status) {});
613
+ },
614
+
615
+ sendStreamMsgInner: function (obj) {
616
+ try {
617
+ var logmsg = 'send:' + obj.index;
618
+ logmsg += ',msg:';
619
+ logmsg += obj.message;
620
+ logmsg += ',uuid:';
621
+ logmsg += obj.uuid;
622
+ ENTRY.recordLogToFile('info', logmsg);
623
+
624
+ this.addToCheckList(obj);
625
+ this.socket.emit('stream', obj, function (status) {
626
+ if (status.code == 0) {
627
+ CONTROL.setSendSuccess(obj);
628
+
629
+ //提示开始上课/结束上课
630
+ var curtime = new Date();
631
+ var timeseconds = curtime.getTime() + CONTROL.timedeviation;
632
+ var timestr = '';
633
+ timestr += timeseconds;
634
+ obj.unixtime = timestr;
635
+ CONTROL.displayClassOperate(obj);
636
+ }
637
+ var logmsg = 'control:send ack:' + obj.index;
638
+ ENTRY.recordLogToFile('info', logmsg);
639
+ });
640
+ } catch (e) {
641
+ ENTRY.recordException(e);
642
+ }
643
+
644
+ //CONTROL.displayLogMsg(logmsg1);//删掉
645
+ },
646
+
647
+ //发送普通控制消息 string string string 暂时没有使用此事件
648
+ sendCommonMsg: function (subtype, content, targetid) {
649
+ //subtype:netstate
650
+ var obj = {};
651
+ obj.index = ENTRY.getMsgIndex(); //int
652
+ obj.mtype = subtype; //消息子类型
653
+ obj.targetid = targetid;
654
+ obj.message = content;
655
+ //obj.save = save;//暂时没有save字段
656
+ this.socket.emit('common', obj, function (status) {});
657
+ },
658
+
659
+ //发送可以丢失的消息
660
+ sendLowQualityMsg: function (subtype, content, targetid) {
661
+ //subtype : stream / class(save)
662
+ if (!this.isInRoom || !this.socket) {
663
+ return;
664
+ }
665
+ var obj = {};
666
+ obj.index = this.normalMsgIndex++; //int 不关心
667
+ obj.uuid = ENTRY.getMsgKey(obj.index); //string
668
+ obj.mtype = subtype; //消息子类型
669
+ obj.targetid = targetid;
670
+ obj.message = content;
671
+ this.socket.emit('netstate', obj, function (status) {});
672
+ },
673
+
674
+ //获取当前在线列表 老师身份的才有效
675
+ getOnlineList: function () {
676
+ try {
677
+ this.socket.emit('listeners', {}, function (status) {
678
+ if (status.code != 0) {
679
+ //if(w.onlinemeber && w.onlinemeber.onRecvMemberDataFinished){
680
+ // w.onlinemeber.onRecvMemberDataFinished();
681
+ //}
682
+
683
+ ENTRY.recordLogToFile('error', 'get online list failed!');
684
+ }
685
+ });
686
+ } catch (e) {
687
+ ENTRY.recordException(e);
688
+ }
689
+ },
690
+
691
+ //请求stream历史消息
692
+ getHistoryList: function () {
693
+ try {
694
+ ENTRY.recordLogToFile('info', 'emit history_message!');
695
+ this.socket.emit('history_message', {}, function (para) {
696
+ ENTRY.recordLogToFile('info', 'history_message ret!');
697
+ if (para.code == 0) {
698
+ try {
699
+ //只处理开始上课、结束上课消息
700
+ var length = para.data.history_list.length;
701
+ for (var i = 0; i < length; ++i) {
702
+ var msgobj = para.data.history_list[i];
703
+ CONTROL.displayClassOperate(msgobj);
704
+ } //end of for
705
+
706
+ //通知学生端 最后一条课程状态消息
707
+ if (length > 0 && CONTROL.role == '2' && w.controlObj && w.controlObj.onReciveStream) {
708
+ for (var j = length - 1; j >= 0; j--) {
709
+ var msgobjclass = para.data.history_list[j];
710
+ if (msgobjclass.mtype == 'class') {
711
+ w.controlObj.onReciveStream(msgobjclass.mtype, msgobjclass.message);
712
+ break;
713
+ }
714
+ }
715
+ }
716
+
717
+ //通知老师端,开始上课和结束上课有没有
718
+ var startclassExist = 'false';
719
+ var endclassExist = 'false';
720
+ if (w.controlObj && w.controlObj.onKeyMessageSent) {
721
+ for (var i = 0; i < length; i++) {
722
+ var msgobjclass = para.data.history_list[i];
723
+ if (msgobjclass.mtype == 'class') {
724
+ var cmdobj = JSON.parse(msgobjclass.message);
725
+ if (cmdobj && cmdobj.cmdtype == 'start') {
726
+ startclassExist = 'true';
727
+ }
728
+ if (cmdobj && cmdobj.cmdtype == 'end') {
729
+ endclassExist = 'true';
730
+ }
731
+ }
732
+ }
733
+ w.controlObj.onKeyMessageSent('startClass', startclassExist);
734
+ w.controlObj.onKeyMessageSent('endClass', endclassExist);
735
+ } //end of if
736
+ } catch (e) {
737
+ ENTRY.recordException(e);
738
+ }
739
+ } //end of if
740
+ });
741
+ } catch (e) {
742
+ ENTRY.recordException(e);
743
+ }
744
+ },
745
+
746
+ //监听消息
747
+ OnUserDefineMsg: function (msg) {
748
+ //进入教室成功
749
+ this.socket.on('join_room', function (obj) {
750
+ CONTROL.dealJoinMsg(obj);
751
+ });
752
+
753
+ //离开教室
754
+ this.socket.on('leave_room', function (obj) {
755
+ CONTROL.dealleaveRoomMsg(obj);
756
+ });
757
+
758
+ //监测网络状态
759
+ this.socket.on('pong', function (time) {
760
+ if (w.controlObj && controlObj.onPong) {
761
+ controlObj.onPong('' + time);
762
+ }
763
+ });
764
+
765
+ //接收流控制消息
766
+ this.socket.on('stream', function (obj) {
767
+ CONTROL.dealStreamMsg(obj, false);
768
+ });
769
+
770
+ this.socket.on('netstate', function (obj) {
771
+ CONTROL.dealNetStateMsg(obj);
772
+ });
773
+
774
+ this.socket.on('award', function (obj) {
775
+ CONTROL.dealAwardMsg(obj); //奖励通知
776
+ });
777
+
778
+ this.socket.on('streamservicetype', function (obj) {
779
+ CONTROL.dealStreamServiceTypeMsg(obj); //切换SDK通知
780
+ });
781
+
782
+ this.socket.on('force_exit', function (obj) {
783
+ //被踢通知
784
+ CONTROL.displayLogMsg('force_exit'); //删掉
785
+ CONTROL.dealForceExit(obj);
786
+ });
787
+
788
+ this.socket.on('room_expired', function (obj) {
789
+ //房间过期
790
+ CONTROL.dealRoomExpired(obj);
791
+ });
792
+
793
+ //接收监课状态消息
794
+ this.socket.on('supervisor', function (obj) {
795
+ CONTROL.dealSupervisorMsg(obj);
796
+ });
797
+
798
+ //收到在线列表消息
799
+ this.socket.on('listeners', function (obj) {
800
+ if (w.onlinemeber && w.onlinemeber.onRecvOnlinMemberData) {
801
+ var objstr = JSON.stringify(obj);
802
+ w.onlinemeber.onRecvOnlinMemberData(objstr);
803
+ }
804
+ });
805
+
806
+ //掉线通知
807
+ this.socket.on('offline', function (obj) {
808
+ CONTROL.dealOfflineMsg(obj);
809
+ CONTROL.isOffline = true;
810
+ //channel_disconnect 信道离线,退出房间
811
+ CONTROL.dealChannelMsg({
812
+ type: 'user_disconnect',
813
+ data: {
814
+ userId: +obj.userid,
815
+ userName: obj.username,
816
+ role: obj.role
817
+ }
818
+ });
819
+ ENTRY.recordLogToFile('info', `sdk notice user_disconnect role: ${obj.role} userId : ${obj.userid} userName: ${obj.username}`);
820
+ ENTRY.recordLogToFile('info', `offline ${JSON.stringify(obj)}`);
821
+ });
822
+
823
+ //收到异常状态消息
824
+ this.socket.on('unusual', function (obj) {
825
+ if (obj && w.controlObj && w.controlObj.onRecvUnusualNOtify) {
826
+ w.controlObj.onRecvUnusualNOtify(JSON.stringify(obj));
827
+ }
828
+ });
829
+
830
+
831
+ //供参考,实测并不完全符合:客户端socket发起连接时的顺序。当第一次连接时,事件触发顺序为:connecting->connect;
832
+ // 当失去连接时,事件触发顺序为:disconnect->reconnecting(可能进行多次)->connecting->reconnect->connect。
833
+ this.socket.on('reconnecting', function () {
834
+ CONTROL.displayLogMsg('control: reconnecting!');
835
+ });
836
+
837
+ //并不会回调这个
838
+ this.socket.on('connecting', function () {
839
+ CONTROL.displayLogMsg('control: connecting!');
840
+ });
841
+
842
+ //监听连接失败
843
+ this.socket.on('connect_failed', function (o) {
844
+ CONTROL.displayLogMsg('control:connectfailed');
845
+ try {
846
+ dataReport.joinRoomResult({
847
+ code: '3',
848
+ cloud_api_response: window.zby_sdk_cloud_data,
849
+ cloud_api_url: `${getApiCloudBaseUrl()}/rtccloud/class/init`,
850
+ chat_url: window.zby_sdk_cloud_data.chatUrl
851
+ });
852
+ } catch (e) {};
853
+ });
854
+
855
+ //目前没发现,什么情况下会回调这个
856
+ this.socket.on('error', function () {
857
+ CONTROL.displayLogMsg('control:soceket错误!');
858
+ });
859
+
860
+ //并不会回调这个:自动重连成功后,会调用connect
861
+ this.socket.on('reconnect', function () {
862
+ CONTROL.displayLogMsg('control:reconnect!');
863
+ });
864
+
865
+ //并不会回调这个
866
+ this.socket.on('reconnect_failed', function () {
867
+ CONTROL.displayLogMsg('control:reconnect_failed!');
868
+ });
869
+ },
870
+
871
+ //处理登录消息
872
+ dealJoinMsg: function (msgobj) {
873
+ if (w.onlinemeber && w.onlinemeber.onRecvMemberStateChange) {
874
+ try {
875
+ var objuser = {};
876
+ objuser.online = 'login';
877
+ objuser.username = msgobj.username;
878
+ objuser.userid = msgobj.userid;
879
+ objuser.role = ENTRY.translateRoleBack(msgobj.role);
880
+ if (msgobj.hasOwnProperty('avatar')) {
881
+ objuser.avatar = msgobj.avatar;
882
+ }
883
+ if (msgobj.hasOwnProperty('device')) {
884
+ objuser.device = msgobj.device;
885
+ }
886
+ var jsonstr = JSON.stringify(objuser);
887
+ w.onlinemeber.onRecvMemberStateChange(jsonstr);
888
+ } catch (e) {
889
+ ENTRY.recordException(e);
890
+ }
891
+ }
892
+
893
+ var logmsg = 'control:收到join_room:' + msgobj.userid;
894
+ ENTRY.recordLogToFile('info', logmsg);
895
+ this.displayLogMsg(logmsg);
896
+
897
+ CONTROL.notifyMembernumChanged(msgobj);
898
+ },
899
+
900
+ //处理退出登录消息
901
+ dealleaveRoomMsg: function (msgobj) {
902
+ try {
903
+ //{'unixtime':'32435435','userid':'username','username':'Falcon','role':'1'}
904
+ var logmsg = 'control:收到leaveRoom_message:';
905
+ logmsg += JSON.stringify(msgobj);
906
+ CONTROL.displayLogMsg(logmsg);
907
+ ENTRY.recordLogToFile('info', logmsg);
908
+
909
+ var isme = ENTRY.isMyMsg(msgobj);
910
+ if (isme) {
911
+ //这个应该不会发生
912
+ ENTRY.recordLogToFile('error', 'receive self leaveroom ack');
913
+ } else {
914
+ if (w.onlinemeber && w.onlinemeber.onRecvMemberStateChange) {
915
+ var objuser = {};
916
+ objuser.online = 'logout';
917
+ objuser.userid = msgobj.userid;
918
+ objuser.role = ENTRY.translateRoleBack(msgobj.role);
919
+ var jsonstr = JSON.stringify(objuser);
920
+ w.onlinemeber.onRecvMemberStateChange(jsonstr);
921
+ }
922
+ }
923
+ } catch (e) {
924
+ ENTRY.recordException(e);
925
+ }
926
+
927
+ CONTROL.notifyMembernumChanged(msgobj);
928
+ },
929
+
930
+ notifyMembernumChanged: function (obj) {
931
+ try {
932
+ //非一对一模式下,需要通知应用层成员数量
933
+ if (obj.hasOwnProperty('onlinecounts')) {
934
+ if (w.controlObj && controlObj.onMemberChanged && ENTRY.isLargeClass()) {
935
+ controlObj.onMemberChanged(obj.onlinecounts);
936
+ }
937
+
938
+ var logmsg = 'control:online count:';
939
+ logmsg += obj.onlinecounts;
940
+ this.displayLogMsg(logmsg);
941
+ }
942
+ } catch (e) {
943
+ ENTRY.recordException(e);
944
+ }
945
+ },
946
+
947
+ //处理断开连接消息
948
+ dealOfflineMsg: function (msgobj) {
949
+ try {
950
+ var logmsg = 'control:收到disconnect_message';
951
+ logmsg += JSON.stringify(msgobj);
952
+ CONTROL.displayLogMsg(logmsg);
953
+ ENTRY.recordLogToFile('info', logmsg);
954
+
955
+ var isme = ENTRY.isMyMsg(msgobj);
956
+ if (!isme) {
957
+ if (w.onlinemeber && w.onlinemeber.onRecvMemberStateChange) {
958
+ var objuser = {};
959
+ objuser.online = 'offline';
960
+ objuser.userid = msgobj.userid;
961
+ objuser.role = ENTRY.translateRoleBack(msgobj.role);
962
+ var jsonstr = JSON.stringify(objuser);
963
+ w.onlinemeber.onRecvMemberStateChange(jsonstr);
964
+ }
965
+
966
+ CONTROL.notifyMembernumChanged(msgobj);
967
+ }
968
+ } catch (e) {
969
+ ENTRY.recordException(e);
970
+ }
971
+ },
972
+
973
+ //处理流控制消息
974
+ dealStreamMsg: function (obj, history) {
975
+ if (!obj) {
976
+ return;
977
+ }
978
+
979
+ if (CONTROL.judgeAlreadyRecv(obj, history)) {
980
+ var logmsg = 'recv repeat msg:' + JSON.stringify(obj);
981
+ ENTRY.recordLogToFile('info', logmsg);
982
+
983
+ CONTROL.displayLogMsg(logmsg); //删除
984
+ return;
985
+ }
986
+
987
+ //如果现在正在请求缓存队列,先缓存收到的正常消息
988
+ if (this.cacheReqSend) {
989
+ obj.history = history;
990
+ if (obj.hasOwnProperty('cache') && obj.cache == 1) {
991
+ this.recvCacheList.push(obj);
992
+
993
+ var logmsg1 = 'recv:cache msg' + JSON.stringify(obj);
994
+ ENTRY.recordLogToFile('info', logmsg1);
995
+ CONTROL.displayLogMsg(logmsg1); //删除
996
+ } else {
997
+ this.recvTmpList.push(obj);
998
+
999
+ var logmsg2 = 'recv:cache normal msg' + JSON.stringify(obj);
1000
+ ENTRY.recordLogToFile('info', logmsg2);
1001
+ CONTROL.displayLogMsg(logmsg2); //删除
1002
+ }
1003
+ return;
1004
+ }
1005
+
1006
+ CONTROL.dealStreamMsgInner(obj, history);
1007
+
1008
+ this.checkToIntException(obj);
1009
+ },
1010
+
1011
+ //消息去重处理
1012
+ judgeAlreadyRecv: function (obj, history) {
1013
+ //缓存队列
1014
+ if (!history && obj.hasOwnProperty('uuid') && obj.uuid != '') {
1015
+ if (this.recvmsgKeys.indexOf(obj.uuid) != -1) {
1016
+ return true;
1017
+ } else {
1018
+ this.recvmsgKeys.push(obj.uuid);
1019
+ var timenow = new Date();
1020
+ this.recvmsgTimes.push(timenow);
1021
+
1022
+ //var logmsg = 'recv msg,time now:'+timenow.getTime();
1023
+ //CONTROL.displayLogMsg(logmsg);
1024
+ }
1025
+
1026
+ CONTROL.reduceRecvMsgList();
1027
+ }
1028
+ return false;
1029
+ },
1030
+
1031
+ //缩减接收消息列表的长度,防止超长
1032
+ reduceRecvMsgList: function () {
1033
+ try {
1034
+ if (this.recvmsgTimes.length < 1000) {
1035
+ return;
1036
+ }
1037
+ var timenow = new Date();
1038
+ var timeex = 3 * 60 * 1000;
1039
+ var index = 0;
1040
+ for (index = 0; index < this.recvmsgTimes.length; ++index) {
1041
+ if ((timenow.getTime() - this.recvmsgTimes[index].getTime()) < timeex) {
1042
+ break;
1043
+ }
1044
+ }
1045
+
1046
+ if (index >= 1) {
1047
+ this.recvmsgTimes.splice(0, index);
1048
+ this.recvmsgKeys.splice(0, index);
1049
+
1050
+ //var logmsg = 'reduce key list: index';
1051
+ //logmsg += index;
1052
+ //logmsg += ',left:';
1053
+ //logmsg += this.recvmsgKeys.length;
1054
+ //CONTROL.displayLogMsg(logmsg);//删除
1055
+ }
1056
+ } catch (e) {
1057
+ ENTRY.recordException(e);
1058
+ }
1059
+ },
1060
+
1061
+ //处理流控制消息
1062
+ dealStreamMsgInner: function (obj, history) {
1063
+ try {
1064
+ ////测试丢消息、保序和时延
1065
+ //if(!history){
1066
+ // this.checkechobacktest(obj);
1067
+ //}
1068
+
1069
+ //var logmsg1 = 'deal stream:'+obj.index + ' '+obj.userid;
1070
+ if (obj.mtype != 'lowquality') {
1071
+ var logmsg1 = 'recv:' + obj.index;
1072
+ logmsg1 += ',msg:';
1073
+ logmsg1 += obj.message;
1074
+ logmsg1 += ',uuid:';
1075
+ logmsg1 += obj.uuid;
1076
+ logmsg1 += ',utime:';
1077
+ logmsg1 += obj.unixtime;
1078
+ ENTRY.recordLogToFile('info', logmsg1);
1079
+ }
1080
+ /*******专用处理信道中流信息相关功能 start ********/
1081
+ if (!history) {
1082
+ const data = JSON.parse(obj.message);
1083
+ // window.zby_sdk_init_params为用户初始化sdk传递的基础参数
1084
+ const baseInfo = {
1085
+ roomId: window.zby_sdk_init_params.roomId,
1086
+ userId: CONTROL.userid,
1087
+ userName: CONTROL.username,
1088
+ institutionId: window.zby_sdk_init_params.institutionId,
1089
+ targetId: data.actorId,
1090
+ role: CONTROL.role === '1' ? 'teacher' : 'student'
1091
+ };
1092
+ dealReceiveStreamMsg(data, baseInfo);
1093
+ }
1094
+ /*******专用处理信道中流信息相关功能 end ********/
1095
+
1096
+
1097
+ if (!history && w.controlObj && controlObj.onReciveStream) {
1098
+ controlObj.onReciveStream(obj.mtype, obj.message);
1099
+ }
1100
+
1101
+ //提示上下课
1102
+ CONTROL.displayClassOperate(obj);
1103
+
1104
+ if (w.CHATEST && w.CHATEST.checkorder == 1) {
1105
+ CONTROL.checkOrder(obj);
1106
+ }
1107
+
1108
+ } catch (e) {
1109
+ ENTRY.recordException(e);
1110
+ }
1111
+ },
1112
+
1113
+ //处理监课消息
1114
+ dealSupervisorMsg: function (obj) {
1115
+ if (!obj) {
1116
+ return;
1117
+ }
1118
+
1119
+ try {
1120
+ if (obj.mtype == 'help_state') {
1121
+ //var message = obj.message;
1122
+ var helpobj = obj.message;
1123
+ if (this.roomid != helpobj.lessonid || this.userid != helpobj.userid) {
1124
+ return;
1125
+ }
1126
+
1127
+ //求助,机构后台处理后,推送此消息,收到后上报客户端
1128
+ if (w.controlObj && w.controlObj.onSupervisorState) {
1129
+ var objformat = {};
1130
+ objformat.mtype = 'help_state';
1131
+ objformat.status = helpobj.supervisorStatus;
1132
+ objformat.resolve = helpobj.supervisorResolve;
1133
+ w.controlObj.onSupervisorState(JSON.stringify(objformat));
1134
+ }
1135
+ }
1136
+ } catch (e) {
1137
+ ENTRY.recordException(e);
1138
+ }
1139
+ },
1140
+
1141
+ //处理网络状态消息
1142
+ dealNetStateMsg: function (obj) {
1143
+ if (obj && w.controlObj && w.controlObj.onReciveLowQualityMsg) {
1144
+ w.controlObj.onReciveLowQualityMsg(obj.mtype, obj.message);
1145
+ }
1146
+ },
1147
+ //处理奖励消息
1148
+ dealAwardMsg: function (obj) {
1149
+ if (obj && w.controlObj && w.controlObj.onServerPushMessage) {
1150
+ w.controlObj.onServerPushMessage('award', JSON.stringify(obj.message));
1151
+ }
1152
+ },
1153
+
1154
+ //处理切换SDK消息
1155
+ dealStreamServiceTypeMsg: function (obj) {
1156
+ console.log('%c接收到信道广播的切换SDK消息,切换到:' + obj.message.data, 'color:blue');
1157
+ ENTRY.recordLogToFile('info', 'channel msg: streamservicetype, change sdk to ' + obj.message.data);
1158
+ const data = obj.message;
1159
+ if (window.current_sdk_type !== data.data) {
1160
+ zbysdk.changeSDK();
1161
+ } else {
1162
+ console.log('%c接收到信道广播目标SDK和本地一致,不切换:' + obj.message.data, 'color:blue');
1163
+ ENTRY.recordLogToFile('info', 'channel target sdk type is the same as the local sdk ,will not change sdk to :' + obj.message.data);
1164
+ }
1165
+ },
1166
+
1167
+ //处理被踢消息
1168
+ dealForceExit: function (obj) {
1169
+ if (ENTRY.istestFromhtml == 1) {
1170
+ CONTROL.displayLogMsg('您已被踢');
1171
+ ENTRY.recordLogToFile('info', 'deal with force exit');
1172
+ CONTROL.leaveRoom();
1173
+ if (w.CHAT && ENTRY.channeltype == 0) {
1174
+ w.CHAT.leaveRoom();
1175
+ }
1176
+ }
1177
+
1178
+ if (w.controlObj && w.controlObj.onServerPushMessage) {
1179
+ w.controlObj.onServerPushMessage('force_exit', '');
1180
+ }
1181
+ },
1182
+
1183
+ //处理房间过期消息
1184
+ dealRoomExpired: function (obj) {
1185
+ if (w.controlObj && w.controlObj.onServerPushMessage) {
1186
+ w.controlObj.onServerPushMessage('room_expired', '');
1187
+ }
1188
+ },
1189
+
1190
+ //处理断线后重连
1191
+ dealReconnectSuccess: function () {
1192
+ ENTRY.recordLogToFile('info', 'deal reconnect success');
1193
+ CONTROL.displayLogMsg('deal reconnect success'); //删掉
1194
+ CONTROL.resendMessages();
1195
+ CONTROL.requestCachedMsg();
1196
+ },
1197
+
1198
+ //断线重连后,请求缓存队列
1199
+ requestCachedMsg: function () {
1200
+ var uuid = '';
1201
+ if (this.recvmsgKeys.length > 0) {
1202
+ uuid = this.recvmsgKeys[this.recvmsgKeys.length - 1];
1203
+ }
1204
+ this.cacheReqSend = true;
1205
+ var obj = {};
1206
+ obj.uuid = uuid;
1207
+ var logmsg = 'requestCachedMsg:' + obj.uuid;
1208
+ CONTROL.displayLogMsg(logmsg); //删除
1209
+ ENTRY.recordLogToFile('info', logmsg);
1210
+ this.socket.emit('cache_message', obj, function (para) {
1211
+ logmsg = 'requestCachedMsg: ack ' + para.code;
1212
+ CONTROL.displayLogMsg(logmsg); //删除
1213
+ ENTRY.recordLogToFile('info', logmsg);
1214
+
1215
+ CONTROL.cacheReqSend = false;
1216
+ if (para.code == 0) {
1217
+ CONTROL.dealRecvCache();
1218
+ } else {
1219
+ ENTRY.recordLogToFile('error', 'request cache msg ret failed!');
1220
+ }
1221
+ });
1222
+ },
1223
+
1224
+ //处理缓存的收到但未处理的消息
1225
+ dealRecvCache: function () {
1226
+ var reportobj = {};
1227
+ reportobj.count = this.recvCacheList.length;
1228
+ for (var i = 0; i < this.recvCacheList.length; ++i) {
1229
+ CONTROL.dealStreamMsgInner(this.recvCacheList[i], this.recvCacheList[i].history);
1230
+ }
1231
+ ENTRY.recordLogToFile('info', 'dealRecvCache:server cached num:' + this.recvCacheList.length);
1232
+ this.recvCacheList.length = 0;
1233
+
1234
+ for (var j = 0; j < this.recvTmpList.length; ++j) {
1235
+ CONTROL.dealStreamMsgInner(this.recvTmpList[j], false);
1236
+ }
1237
+ ENTRY.recordLogToFile('info', 'dealRecvCache:local cached num:' + this.recvTmpList.length);
1238
+ this.recvTmpList.length = 0;
1239
+
1240
+ //上报积压消息情况
1241
+ if (w.controlObj && w.controlObj.onSelfHealthReport) {
1242
+ w.controlObj.onSelfHealthReport('servercachedcount', JSON.stringify(reportobj));
1243
+ }
1244
+ },
1245
+
1246
+ //保序验证
1247
+ checkOrder: function (obj) {
1248
+ //CONTROL.displayLogMsg('recv:'+obj.index);
1249
+ if (CONTROL.lastRecvMsgId == null) {
1250
+ CONTROL.lastRecvMsgId = new Array();
1251
+ }
1252
+
1253
+ ++CONTROL.testrecvcount;
1254
+ var curtime = new Date();
1255
+ CONTROL.displayLogMsg('recv:' + curtime.toTimeString() + ',' + CONTROL.testrecvcount);
1256
+
1257
+ var userFind = false;
1258
+ for (var i = 0; i < CONTROL.lastRecvMsgId.length; ++i) {
1259
+ if (CONTROL.lastRecvMsgId[i].userid == obj.userid) {
1260
+ userFind = true;
1261
+ if (CONTROL.lastRecvMsgId[i].index > obj.index) {
1262
+ CONTROL.displayLogMsg('control msg disorder,userid:' + obj.userid + ',' + obj.index);
1263
+
1264
+ if (w.CHATEST) {
1265
+ w.CHATEST.setOrderCheckResult('message disorder');
1266
+ }
1267
+ }
1268
+ if (CONTROL.lastRecvMsgId[i].index + 1 != obj.index) {
1269
+ CONTROL.displayLogMsg('control msg lost,userid:' + obj.userid + ',' + CONTROL.lastRecvMsgId[i].index + ' to ' + obj.index);
1270
+ if (w.CHATEST) {
1271
+ w.CHATEST.setOrderCheckResult('message lost');
1272
+ }
1273
+ }
1274
+
1275
+ if (obj.index % 30 == 0) {
1276
+ CONTROL.displayLogMsg('recv,useri:' + obj.userid + ',' + obj.index);
1277
+ }
1278
+
1279
+ CONTROL.lastRecvMsgId[i].index = obj.index;
1280
+ break;
1281
+ }
1282
+ }
1283
+ if (!userFind) {
1284
+ var tmpobj = {};
1285
+ tmpobj.index = obj.index;
1286
+ tmpobj.userid = obj.userid;
1287
+ CONTROL.lastRecvMsgId.push(tmpobj);
1288
+ }
1289
+ },
1290
+
1291
+ //初始化缓存队列相关
1292
+ initCacheList: function () {
1293
+ try {
1294
+ this.streamIndex = 0;
1295
+ this.normalMsgIndex = 0;
1296
+ if (!this.sendCheckList) {
1297
+ this.sendCheckList = new Array();
1298
+ } else {
1299
+ this.sendCheckList.length = 0;
1300
+ }
1301
+ if (!this.sendCacheList) {
1302
+ this.sendCacheList = new Array();
1303
+ } else {
1304
+ this.sendCacheList.length = 0;
1305
+ }
1306
+ this.cacheReqSend = false;
1307
+ if (!this.recvCacheList) {
1308
+ this.recvCacheList = new Array();
1309
+ } else {
1310
+ this.recvCacheList.length = 0;
1311
+ }
1312
+ if (!this.recvTmpList) {
1313
+ this.recvTmpList = new Array();
1314
+ } else {
1315
+ this.recvTmpList.length = 0;
1316
+ }
1317
+ if (!this.recvmsgKeys) {
1318
+ this.recvmsgKeys = new Array();
1319
+ } else {
1320
+ this.recvmsgKeys.length = 0;
1321
+ }
1322
+ if (!this.recvmsgTimes) {
1323
+ this.recvmsgTimes = new Array();
1324
+ } else {
1325
+ this.recvmsgTimes.length = 0;
1326
+ }
1327
+ if (!this.orderCheck) {
1328
+ this.orderCheck = new Array();
1329
+ } else {
1330
+ this.orderCheck.length = 0;
1331
+ }
1332
+ if (!this.delaycheckList) {
1333
+ this.delaycheckList = new Array();
1334
+ } else {
1335
+ this.delaycheckList.length = 0;
1336
+ }
1337
+ if (!this.delayList) {
1338
+ this.delayList = new Array();
1339
+ } else {
1340
+ this.delayList.length = 0;
1341
+ }
1342
+ this.checkSendSucessTimer = w.setInterval(this.checkStreamMsgSendSuccess, this.checkInterval);
1343
+ } catch (e) {
1344
+ ENTRY.recordException(e);
1345
+ }
1346
+ },
1347
+
1348
+ //反初始化缓存队列相关
1349
+ unInitCacheList: function () {
1350
+ this.streamIndex = 0;
1351
+ this.normalMsgIndex = 0;
1352
+ this.sendCacheList = null;
1353
+ this.cacheReqSend = false;
1354
+ this.recvCacheList = null;
1355
+ this.recvTmpList = null;
1356
+ this.recvmsgKeys = null;
1357
+ this.recvmsgTimes = null;
1358
+ this.orderCheck = null;
1359
+ this.delaycheckList = null;
1360
+ this.delayList = null;
1361
+ if (this.checkSendSucessTimer) {
1362
+ w.clearInterval(this.checkSendSucessTimer);
1363
+ this.checkSendSucessTimer = null;
1364
+ }
1365
+ this.sendCheckList = null;
1366
+ },
1367
+
1368
+ //缓存要发送的消息
1369
+ cachedSendMsg: function (obj) {
1370
+ try {
1371
+ this.sendCacheList.push(obj);
1372
+ } catch (e) {
1373
+ ENTRY.recordException(e);
1374
+ }
1375
+ },
1376
+
1377
+ //添加到确认队列
1378
+ addToCheckList: function (obj) {
1379
+ try {
1380
+ var checkobj = {};
1381
+ checkobj.data = obj;
1382
+ checkobj.time = new Date();
1383
+ checkobj.success = false;
1384
+ this.sendCheckList.push(checkobj);
1385
+ } catch (e) {
1386
+ ENTRY.recordException(e);
1387
+ }
1388
+ },
1389
+
1390
+ //收到确认
1391
+ setSendSuccess: function (obj) {
1392
+ try {
1393
+ for (var i = 0; i < CONTROL.sendCheckList.length; ++i) {
1394
+ if (CONTROL.sendCheckList[i].data.index == obj.index) {
1395
+ CONTROL.sendCheckList[i].success = true;
1396
+ break;
1397
+ }
1398
+ }
1399
+
1400
+ //缓存队列:清理
1401
+ var length = CONTROL.sendCheckList.length;
1402
+ while (length > 0 && CONTROL.sendCheckList[0].success) {
1403
+ CONTROL.sendCheckList.splice(0, 1);
1404
+ length = CONTROL.sendCheckList.length;
1405
+ }
1406
+ } catch (e) {
1407
+ ENTRY.recordException(e);
1408
+ }
1409
+ },
1410
+
1411
+ //检查消息是否发送成功
1412
+ checkStreamMsgSendSuccess: function () {
1413
+ try {
1414
+ var length = CONTROL.sendCheckList.length;
1415
+ if (length > 0 && this.isInRoom) {
1416
+ var curtime = new Date();
1417
+ if (curtime.getTime() - CONTROL.sendCheckList[length - 1].time.getTime() > CONTROL.maxAckDelay) {
1418
+ CONTROL.resendMessages();
1419
+
1420
+ ////todo 缓存队列过长的话,断开重新连接
1421
+ if (length > 200) {
1422
+ var logmsg01 = 'check message to much:' + length;
1423
+ ENTRY.recordLogToFile('error', logmsg01);
1424
+ }
1425
+
1426
+ var logmsg = 'resend messages withou ack:' + length;
1427
+ ENTRY.recordLogToFile('info', logmsg);
1428
+ CONTROL.displayLogMsg(logmsg); //删掉
1429
+ ENTRY.reportHintInfo(logmsg);
1430
+ }
1431
+ }
1432
+ } catch (e) {
1433
+ ENTRY.recordException(e);
1434
+ }
1435
+ },
1436
+
1437
+ //重新发送缓存的消息
1438
+ resendMessages: function () {
1439
+ try {
1440
+ var reportobj = {};
1441
+ var length = CONTROL.sendCheckList.length;
1442
+ reportobj.unconfirmcount = length;
1443
+ if (length > 0) {
1444
+ var sendlist = CONTROL.sendCheckList.slice(0);
1445
+ CONTROL.sendCheckList.length = 0;
1446
+ for (var i = 0; i < sendlist.length; ++i) {
1447
+ this.sendStreamMsgInner(sendlist[i].data);
1448
+ }
1449
+ }
1450
+
1451
+ var cachedlenth = this.sendCacheList.length;
1452
+ reportobj.count = length + this.sendCacheList.length;
1453
+ for (var i = 0; i < this.sendCacheList.length; ++i) {
1454
+ this.sendStreamMsgInner(this.sendCacheList[i]);
1455
+ }
1456
+ this.sendCacheList.length = 0;
1457
+
1458
+ //上报积压消息情况
1459
+ if (w.controlObj && w.controlObj.onSelfHealthReport) {
1460
+ w.controlObj.onSelfHealthReport('resendcount', JSON.stringify(reportobj));
1461
+ }
1462
+
1463
+ var logmsg = 'resent message,checklist:';
1464
+ logmsg += length;
1465
+ logmsg += ',cached:';
1466
+ logmsg += cachedlenth;
1467
+ ENTRY.recordLogToFile('info', logmsg);
1468
+ CONTROL.displayLogMsg(logmsg); //删掉
1469
+ } catch (e) {
1470
+ ENTRY.recordException(e);
1471
+ }
1472
+ },
1473
+
1474
+ //显示开始上课/结束上课消息
1475
+ displayClassOperate: function (msgobj) {
1476
+ try {
1477
+ if (msgobj.mtype == 'class') {
1478
+ var classobj = JSON.parse(msgobj.message);
1479
+ if (!msgobj.hasOwnProperty('unixtime')) {
1480
+ return;
1481
+ }
1482
+
1483
+ //只用control通道的话,需要通知chat通道去显示,否则直接在聊天页面显示
1484
+ if (ENTRY.channeltype == 1) {
1485
+ if (w.controlObj && w.controlObj.onDisplayClassOperate) {
1486
+ w.controlObj.onDisplayClassOperate(classobj.cmdtype, msgobj.unixtime);
1487
+ }
1488
+ } else {
1489
+ if (w.CHATDIS) {
1490
+ w.CHATDIS.disClassStatusHint(classobj.cmdtype, msgobj.unixtime);
1491
+ }
1492
+ }
1493
+
1494
+ } //end of if
1495
+ } catch (e) {
1496
+ ENTRY.recordException(e);
1497
+ }
1498
+ },
1499
+
1500
+ //检查异常
1501
+ checkToIntException: function (obj) {
1502
+ try {
1503
+ var uttime = obj.unixtime.substr(0, obj.unixtime.length - 3);
1504
+ var timeint = parseInt(uttime); //todo 检查到底怎么回事
1505
+ var timeint = ENTRY.parseIntMySimple(uttime);
1506
+ if (!(timeint.toString() == uttime)) {
1507
+ ENTRY.recordLogToFile('error', 'parseint error');
1508
+ CONTROL.displayLogMsg('parseint error'); //删掉
1509
+ }
1510
+ } catch (e) {}
1511
+ },
1512
+
1513
+ //发送流控制消息 string string string string
1514
+ sendStreamMsgTest: function (subtype, content, targetid, save) {
1515
+ //subtype : stream / class(save)
1516
+ var curtime = new Date();
1517
+ var obj = {};
1518
+ obj.index = this.streamIndex++; //int
1519
+ obj.uuid = ENTRY.getMsgKey(obj.index); //string
1520
+ obj.mtype = subtype; //消息子类型
1521
+ obj.targetid = targetid;
1522
+ obj.message = content;
1523
+ obj.save = save;
1524
+ obj.echotest = 1;
1525
+ obj.sendtime = curtime.getTime();
1526
+ obj.checkindex = obj.index;
1527
+
1528
+ var objtest = {};
1529
+ objtest.checkindex = obj.index;
1530
+ objtest.sendtime = obj.sendtime;
1531
+ this.delaycheckList.push(objtest);
1532
+
1533
+ if (this.isInRoom) {
1534
+ this.sendStreamMsgInner(obj);
1535
+ } else {
1536
+ this.cachedSendMsg(obj);
1537
+ }
1538
+ },
1539
+
1540
+ checkechobacktest: function (obj) {
1541
+ //subtype : stream / class(save)
1542
+ var curtime = new Date();
1543
+ var index = 0;
1544
+ if (!obj.hasOwnProperty('echotest')) {
1545
+ return;
1546
+ }
1547
+
1548
+
1549
+ for (index = 0; index < this.delaycheckList.length; ++index) {
1550
+ if (obj.checkindex > this.delaycheckList[index].checkindex) {
1551
+ break;
1552
+ }
1553
+
1554
+ if (obj.checkindex == this.delaycheckList[index].checkindex) {
1555
+ ;
1556
+ }
1557
+ }
1558
+ },
1559
+ getPingPongArr: function () {
1560
+ setTimeout(function () {
1561
+ CONTROL.pingPongArr = [];
1562
+ }, 1);
1563
+ return CONTROL.pingPongArr;
1564
+ }
1565
+ };
1566
+
1567
+ export default CONTROL;
1568
+ // })();