继续操作前请注册或者登录。
李勇

1.修改MCU断线处理,断开连接之后,各个模块不处理应用层操作,只给提示

2.MCU 心跳修改,MUC服务端已经修改了心跳请求的逻辑,30秒没有请求按离开处理,客户端每次心跳的时间改为10秒,检查超时=心跳时长*2+1;
3.会议状态增加当前课堂进行时间的记录,每隔30秒同步当前课堂状态,并保存到Sass
... ... @@ -121,11 +121,11 @@ export default class MessageEntrance extends Emiter {
this.sendChatMsg = this._sendChatMsg;
//videoApe
this.getVideoPlayPath = this._getPlayVideoPath;
this.getVideoPublishPath = this._getPublishVideoPath;
this.getVideoPlayPath = this._getVideoPlayPath;
this.getVideoPublishPath = this._getVideoPublishPath;
this.publishVideo = this._publishVideo;
this.stopPublishVideo = this._stopPublishVideo;
this.sendVideoBroadcastMsg=this.sendVideoCommandMsg;
this.sendVideoBroadcastMsg=this._sendVideoBroadcastMsg;
//audioApe
... ... @@ -446,7 +446,7 @@ export default class MessageEntrance extends Emiter {
//获取会议所有参数 api/meeting/detail.do? flash中的接口文件是 getClassParam.do
_sassGetClassParamSuccessHandler(_data) {
//console.log(GlobalConfig.classStatusInfo)
loger.log('获取api/meeting/detail.do完成.');
loger.log('获取课堂会议的完整信息完成.');
// console.log(_data);
//包含整个会议最全的信息,储存数据
if (_data) {
... ... @@ -585,13 +585,19 @@ export default class MessageEntrance extends Emiter {
initSuccessCallBackData.userId = GlobalConfig.userId;
initSuccessCallBackData.passwordRequired = GlobalConfig.passwordRequired;
initSuccessCallBackData.classType = GlobalConfig.classType || ApeConsts.CLASS_TYPE_INTERACT;
loger.log('加入会议成功', initSuccessCallBackData);
loger.log('加入会议成功');
console.log(initSuccessCallBackData);
_joinClassSuccessCallBackFun(initSuccessCallBackData);
}
}
//Sass删除文档数据
_sassDeleteDocument(_param) {
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
//判断传入的参数是否存在
if (_param == null || EngineUtils.isEmptyObject(_param)) {
loger.error('sassDeleteDocument失败,参数错误', _param);
... ... @@ -620,24 +626,42 @@ export default class MessageEntrance extends Emiter {
//ConferApe
//开始上课
_sendStartClass(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if(_confer_ape){
_confer_ape.startClass(_param);
}
}
//暂停上课
_sendPauseClass(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if(_confer_ape){
_confer_ape.pauseClass(_param);
}
}
//停止上课
_sendCloseClass(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if(_confer_ape){
_confer_ape.closeClass(_param);
}
}
// 离开会议
_leaveClass() {
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
//停止推流
if(_video_ape){
_video_ape.stopPublishVideo();
... ... @@ -659,6 +683,10 @@ export default class MessageEntrance extends Emiter {
//ChatApe
// 发送聊天消息
_sendChatMsg(_messageInfo) {
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if(_messageInfo===null||EngineUtils.isEmptyObject(_messageInfo)){
loger.log('sendChatMsg 传递的参数不对',_messageInfo);
return ;
... ... @@ -676,31 +704,43 @@ export default class MessageEntrance extends Emiter {
}
}
sendVideoCommandMsg(_param){
_sendVideoBroadcastMsg(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if(_video_ape){
return _video_ape.sendVideoCommandMsg(_param);
return _video_ape.sendVideoBroadcastMsg(_param);
}
}
_getPlayVideoPath(_param){
_getVideoPlayPath(_param){
if(_video_ape){
return _video_ape.getPlayVideoPath(_param);
}
}
_getPublishVideoPath(_param){
_getVideoPublishPath(_param){
if(_video_ape){
return _video_ape.getPublishVideoPath(_param);
}
}
_publishVideo(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if(_video_ape){
return _video_ape.publishVideo(_param);
}
}
_stopPublishVideo(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if(_video_ape){
return _video_ape.stopPublishVideo(_param);
}
... ... @@ -715,6 +755,10 @@ export default class MessageEntrance extends Emiter {
}
sendAudioCommandMsg(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if(_audio_ape){
return _audio_ape.sendAudioBroadcastMsg(_param);
}
... ... @@ -733,12 +777,20 @@ export default class MessageEntrance extends Emiter {
}
_publishAudio(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if(_audio_ape){
return _audio_ape.publishAudio(_param);
}
}
_stopPublishAudio(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if(_audio_ape){
return _audio_ape.stopPublishAudio(_param);
}
... ... @@ -748,6 +800,10 @@ export default class MessageEntrance extends Emiter {
//WhiteBoardApe
// 添加标注,发送信息
_sendInsertAnnotaion(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if(_whiteboard_ape){
_whiteboard_ape.sendInsetAnnotaion(_param);
}
... ... @@ -755,18 +811,30 @@ export default class MessageEntrance extends Emiter {
//删除标注,发送信息
_sendDeleteAnnotaion(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if(_whiteboard_ape){
_whiteboard_ape.sendDeleteAnnotaion(_param);
}
}
//删除当前页面上的所有标注
_sendDeleteCurPageAnnotation(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if(_whiteboard_ape){
_whiteboard_ape.sendDeleteCurPageAnnotation(_param);
}
}
//删除所有标注
_sendDeleteAllAnnotation(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if(_whiteboard_ape){
_whiteboard_ape.sendDeleteAllAnnotation(_param);
}
... ... @@ -791,36 +859,60 @@ export default class MessageEntrance extends Emiter {
}
//上传文档
_sendDocumentUpload(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if(_doc_ape){
_doc_ape.documentUpload(_param);
}
}
//切换文档
_sendDocumentSwitchDoc(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if(_doc_ape){
_doc_ape.documentSwitchDoc(_param);
}
}
//操作文档(翻页)
_sendDocumentSwitchPage(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if(_doc_ape){
_doc_ape.documentSwitchPage(_param);
}
}
//操作文档(缩放、滚动...)
_sendDocumentCommand(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if(_doc_ape){
_doc_ape.documentCommand(_param);
}
}
//删除文档
_sendDocumentDelete(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if(_doc_ape){
_doc_ape.documentDelete(_param);
}
}
//删除所有文档
_documentDeleteAll(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if(_doc_ape){
_doc_ape.documentDeleteAll(_param);
}
... ... @@ -828,6 +920,10 @@ export default class MessageEntrance extends Emiter {
//// 文档变更,白板也需要做处理
docUpdateHandler(_data) {
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
loger.log('Doc UpdateId ->');
console.log(_data);
if(_whiteboard_ape){
... ...
... ... @@ -20,7 +20,7 @@ class EverSocket extends Emiter {
constructor() {
super();
this._connected = false;
this._lastActiveTime = 0;
this._lastActiveTime = 0;//最后一次收到消息的时间
this._enableEverSocket = false;
}
... ... @@ -77,6 +77,7 @@ class EverSocket extends Emiter {
}
_clear() {
this._emit(EverSocket.CLOSED);
loger.log('WebSocket,Timers销毁');
window.clearInterval(this.pingTimer);
window.clearInterval(this.pongTimer);
... ... @@ -150,9 +151,19 @@ class EverSocket extends Emiter {
}
}
/*//修改之前的
EverSocket.prototype.PONG_INTERVAL = EverSocket.PONG_INTERVAL = 5000;
EverSocket.prototype.PING_INTERVAL = EverSocket.PING_INTERVAL = 3000;
EverSocket.prototype.RECONN_INTERVAL = EverSocket.RECONN_INTERVAL = 2000;
EverSocket.prototype.RECONN_INTERVAL = EverSocket.RECONN_INTERVAL = 2000;*/
//20170223-mcu服务端修改了心跳的逻辑,如果客户端30秒没有请求,就会按离开的处理
//目前客户端发送心跳请求的空数据,服务端不会每次都回,暂定为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.CONNECTING = EverSocket.CONNECTING = 0;
EverSocket.prototype.OPEN = EverSocket.OPEN = 1;
EverSocket.prototype.CLOSING = EverSocket.CLOSING = 2;
... ...
... ... @@ -311,6 +311,7 @@ GlobalConfig.recordFileName="";//录制的文件名
GlobalConfig.recordDownloadUrl="";//下载地址
GlobalConfig.recordReplaytickValues={}; // 滚动条关键点,用于快进快退
GlobalConfig.updateClassInfoDelay=30;//(秒),每隔30秒同步一次会议状态的并保存到Sass
//GlobalConfig.serverTimestamp=0;//当前的系统时间戳 用get set 获取
... ...
... ... @@ -24,6 +24,11 @@ MessageTypes.CLASS_EXIT = 'class.exit';//退出 关闭会议
MessageTypes.CLASS_UPTATE_STATUS = 'class.update.status';//更新会议状态信息
MessageTypes.CLASS_STATUS_INFO_CHANGE= 'class.status.info.change';//会议状态信息发生改变,需要保存数据到sass和同步MCU
MessageTypes.CLASS_UPDATE_TIMER='class.update.timer';//更新当前上课的时间
//聊天模块事件定义
MessageTypes.CHAT_RECEIVE = 'chat.receive';
... ...
... ... @@ -17,7 +17,6 @@ class Sass extends Emiter {
///////////////////////////////////////Sass 接口///////////////////////////////////////////////////
//Sass init初始化获取课堂校验信息-----------------------------------------------------------------
getJoinParams(_initInfo) {
loger.log('初始化init获取课堂校验信息', _initInfo);
/* 获取用于加入课堂的参数
/3m/api/meeting/joinParams.do
参数 (application/x-www-form-urlencoded):
... ... @@ -37,7 +36,9 @@ class Sass extends Emiter {
classType 课堂类型
*/
let url = `http://${_initInfo.portal}/3m/api/meeting/joinParams.do?meetingNumber=${_initInfo.classId}&userID=${_initInfo.userId}`;
loger.log('初始化init获取课堂校验信息.', url);
loger.log('1.初始化init获取课堂校验信息.');
console.log(url);
console.log(_initInfo);
fetch(url, {
timeout: 5000
})
... ... @@ -83,7 +84,8 @@ class Sass extends Emiter {
// Sass校验开始-->密码校验(如果需要密码)--->MD5校验----------------------------------------------------
passwordAndMd5Checking(_param) {
loger.log('开始Sass校验', _param);
loger.log('2.开始Sass校验');
console.log(_param);
confInfo = _param;
// 密码校验
if (confInfo.passwordRequired === 'true'||confInfo.passwordRequired === true) {
... ... @@ -112,7 +114,7 @@ class Sass extends Emiter {
}
let url = `http://${confInfo.portal}/3m/api/meeting/signIn.do?siteId=${confInfo.siteId}&classId=${confInfo.classId}&isTeacher=${isTeacher}&password=${confInfo.password}`;
loger.log('会议密码校验', url);
loger.log('3.会议密码校验', url);
fetch(url, {
timeout: 5000
})
... ... @@ -149,7 +151,7 @@ class Sass extends Emiter {
//MD5校验-----------------------------------------------------------------------------------------
sendMD5Checking() {
let url = `http://${confInfo.portal}/3m/meeting/md5CheckMeeting.do?siteId=${confInfo.siteId}&meetingNumber=${confInfo.classId}&userId=${confInfo.userId}&userName=${confInfo.userName}&userType=${confInfo.userType}&nopassword=${confInfo.passwordRequired}&md5=${confInfo.md5}`;
loger.log('MD5校验', url);
loger.log('4.MD5校验', url);
fetch(url, {
timeout: 5000
})
... ... @@ -179,7 +181,8 @@ class Sass extends Emiter {
GlobalConfig.maxVideoChannels=confInfo.maxVideoChannels;
GlobalConfig.maxAudioChannels=confInfo.maxAudioChannels;
GlobalConfig.maxMediaChannels=confInfo.maxMediaChannels;*/
loger.log('MD5校验完成',ret);
loger.log('MD5校验完成');
console.log(ret);
this._emit(Sass.SUCCESS,ret);
} else {
loger.log('MD5校验-失败.');
... ... @@ -245,7 +248,8 @@ class Sass extends Emiter {
var timestamp=new Date().getTime();
var authId=MD5(confInfo.classId+""+timestamp);//课堂号+时间戳 的字符串,转成MD5
let url = `http://${confInfo.portal}/3m/api/meeting/detail.do?meetingNumber=${confInfo.classId}&timestamp=${timestamp}&authId=${authId}`;
loger.log('Sass getClassParam ', url);
loger.log('5.获取课堂会议的完整信息 ');
console.log(url);
fetch(url, {
timeout: 5000
})
... ... @@ -253,7 +257,7 @@ class Sass extends Emiter {
if (ret.ok) {
return ret.json();
} else {
loger.error(`getClassParam-网络异常.状态码:${ret.status}`);
loger.error(`获取课堂会议的完整信息-网络异常.状态码:${ret.status}`);
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_GET_CLASS_PARAML);
throw '';
... ... @@ -261,15 +265,15 @@ class Sass extends Emiter {
})
.then(ret => {
if (ret.code === 0) {
loger.log('getClassParam 完成');
loger.log('获取课堂会议的完整信息完成');
this._emit(Sass.CLASS_GET_CLASS_PARAM, ret);
} else {
loger.warn('getClassParam 失败.');
loger.warn('获取课堂会议的完整信息 失败.');
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_GET_CLASS_PARAML);
}
})
.catch(err => {
loger.error(`getClassParam异常.状态码:${err}`);
loger.error(`获取课堂会议的完整信息异常.状态码:${err}`);
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_GET_CLASS_PARAML);
});
}
... ...
... ... @@ -300,7 +300,8 @@ export default class Ape extends Emiter {
}
send(appPdu) {
loger.log('Ape发送数据NORMAL PDU', appPdu);
loger.log('Ape发送数据NORMAL PDU');
console.log(appPdu);
//loger.log('当前的状态============',GlobalConfig.getCurrentStatus().code);
if(GlobalConfig.getCurrentStatus().code==0||GlobalConfig.getCurrentStatus().code==1){
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN);
... ... @@ -325,7 +326,8 @@ export default class Ape extends Emiter {
// 发送当前APE(session uniform包)
sendUniform(appPdu, top) {
loger.log('Ape发送数据UNIFORM PDU', appPdu);
loger.log('Ape发送数据UNIFORM PDU');
console.log(appPdu);
//loger.log('当前的状态============',GlobalConfig.getCurrentStatus().code);
if(GlobalConfig.getCurrentStatus().code==0||GlobalConfig.getCurrentStatus().code==1){
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN);
... ... @@ -349,7 +351,8 @@ export default class Ape extends Emiter {
}
sendChatUniform(appPdu, top) {
loger.log('Ape发送数据UNIFORM PDU', appPdu);
loger.log('Ape发送数据UNIFORM PDU');
console.log(appPdu);
//loger.log('当前的状态============',GlobalConfig.getCurrentStatus().code);
if(GlobalConfig.getCurrentStatus().code==0||GlobalConfig.getCurrentStatus().code==1){
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN);
... ...
... ... @@ -52,6 +52,11 @@ class AudioApe extends Ape {
//推流
publishAudio(_param) {
if(!this.mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};
}
if (_param == null||_param.channelId == null||
_param.classId == null||_param.userId == null||
_param.siteId == null|| _param.timestamp==null)
... ... @@ -96,6 +101,10 @@ class AudioApe extends Ape {
//停止推流,
stopPublishAudio(_param) {
loger.log('stopPublishAudio');
if(!this.mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};
}
//_param如果为空,那么默认就是当前自己的nodeId,否则用_param
let nodeId;
if(_param&&parseInt(_param.nodeId)>=0){
... ... @@ -122,6 +131,10 @@ class AudioApe extends Ape {
}
sendAudioBroadcastMsg(_param) {
if(!this.mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};
}
if (this._classInfo === null || EngineUtils.isEmptyObject(this._classInfo)) {
loger.log('sendAudioBroadcastMsg.McuClient还未初始化数据!');
if (GlobalConfig.getCurrentStatus().code == 0 || GlobalConfig.getCurrentStatus().code == 1) {
... ...
... ... @@ -11,6 +11,7 @@ import UTF8 from 'utf-8';
import Loger from 'Loger';
import GlobalConfig from 'GlobalConfig';
import EngineUtils from 'EngineUtils';
import TimerCounter from "TimerCounter";
let loger = Loger.getLoger('ConferApe');
let itemIdx=0;//table插入新数据的计数id,目前用时间戳
... ... @@ -34,6 +35,7 @@ class ConferApe extends Ape {
// 默认值: normal
this.hostUserId = '';//主持人的 第三方userId
this.rosters = {};//用户列表
this.timerCounter=new TimerCounter();//计时器
// Ape Models
this.registerKey(this._session_id, this._session_name, this._session_tag, new ArrayBuffer);
... ... @@ -55,11 +57,11 @@ class ConferApe extends Ape {
this.on(pdu.RCPDU_CONFERENCE_SEND_DATA_REQUEST, this.conferMsgComingHandler.bind(this));//这个是会议消息类型,flash里在使用这里不再使用,各个模块的消息由模块自己来处理
}
//加入会议
_joinSessionHandler(_data) {
let nodeInfoRecordPdu = this.mcu.mcuClassInfo.self;
loger.log("_joinSessionHandler nodeInfoRecordPdu=",nodeInfoRecordPdu);
loger.log("_joinSessionHandler nodeInfoRecordPdu=");
console.log(nodeInfoRecordPdu);
let userDataPdu = new pdu['RCNodeInfoUserDataPdu'];
userDataPdu.qq = '';
userDataPdu.skype = '';
... ... @@ -104,7 +106,7 @@ class ConferApe extends Ape {
// to, message
loger.log('发送会议消息.', _messageInfo);
/* message RCConferenceSendDataRequestPdu {
/* message RCConferenceSendDataRequestPdu {
optional uint32 initiator = 1;
optional uint32 peer = 2;
required bool is_public = 3;
... ... @@ -170,6 +172,7 @@ class ConferApe extends Ape {
//还原课堂状态
restorClass(){
GlobalConfig.classTimestamp=0;
GlobalConfig.classStatus=ApeConsts.CLASS_STATUS_WAIT;
GlobalConfig.classStopTime=EngineUtils.creatTimestampStr();
this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
... ... @@ -189,6 +192,9 @@ class ConferApe extends Ape {
//_param.actionType=ACTION_TYPE_1;
this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
this.sendUpdaterClassStatusInfo({"actionType":1});
//开始计时
this.startTimerCounter();
}
//暂停上课
pauseClass(_param){
... ... @@ -202,6 +208,7 @@ class ConferApe extends Ape {
//_param.actionType=ACTION_TYPE_2;
this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
this.sendUpdaterClassStatusInfo({"actionType":2});
this.stopTimerCounter();
}
//关闭课堂
closeClass(_param){
... ... @@ -210,8 +217,8 @@ class ConferApe extends Ape {
return;
}
this.stopTimerCounter();
this.restorClass();
//把所有人都踢出课堂
this.sendConferMsg({"to":0,"message":"所有人退出会议","actionType":ApeConsts.CLASS_ACTION_CLOSE_ALL});
}
... ... @@ -219,7 +226,7 @@ class ConferApe extends Ape {
//更新会议信息
sendUpdaterClassStatusInfo(_param){
loger.log('sendUpdaterClassStatusInfo---1-------');
loger.log('sendUpdaterClassStatusInfo');
if(_param==null||EngineUtils.isEmptyObject(_param)){
loger.log('sendUpdaterClassStatusInfo,参数错误');
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
... ... @@ -227,7 +234,7 @@ class ConferApe extends Ape {
}
itemIdx=ApeConsts.CONFERENCE_OBJ_TABLE_ID;// itemIdx=_param.itemIdx;
let modelPdu = this.packPdu(_param,itemIdx);
loger.log('sendUpdaterClassStatusInfo----2------');
//loger.log('sendUpdaterClassStatusInfo----2------');
console.log(modelPdu);
if(modelPdu==null){
... ... @@ -269,80 +276,57 @@ class ConferApe extends Ape {
this.sendUniform(adapterPdu,true);
}
/* //更新会议状态
sendUpdaterClassStatus(_param){
loger.log('sendUpdaterClassStatus----------');
if(_param==null||EngineUtils.isEmptyObject(_param)){
loger.log('sendUpdaterClassStatusInfo,参数错误');
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
return ;
}
itemIdx=_param.itemIdx;
let modelPdu = this.packPdu(_param,itemIdx);
console.log(modelPdu);
if(modelPdu==null){
loger.log('sendUpdaterClassStatusInfo,参数错误');
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
return ;
}
let tableItemPdu = new pdu['RCRegistryTableItemPdu'];
tableItemPdu.itemIdx=itemIdx;
tableItemPdu.owner = 0;//收到flash的是这个值,不清楚先写固定
tableItemPdu.registerObjId=ApeConsts.CONFERENCE_OBJ_TABLE_ID;
tableItemPdu.itemData =modelPdu.toArrayBuffer();
//updater
let tableUpdateItem = new pdu['RCRegistryTableUpdateItemPdu'];
//optional RCPduType_E type = 1 [default = RCPDU_REG_TABLE_UPDATE_PDU];
//repeated RCRegistryTableItemPdu items = 2;
tableUpdateItem.type = pdu.RCPDU_REG_TABLE_UPDATE_PDU;//
tableUpdateItem.items.push(tableItemPdu);
let updateObjPdu = new pdu['RCRegistryUpdateObjPdu'];
updateObjPdu.objId = ApeConsts.CONFERENCE_OBJ_TABLE_ID;
updateObjPdu.subType = tableUpdateItem.type;
updateObjPdu.userData = tableUpdateItem.toArrayBuffer();
//同步
let adapterItemPdu = new pdu['RCAdapterItemPdu'];
adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ;
adapterItemPdu.itemData = updateObjPdu.toArrayBuffer();
let adapterPdu = new pdu['RCAdapterPdu'];
adapterPdu.type = pdu.RCPDU_REG_ADAPTER;
adapterPdu.item.push(adapterItemPdu);
console.log("会议发送更新数据111============");
this.sendUniform(adapterPdu,true);
}*/
/////收到消息处理/////////////////////////////////////////////////////////////////////////////////
//加入channel成功
onJoinChannelHandlerSuccess(){
loger.log('ConferApe onJoinChannelHandlerSuccess');
//if(GlobalConfig.isHost){
// if(GlobalConfig.classStatus==ApeConsts.CLASS_STATUS_WAIT){
// GlobalConfig.classStartTime=EngineUtils.creatTimestampStr();
// GlobalConfig.classStopTime=GlobalConfig.classStartTime;
// }else{
// GlobalConfig.classStopTime=GlobalConfig.creatTimestampStr;
// }
//
// GlobalConfig.classStatus=ApeConsts.CLASS_STATUS_STARTED;
// //_param.actionType=ACTION_TYPE_1;
// this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
// this.sendUpdaterClassStatusInfo(_param);
//}
this.timerCounter.addTimerCallBack(this.timerCounterUptate.bind(this),1);
//如果当前会议正在进行中,开启计时器
if(GlobalConfig.classStatus==ApeConsts.CLASS_STATUS_STARTED){
//开始计时
this.startTimerCounter();
}
}
//开启计时器
startTimerCounter(){
this.timerCounter.startTimer();
}
//停止计时器
stopTimerCounter(){
this.timerCounter.stopTimer();
}
timerCounterUptate(){
if(!this.mcu.connected){
loger.warn('MCU 连接已经断开');
this.stopTimerCounter();
}
//如果还没开始或已经暂停、关闭,不做计时处理
if(GlobalConfig.classStatus!=ApeConsts.CLASS_STATUS_STARTED){
loger.warn('当前课堂已经暂停或者未开始,不计时',"classStatus-->",GlobalConfig.classStatus);
return;
}
GlobalConfig.classTimestamp=GlobalConfig.classTimestamp+1;//计时
loger.log('课堂进行时间',GlobalConfig.classTimestamp);
this._emit(MessageTypes.CLASS_UPDATE_TIMER,{"classTimestamp":GlobalConfig.classTimestamp});
if(GlobalConfig.classTimestamp%GlobalConfig.updateClassInfoDelay==0){
//如果是host身份,需要同步时间给其他人,同时把当前的状态上传到服务器
if(GlobalConfig.isHost){
//保存数据到Sass
this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
//同步消息给其他人
this.sendUpdaterClassStatusInfo({"actionType":1});
}
}
}
tableUpdateHandler(owner, itemIdx, itemData) {
try {
let model=this.unPackPdu(owner, itemIdx,itemData);
loger.log('tableUpdateHandler',model);
loger.log('tableUpdateHandler');
console.log(model);
//处理会议更新的信息
if(model&&model.classStatusInfo){
... ... @@ -351,36 +335,20 @@ class ConferApe extends Ape {
//通知应用层更新会议状态
this._emit(MessageTypes.CLASS_UPTATE_STATUS,GlobalConfig.classStatusInfo);
//_confer_ape.on(MessageTypes.CLASS_CLOSE, this._doClassClose.bind(this));//会议关闭,所有人都退出
/*{
"itemIdx": 720899,
"from": 161770995,
"owner": 161770995,
"actionType": null,
"classStatusInfo": {
"nodeId": 161770995,
"userId": "0",
"userName": "mcuTest1487161768",
"siteId": "h5test",
"classId": 1730033559,
"className": "mcuClient",
"classType": 1,
"classStatus": 0,
"classStartTime": "2017-2-15-20-30-11",
"classStopTime": "2017-2-15-20-30-28",
"classTimestamp": 0,
"classBeginTime": "2017-02-13 10:00:00",
"classEndTime": "2017-02-22 12:00:00",
"recordStatus": false,
"recordTimestamp": 0,
"recordFileName": "",
"recordDownloadUrl": "xxxxxxxxxxxxxxxxxxxxx",
"serverTimestamp": 161828290,
"activeDocId": 0,
"activeDocCurPage": 1
//如果MCU已经断开连接,停止计时器
if(!this.mcu.connected){
//停止计时
this.stopTimerCounter();
return;
}
}*/
if(GlobalConfig.classStatus==ApeConsts.CLASS_STATUS_STARTED){
//如果会议在进行中,开始计时器
this.startTimerCounter();
}else {
//停止计时
this.stopTimerCounter();
}
} catch (e) {
loger.warn('ConferApe table update got exception. itemIdx',itemIdx);
}
... ... @@ -499,28 +467,6 @@ class ConferApe extends Ape {
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
return null;
}
/* message RCClassStatusInfoPdu {
optional uint32 node_id=1;//mcu中的唯一ID
optional uint32 user_id=2;
optional uint32 user_name=3;
optional uint32 site_id=4;//站点号
optional uint32 class_id=5;
optional uint32 class_name=6;
required uint32 class_type=7;//课堂类型
required uint32 class_status=9;//课堂的状态
optional uint32 class_startTime=10;//课堂点击开始时间
optional uint32 class_stopTime=11;//最后一次停止的时间(点暂停或结束),每次发送数据都获取当前时间戳
optional uint32 class_timestamp=12;//相对于点开始课堂的时间戳
optional uint32 class_beginTime=13;//课堂创建的时间,这个是Sass返回的
optional uint32 class_endTime=14;//课堂结束的时间,这个是Sass返回的
optional uint32 record_status=15;//当前录制状态
optional uint32 record_timestamp=16;//相对于首次开始录制的时间戳
optional uint32 record_fileName=17;//录制的文件名
optional uint32 record_downloadUrl=18;//下载地址
optional uint32 server_timestamp=19;//当前的系统时间戳
}*/
let classStatusInfo=new pdu['RCClassStatusInfoPdu'];
classStatusInfo.nodeId=GlobalConfig.nodeId;//mcu中的唯一ID
classStatusInfo.userId=GlobalConfig.userId;
... ...
... ... @@ -53,6 +53,11 @@ class VideoApe extends Ape {
//推流
publishVideo(_param) {
if(!this.mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};
}
if (_param == null||_param.channelId == null||
_param.classId == null||_param.userId == null||
_param.siteId == null|| _param.timestamp==null)
... ... @@ -98,6 +103,11 @@ class VideoApe extends Ape {
//停止推流,
stopPublishVideo(_param) {
if(!this.mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};
}
loger.log('stopPublishVideo -> maxVideoChannels', GlobalConfig.maxVideoChannels);
//_param如果为空,那么默认就是当前自己的nodeId,否则用_param
let nodeId;
... ... @@ -124,7 +134,12 @@ class VideoApe extends Ape {
this.sendTableUpdateHandler(channelInfo);
}
sendVideoCommandMsg(_param) {
sendVideoBroadcastMsg(_param) {
if(!this.mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};
}
if (this._classInfo === null || EngineUtils.isEmptyObject(this._classInfo)) {
loger.log('不能发送Video消息.McuClient还未初始化数据!');
if (GlobalConfig.getCurrentStatus().code == 0 || GlobalConfig.getCurrentStatus().code == 1) {
... ... @@ -237,7 +252,8 @@ class VideoApe extends Ape {
return;
}
videoReceivePdu.data = this._rCArrayBufferUtil.uint8ArrayToStr(videoReceivePdu.data, 2);//开头两个字会乱码
loger.log('视频消息处理 receiveVideoCommandHandler.', videoReceivePdu);
loger.log('视频消息处理 receiveVideoCommandHandler.');
console.log(videoReceivePdu);
//判断接收者的id,如果不是0,并且也不是自己的nodeId,那么消息不做处理
if (videoReceivePdu.toNodeId != 0 && videoReceivePdu.toNodeId != GlobalConfig.nodeId) {
... ...
... ... @@ -23,6 +23,7 @@ class MCU extends Emiter {
this._everSocket = everSocket;
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));
}
// 注册Ape
... ... @@ -34,12 +35,18 @@ class MCU extends Emiter {
_everSocketOpenHandler() {
this._sendJoinClassRequest();
}
// EverSocket连接断开
_everSocketCloseHandler() {
GlobalConfig.setCurrentStatus(GlobalConfig.statusCode_3);
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_SOCKET_DISCONNECT);
}
//MCU-发送加入会议请求
_sendJoinClassRequest(){
//const classInfo = this.classInfo;
loger.log('MCU-发送加入会议请求.',this.classInfo);
loger.log('MCU-发送加入会议请求.');
console.log(this.classInfo);
var descriptorPdu = new pdu['RCConferenceDescriptorPdu'];
descriptorPdu.id = this.classInfo.classId;
descriptorPdu.name = this.classInfo.className||"";
... ... @@ -123,7 +130,7 @@ class MCU extends Emiter {
_updateMCUConfInfoDescription(_data) {
// let _mcuConfDesc=new pdu['RCConferenceDescriptorPdu'].decode(mcuConfDesc);
loger.log('_updateMCUConfInfoDescription.', _data);
loger.log('_updateMCUConfInfoDescription.');
//let classDescription=new pdu['RCConferenceDescriptorPdu'].decode(_data);
console.log(_data);
//let info = this.mcuClassInfo.info;
... ... @@ -162,7 +169,8 @@ class MCU extends Emiter {
// 主动建立MCU连接
joinMCU(_classInfo) {
loger.log('开始建立EverSocket通道.', _classInfo);
loger.log('开始建立EverSocket通道.');
console.log(_classInfo);
_classInfo.classId = parseInt(_classInfo.classId); // classId 必须整形
this.classInfo = _classInfo;
// 创建刷新nodeId
... ...