李勇

1.新增MCU断线重连、MCU动态选点的功能(断线重连3次,间隔5秒);2.MS动态选点功能(在开始上课状态下每15秒动态获取一次MS);3.动态选点的两个接口(MS,MCU)

此 diff 太大无法显示。
... ... @@ -27,7 +27,7 @@ import Server from "config/Server";
import UTF8 from 'utf-8';
let loger = Loger.getLoger('McuClient');
let _sdkInfo = {"version": "v1.9.14.20170420", "author": "www.3mang.com"};
let _sdkInfo = {"version": "v1.9.15.20170420", "author": "www.3mang.com"};
//APE
let _sass;
... ... @@ -78,7 +78,7 @@ export default class MessageEntrance extends Emiter {
_mcu = Mcu;
_mcu.on('*', (type, data) => this._emit(type, data));
_mcu.on(MessageTypes.CLASS_JOIN_MCU_SUCCESS, this._mcuJoinMCUClassSuccessHandler.bind(this));//加入MCU课堂完成
_mcu.on(MessageTypes.CHANGE_MCU_IP, this._changeMcuIpHandler.bind(this));//切换MCU,重新选点
_mcu.on(MessageTypes.SWITCH_MCU_IP, this._switchMcuIpHandler.bind(this));//切换MCU,重新选点
//录制回放
_recordPlayback = RecordPlayBackParse;
... ... @@ -96,6 +96,8 @@ export default class MessageEntrance extends Emiter {
_confer_ape.on(MessageTypes.CLASS_NONENTITY_ROSTER, this._onClassNonentityRoster.bind(this));//当前课堂中视频或音频占用channel的nodeId ,在人员列表中不存在
_confer_ape.on(MessageTypes.CLASS_RECORD_START, this._onClassRecordStart.bind(this));//课堂开始录制
_confer_ape.on(MessageTypes.CLASS_RECORD_SUCCESS, this._onClassRecordSuccess.bind(this));//课堂开启录制成功
_confer_ape.on(MessageTypes.SWITCH_MS_IP, this._switchMsIpHandler.bind(this));//MS动态选点
_chat_ape = new ChatApe();
_chat_ape.on('*', (type, data) => this._emit(type, data));
... ... @@ -149,7 +151,6 @@ export default class MessageEntrance extends Emiter {
this.stopPublishVideo = this.unPublishVideo = this._stopPublishVideo.bind(this);
this.sendVideoBroadcastMsg = this._sendVideoBroadcastMsg.bind(this);
//audioApe
//this.getAudioPlayPath = this._getPlayAudioPath.bind(this);
this.getAudioPublishPath = this._getPublishAudioPath.bind(this);
... ... @@ -180,8 +181,10 @@ export default class MessageEntrance extends Emiter {
this.getDocFullAddress = this._getDocFullAddress.bind(this);//获取文档资源地址
this.setDebuger = this._setDebuger.bind(this);//debug
//this.setDebuger = this._setDebuger.bind(this);//debug
this.setMessageDelay = this._setMessageDelay.bind(this);//设置是否延迟消息
this.switchServer = this._switchMcuIpHandler.bind(this);//切换mcu服务器
this.switchMediaServer = this._switchMsIpHandler.bind(this);//切换ms服务器
}
_setDebuger(_data) {
... ... @@ -291,7 +294,7 @@ export default class MessageEntrance extends Emiter {
//{"classId":"1653304953","portal":"112.126.80.182:80","userRole":"normal","userId":0}
//判断传入的参数是否存在
if (_param == null || EngineUtils.isEmptyObject(_param)) {
loger.error('初始化课堂失败->参数错误',_param);
loger.error('初始化课堂失败->参数错误', _param);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_INIT_PARAM);
return;
}
... ... @@ -453,7 +456,7 @@ export default class MessageEntrance extends Emiter {
let index = parseInt(Math.random() * _data.mcuList.length);
GlobalConfig.MCUServerIP = _data.mcuList[index].ip || "";
GlobalConfig.MCUServerPort = _data.mcuList[index].port || "";
loger.log('初始->MCU->.', GlobalConfig.MCUServerIP , GlobalConfig.MCUServerPort );
loger.log('初始->MCU->.', GlobalConfig.MCUServerIP, GlobalConfig.MCUServerPort);
}
//上课中视频推流播流地址
... ... @@ -465,7 +468,7 @@ export default class MessageEntrance extends Emiter {
let index = parseInt(Math.random() * _data.msList.length);
GlobalConfig.MSServerIP = _data.msList[index].ip || "";
GlobalConfig.MSServerPort = _data.msList[index].port || "";
loger.log('初始->MS->.', GlobalConfig.MSServerIP , GlobalConfig.MSServerPort );
loger.log('初始->MS->.', GlobalConfig.MSServerIP, GlobalConfig.MSServerPort);
}
//录制回放时m3u8播流地址
... ... @@ -474,10 +477,10 @@ export default class MessageEntrance extends Emiter {
//GlobalConfig.RSServerIP = _data.rsList[0].ip || "";
//GlobalConfig.RSServerPort = _data.rsList[0].port || "";
let index = parseInt(Math.random() * _data.msList.length);
let index = parseInt(Math.random() * _data.rsList.length);
GlobalConfig.RSServerIP = _data.rsList[index].ip || "";
GlobalConfig.RSServerPort = _data.rsList[index].port || "";
loger.log('初始->RS->.', GlobalConfig.RSServerIP , GlobalConfig.RSServerPort );
loger.log('初始->RS->.', GlobalConfig.RSServerIP, GlobalConfig.RSServerPort);
}
//文档地址
... ... @@ -487,7 +490,7 @@ export default class MessageEntrance extends Emiter {
loger.log("docServer->", _data.docList[index]);
GlobalConfig.DOCServerIP = _data.docList[index].ip || "";
GlobalConfig.DOCServerPort = _data.docList[index].port || "";
loger.log('初始->DOC->.', GlobalConfig.DOCServerIP , GlobalConfig.DOCServerPort );
loger.log('初始->DOC->.', GlobalConfig.DOCServerIP, GlobalConfig.DOCServerPort);
}
//record
... ... @@ -499,7 +502,7 @@ export default class MessageEntrance extends Emiter {
let index = parseInt(Math.random() * _data.recordList.length);
GlobalConfig.RecordServerIP = _data.recordList[index].ip || "";
GlobalConfig.RecordServerPort = _data.recordList[index].port || "";
loger.log('初始->RECORD->.', GlobalConfig.RecordServerIP , GlobalConfig.RecordServerPort );
loger.log('初始->RECORD->.', GlobalConfig.RecordServerIP, GlobalConfig.RecordServerPort);
}
}
... ... @@ -562,8 +565,8 @@ export default class MessageEntrance extends Emiter {
this._getFastestMsServer(function (_data) {
loger.log("MS选点结束->", _data);
if (_data && _data.ip) {
GlobalConfig.MSServerIP = _data.ip||"";
GlobalConfig.MSServerPort = _data.port||"";
GlobalConfig.MSServerIP = _data.ip || "";
GlobalConfig.MSServerPort = _data.port || "";
}
loger.log("当前使用的MS->", GlobalConfig.MSServerIP, GlobalConfig.MSServerPort);
_this.isGetFastestMcuCallback = true;
... ... @@ -572,8 +575,8 @@ export default class MessageEntrance extends Emiter {
this._getFastestMcuServer(function (_data) {
loger.log("MCU选点结束->", _data);
if (_data && _data.ip) {
GlobalConfig.MCUServerIP = _data.ip||"";
GlobalConfig.MCUServerPort = _data.port||"";
GlobalConfig.MCUServerIP = _data.ip || "";
GlobalConfig.MCUServerPort = _data.port || "";
}
loger.log("当前使用的MCU->", GlobalConfig.MCUServerIP, GlobalConfig.MCUServerPort);
_this.isGetFastestMsCallback = true;
... ... @@ -682,6 +685,13 @@ export default class MessageEntrance extends Emiter {
}
}
_switchMcuIp() {
loger.log('切换MCU IP->.');
if (_mcu) {
_mcu.switchMCUIp(GlobalConfig.getClassInfo());
}
}
// MCU 课堂成功
_mcuJoinMCUClassSuccessHandler(_data) {
//loger.log('MCU 课堂成功.');
... ... @@ -745,19 +755,22 @@ export default class MessageEntrance extends Emiter {
this._emit(MessageTypes.CLASS_JOIN_SUCCESS, joinClassSuccessCallBackData);
}
//切换MCU
_changeMcuIpHandler() {
//切换MCU ->_param->{reConnect:false} //reConnect(是否立即替换当前的ip并且重新连接)
_switchMcuIpHandler(_param) {
if (GlobalConfig.isRecordPlayBack) {
//录制回放不做操作
loger.log('录制回放->不进行MCU动态选点');
return;
}
loger.log('MCU->动态选点');
let _this = this;
this._getFastestMcuServer(function (_data) {
loger.log("MCU选点结束->", _data);
//记录当前的IP地址,选点结束后需要判断一下是否是新的IP;
let oldIp= GlobalConfig.MCUServerIP;
if (_data && _data.ip) {
GlobalConfig.MCUServerIP = _data.ip||"";
GlobalConfig.MCUServerPort = _data.port||"";
GlobalConfig.MCUServerIP = _data.ip || "";
GlobalConfig.MCUServerPort = _data.port || "";
} else {
//随机选择一个
if (GlobalConfig.mcuList && GlobalConfig.mcuList.length > 0) {
... ... @@ -766,23 +779,40 @@ export default class MessageEntrance extends Emiter {
GlobalConfig.MCUServerPort = GlobalConfig.mcuList[index].port || "";
}
}
loger.log('MCU->切换->', GlobalConfig.MCUServerIP, GlobalConfig.MCUServerPort);
if(oldIp&&oldIp!=GlobalConfig.MCUServerIP){
loger.log('MCU->最新地址->', GlobalConfig.MCUServerIP, GlobalConfig.MCUServerPort);
//判断是否需要主动断开当前的连接然后重连新的服务器
if (_param && _param.reConnect == true) {
loger.log('MCU->切换到最新的IP->', GlobalConfig.MCUServerIP, GlobalConfig.MCUServerPort);
_this._startConnectMCU();
}else {
//不需要断开当前的连接,更改ip即可
_this._switchMcuIp();
}
}else {
//如果选点结束后获得的ip和当前的IP相同,不需要切换
loger.log('MCU不需要切换->之前的IP->',oldIp,"新的IP->",GlobalConfig.MCUServerIP);
}
});
}
//切换MS
_changeMsIpHandler() {
//切换MS ->_param->{reConnect:false} //reConnect(是否立即替换当前的ip并且重新连接)
_switchMsIpHandler(_param) {
if (GlobalConfig.isRecordPlayBack) {
//录制回放不做操作
loger.log('录制回放->不进行MS动态选点');
return;
}
loger.log('MS->动态选点');
let _this = this;
this._getFastestMsServer(function (_data) {
loger.log("MS选点结束->", _data);
//记录当前的IP地址,选点结束后需要判断一下是否是新的IP;
let oldIp= GlobalConfig.MCUServerIP;
if (_data && _data.ip) {
GlobalConfig.MSServerIP = _data.ip||"";
GlobalConfig.MSServerPort = _data.port||"";
GlobalConfig.MSServerIP = _data.ip || "";
GlobalConfig.MSServerPort = _data.port || "";
} else {
//随机选择一个
if (GlobalConfig.msList && GlobalConfig.msList.length > 0) {
... ... @@ -791,7 +821,20 @@ export default class MessageEntrance extends Emiter {
GlobalConfig.MSServerPort = GlobalConfig.msList[index].port || "";
}
}
loger.log('MS->切换->', GlobalConfig.MSServerIP, GlobalConfig.MSServerPort);
if(oldIp&&oldIp!=GlobalConfig.MSServerIP){
/* loger.log('MS->切换地址->', GlobalConfig.MSServerIP, GlobalConfig.MSServerPort);
//判断是否需要断开当前的连接重连新的服务器
if (_param && _param.reConnect == true) {
loger.log('MS->最新地址->', GlobalConfig.MSServerIP, GlobalConfig.MSServerPort);
}*/
loger.log('MS->最新地址->', GlobalConfig.MSServerIP, GlobalConfig.MSServerPort);
}else {
//如果选点结束后获得的ip和当前的IP相同,不需要切换
loger.log('MS不需要切换->IP',GlobalConfig.MSServerIP);
}
});
}
... ...
... ... @@ -27,6 +27,7 @@ class EverSocket extends Emiter {
}
begin(ip, port) {
this._clearHistory();
loger.log('开始WebSocket应用.');
this._enableEverSocket = true;
this.wsURL = 'ws://' + ip + ':' + port;
... ... @@ -37,7 +38,9 @@ class EverSocket extends Emiter {
loger.log('停止WebSocket应用.');
this._clear();
}
switchSocketIp(ip,port) {
this.wsURL = 'ws://' + ip + ':' + port;
}
get connected() {
return this._connected;
}
... ... @@ -45,7 +48,7 @@ class EverSocket extends Emiter {
send(data) {
if (this._connected) {
if (data) {
loger.log('SEND MESSAGE,byteLength---->', data.byteLength);
loger.log('SEND MESSAGE-->byteLength->', data.byteLength);
} else {
loger.log('SEND MESSAGE---->');
}
... ... @@ -91,7 +94,6 @@ class EverSocket extends Emiter {
}
_clear() {
//this._emit(EverSocket.CLOSED);
loger.log('WebSocket,Timers销毁');
window.clearInterval(this.pingTimer);
window.clearInterval(this.pongTimer);
... ... @@ -114,7 +116,29 @@ class EverSocket extends Emiter {
this.websocket = undefined;
}
_clearHistory(){
loger.log('WebSocket->清除记录');
window.clearInterval(this.pingTimer);
window.clearInterval(this.pongTimer);
window.clearInterval(this.reConnectionTimeout);
//this._setConnected(false);//先设置状态
this._connected = false;
this._enableEverSocket = false;
if (this.websocket == null) {
loger.log('WebSocket->已经销毁');
return;
}
this.websocket.onopen = undefined;
this.websocket.onclose = undefined;
this.websocket.onerror = undefined;
this.websocket.onmessage = undefined;
try {
this.websocket.close();
} catch (e) {
loger.log('ignore errors');
}
this.websocket = undefined;
}
_onOpen() {
loger.log('WebSocket建立成功', this.wsURL);
this.reConnectionCounter = 0;
... ... @@ -138,9 +162,9 @@ class EverSocket extends Emiter {
}
_onMessage(messageEvent) {
loger.log('<----RECEIVE MESSAGE');
this._lastActiveTime = Date.now();
const bufferData = messageEvent.data;
loger.log('RECEIVE MESSAGE-->byteLength->',bufferData.byteLength);
if (bufferData.byteLength > 0) {
this._emit(EverSocket.MESSAGE, bufferData);
}
... ... @@ -179,7 +203,7 @@ class EverSocket extends Emiter {
//目前客户端发送心跳请求的空数据,服务端不会每次都回,暂定为10秒心跳一次
EverSocket.prototype.PONG_INTERVAL = EverSocket.PONG_INTERVAL = 21000;//
EverSocket.prototype.PING_INTERVAL = EverSocket.PING_INTERVAL = 10000;//心跳间隔
EverSocket.prototype.RECONN_INTERVAL = EverSocket.RECONN_INTERVAL = 3000;//重连的间隔
EverSocket.prototype.RECONN_INTERVAL = EverSocket.RECONN_INTERVAL = 5000;//重连的间隔
EverSocket.prototype.ERR_SOCKET_RECONNECT_FAILED =EverSocket.ERR_SOCKET_RECONNECT_FAILED=20001;//MCU自动重连失败,已经达到最大重连次数
... ...
... ... @@ -313,6 +313,7 @@ GlobalConfig.recordReplaytickValues={}; // 滚动条关键点,用于快进快
GlobalConfig.isAutoStartClass=0;//是否自动开始上课 0-否 ;1 是
GlobalConfig.updateClassInfoDelay=30;//(秒),每隔30秒同步一次课堂状态的并保存到Sass
GlobalConfig.msDynamicChooseIpDelay=15;//(秒)MS动态选点的间隔
//GlobalConfig.serverTimestamp=0;//当前的系统时间戳 用get set 获取
... ...
... ... @@ -50,8 +50,6 @@ MessageTypes.AUDIO_BROADCAST= "audio_broadcast";//'audio.broadcast';
MessageTypes.AUDIO_GET_PUBLISH_PATH= "audio_get_publish_path";//获取音频推流地址
MessageTypes.AUDIO_PUBLISH_RESULT= "audio_publish_result";//获取音频推流结果
MessageTypes.CHANGE_MS_IP ="change_ms_ip";//切换ms 重新选点
//文档模块事件定义
MessageTypes.DOC_DELETE="document_delete";//'document.delete';//删除文档
... ... @@ -72,8 +70,10 @@ MessageTypes.WHITEBOARD_ANNOTATION_UPDATE ="whiteboard_annotation_update";// 'wh
//MessageTypes.WHITEBOARD_ANNOTATION_CLEAR = 'whiteboard.annotation.clear';
//MCU
MessageTypes.CHANGE_MCU_IP ="change_mcu_ip";//切换mcu 重新选点
//MCU MS
MessageTypes.SWITCH_MCU_IP ="switch_mcu_ip";//切换mcu 重新选点
MessageTypes.SWITCH_MS_IP ="switch_ms_ip";//切换ms 重新选点
//录制回放
... ...
... ... @@ -23,19 +23,6 @@ class ConferApe extends Ape {
ApeConsts.CONFERENCE_SESSION_NAME,
ApeConsts.CONFERENCE_SESSION_TAG
);
/*
// Attribures
this.hostNodeId = -1;//主持人的nodeId
// 用户的身份,5种类型:
// host(主持人/老师)
// presenter(主讲人)
// assistant(助教)
// normal(普通角色/学生)
// record(暂时没用.
// 默认值: normal
this.hostUserId = '';//主持人的 第三方userId
*/
this.rosters = {};//用户列表
this.timerCounter = new TimerCounter();//计时器
... ... @@ -402,14 +389,21 @@ class ConferApe extends Ape {
//开启计时器
startTimerCounter() {
this.stopTimerCounter();
if(this.timerCounter){
this.timerCounter.startTimer();
}
}
//停止计时器
stopTimerCounter() {
if(this.timerCounter){
this.timerCounter.stopTimer();
}
}
timerCounterUptate() {
if (!this.mcu.connected) {
loger.warn('MCU 连接已经断开');
... ... @@ -429,6 +423,7 @@ class ConferApe extends Ape {
//loger.log('课堂进行时间',GlobalConfig.classTimestamp);
this._emit(MessageTypes.CLASS_UPDATE_TIMER, {"classTimestamp": GlobalConfig.classTimestamp});
if (GlobalConfig.classTimestamp % GlobalConfig.updateClassInfoDelay == 0) {
//如果是host身份,需要同步时间给其他人,同时把当前的状态上传到服务器
if (GlobalConfig.isHost) {
... ... @@ -439,6 +434,11 @@ class ConferApe extends Ape {
this.sendUpdaterClassStatusInfo({"actionType": 1});
}
}
//进行MS动态选点,选择最快的MS服务器地址(录制回放不做处理)
if (!GlobalConfig.isRecordPlayBack&&GlobalConfig.classTimestamp % GlobalConfig.msDynamicChooseIpDelay == 0) {
this._emit(MessageTypes.SWITCH_MS_IP);
}
}
tableUpdateHandler(owner, itemIdx, itemData) {
... ...
... ... @@ -24,7 +24,7 @@ class MCU extends Emiter {
this._everSocket.on(everSocket.OPEN, this._everSocketOpenHandler.bind(this));
this._everSocket.on(everSocket.MESSAGE, this._everSocketMsgReceivedHandler.bind(this));
this._everSocket.on(everSocket.CLOSED, this._everSocketCloseHandler.bind(this));
this._everSocket.on(everSocket.ERROR,this._everSocketErrorHandler.bind(this));
this._everSocket.on(everSocket.ERROR, this._everSocketErrorHandler.bind(this));
}
// 注册Ape
... ... @@ -42,12 +42,13 @@ class MCU extends Emiter {
GlobalConfig.setCurrentStatus(GlobalConfig.statusCode_3);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_SOCKET_DISCONNECT);
}
//EverSocket错误异常
_everSocketErrorHandler(_errorCode){
this._emit(MessageTypes.MCU_ERROR,_errorCode);
_everSocketErrorHandler(_errorCode) {
this._emit(MessageTypes.MCU_ERROR, _errorCode);
//如果自动重连次数已经达到最大值,重新选点
if(_errorCode==everSocket.ERR_SOCKET_RECONNECT_FAILED){
this._emit(MessageTypes.CHANGE_MCU_IP);
if (_errorCode == everSocket.ERR_SOCKET_RECONNECT_FAILED) {
this._emit(MessageTypes.SWITCH_MCU_IP);
}
}
... ... @@ -127,7 +128,7 @@ class MCU extends Emiter {
let subTypeLabel = pdu.id2type(pduMsg.subType);
//loger.log('MCU-SecondLayer封装消息', 'sessionId', sessionLabel, pduMsg.sessionId, 'subtype', subTypeLabel, pduMsg.subType);
loger.warn('MCU->收到消息处理->subType->',pduMsg.subType, GlobalConfig.mcuDelay, GlobalConfig.messageDelay);
loger.warn('MCU->收到消息处理->subType->', pduMsg.subType, GlobalConfig.mcuDelay, GlobalConfig.messageDelay);
//延迟处理消息(3个条件--->ape允许延迟&&客户端设置需要延迟&&Sass设置的延迟时间大于0)
if (ape._apeDelayed && GlobalConfig.messageDelay && GlobalConfig.mcuDelay > 0) {
loger.warn('延迟处理消息->', GlobalConfig.mcuDelay);
... ... @@ -218,6 +219,17 @@ class MCU extends Emiter {
//开启EverSocket
this._everSocket.begin(this.classInfo.MCUServerIP, this.classInfo.MCUServerPort);
}
//切换MCU的ip
switchMCUIp(_classInfo) {
if (_classInfo && _classInfo.MCUServerIP) {
this.classInfo.MCUServerIP = _classInfo.MCUServerIP;
this.classInfo.MCUServerPort = _classInfo.MCUServerIP;
if (this._everSocket) {
this._everSocket.switchSocketIp(this.classInfo.MCUServerIP, this.classInfo.MCUServerPort);
}
}
}
}
export default new MCU;
... ...