增加用户身份处理,同一个课堂只能有一个主持人,一个助教,一个主讲人,一个监课,如果新进入的用户是这几个身份,会踢掉当前课堂内同样身份的人
正在显示
7 个修改的文件
包含
626 行增加
和
570 行删除
| @@ -90,6 +90,7 @@ class EverSocket extends Emiter { | @@ -90,6 +90,7 @@ class EverSocket extends Emiter { | ||
| 90 | return; | 90 | return; |
| 91 | } | 91 | } |
| 92 | this._setConnected(false);//先设置状态 | 92 | this._setConnected(false);//先设置状态 |
| 93 | + this._enableEverSocket = false; | ||
| 93 | this.websocket.onopen = undefined; | 94 | this.websocket.onopen = undefined; |
| 94 | this.websocket.onclose = undefined; | 95 | this.websocket.onclose = undefined; |
| 95 | this.websocket.onerror = undefined; | 96 | this.websocket.onerror = undefined; |
| @@ -100,7 +101,7 @@ class EverSocket extends Emiter { | @@ -100,7 +101,7 @@ class EverSocket extends Emiter { | ||
| 100 | loger.log('ignore errors'); | 101 | loger.log('ignore errors'); |
| 101 | } | 102 | } |
| 102 | this.websocket = undefined; | 103 | this.websocket = undefined; |
| 103 | - this._enableEverSocket = false; | 104 | + |
| 104 | } | 105 | } |
| 105 | 106 | ||
| 106 | _onOpen() { | 107 | _onOpen() { |
| @@ -92,7 +92,7 @@ MessageTypes.ERR_CLASS_JOIN_FULL=204;//人数已满 | @@ -92,7 +92,7 @@ MessageTypes.ERR_CLASS_JOIN_FULL=204;//人数已满 | ||
| 92 | MessageTypes.ERR_CLASS_MD5_WRONG=205;//MD5验证失败 | 92 | MessageTypes.ERR_CLASS_MD5_WRONG=205;//MD5验证失败 |
| 93 | MessageTypes.ERR_CLASS_PASSWORD_WRONG=206;//密码错误 | 93 | MessageTypes.ERR_CLASS_PASSWORD_WRONG=206;//密码错误 |
| 94 | MessageTypes.ERR_CLASS_JOIN_CONFILICT=207;//已经在其它地方登陆 | 94 | MessageTypes.ERR_CLASS_JOIN_CONFILICT=207;//已经在其它地方登陆 |
| 95 | - | 95 | +MessageTypes.ERR_CLASS_KICK_OUT=208;//有相同身份的人员加入课堂,自己被踢出; |
| 96 | 96 | ||
| 97 | MessageTypes.ERR_GET_CLASS_DETAIL=300;//获取classDetail失败 | 97 | MessageTypes.ERR_GET_CLASS_DETAIL=300;//获取classDetail失败 |
| 98 | MessageTypes.ERR_GET_CLASS_PARAML=301;//获取ClassParam失败 | 98 | MessageTypes.ERR_GET_CLASS_PARAML=301;//获取ClassParam失败 |
| @@ -137,6 +137,7 @@ MessageTypes.ErrorReson[MessageTypes.ERR_CLASS_JOIN_FULL]="人数已满"; | @@ -137,6 +137,7 @@ MessageTypes.ErrorReson[MessageTypes.ERR_CLASS_JOIN_FULL]="人数已满"; | ||
| 137 | MessageTypes.ErrorReson[MessageTypes.ERR_CLASS_MD5_WRONG]="MD5验证失败"; | 137 | MessageTypes.ErrorReson[MessageTypes.ERR_CLASS_MD5_WRONG]="MD5验证失败"; |
| 138 | MessageTypes.ErrorReson[MessageTypes.ERR_CLASS_PASSWORD_WRONG]="密码错误"; | 138 | MessageTypes.ErrorReson[MessageTypes.ERR_CLASS_PASSWORD_WRONG]="密码错误"; |
| 139 | MessageTypes.ErrorReson[MessageTypes.ERR_CLASS_JOIN_CONFILICT]="已经在其它地方登陆"; | 139 | MessageTypes.ErrorReson[MessageTypes.ERR_CLASS_JOIN_CONFILICT]="已经在其它地方登陆"; |
| 140 | +MessageTypes.ErrorReson[MessageTypes.ERR_CLASS_KICK_OUT]="有相同身份的人员加入课堂,自己被踢出课堂"; | ||
| 140 | 141 | ||
| 141 | 142 | ||
| 142 | MessageTypes.ErrorReson[MessageTypes.ERR_GET_CLASS_DETAIL]="获取classDetail失败"; | 143 | MessageTypes.ErrorReson[MessageTypes.ERR_GET_CLASS_DETAIL]="获取classDetail失败"; |
| @@ -35,7 +35,7 @@ public static const NR_GUEST:uint = 0; // 客人 | @@ -35,7 +35,7 @@ public static const NR_GUEST:uint = 0; // 客人 | ||
| 35 | public static const NR_NORMAL:uint = 1; // 普通与会者 | 35 | public static const NR_NORMAL:uint = 1; // 普通与会者 |
| 36 | public static const NR_ADMIN:uint = 2; // 管理员 | 36 | public static const NR_ADMIN:uint = 2; // 管理员 |
| 37 | public static const NR_MASTER:uint = 4; // 主持人 | 37 | public static const NR_MASTER:uint = 4; // 主持人 |
| 38 | -public static const NR_SLAVE:uint = 8; // 主讲人 | 38 | +public static const NR_PRESENTER:uint = 8; // 主讲人 |
| 39 | public static const NR_ASSISTANT:uint = 16; // 助教 | 39 | public static const NR_ASSISTANT:uint = 16; // 助教 |
| 40 | public static const NR_INVISIBLE:uint = 32; // 隐身用户 | 40 | public static const NR_INVISIBLE:uint = 32; // 隐身用户 |
| 41 | */ | 41 | */ |
| @@ -45,8 +45,8 @@ public static const NR_INVISIBLE:uint = 32; // 隐身用户 | @@ -45,8 +45,8 @@ public static const NR_INVISIBLE:uint = 32; // 隐身用户 | ||
| 45 | //ApeConsts.NR_GUEST = 0; // 客人 | 45 | //ApeConsts.NR_GUEST = 0; // 客人 |
| 46 | ApeConsts.NR_NORMAL = 1;// 普通与会者 | 46 | ApeConsts.NR_NORMAL = 1;// 普通与会者 |
| 47 | ApeConsts.NR_ADMIN = 2;// 管理员 | 47 | ApeConsts.NR_ADMIN = 2;// 管理员 |
| 48 | -ApeConsts.NR_MASTER = 4; // 主持人 | ||
| 49 | -ApeConsts.NR_SLAVE = 8; // 主讲人 | 48 | +ApeConsts.NR_HOST = 4; // 主持人 |
| 49 | +ApeConsts.NR_PRESENTER = 8; // 主讲人 | ||
| 50 | ApeConsts.NR_ASSISTANT = 16; // 助教 | 50 | ApeConsts.NR_ASSISTANT = 16; // 助教 |
| 51 | ApeConsts.NR_INVISIBLE = 32; // 隐身用户 | 51 | ApeConsts.NR_INVISIBLE = 32; // 隐身用户 |
| 52 | 52 | ||
| @@ -58,6 +58,23 @@ ApeConsts.normal="normal";//(普通角色/学生) | @@ -58,6 +58,23 @@ ApeConsts.normal="normal";//(普通角色/学生) | ||
| 58 | ApeConsts.record="record";//(暂时没用. | 58 | ApeConsts.record="record";//(暂时没用. |
| 59 | ApeConsts.invisible="invisible";//隐身用户 | 59 | ApeConsts.invisible="invisible";//隐身用户 |
| 60 | 60 | ||
| 61 | +//下面做身份的数字和字符串对应关系 | ||
| 62 | +ApeConsts.userTypes={}; | ||
| 63 | +ApeConsts.userTypes[ApeConsts.NR_NORMAL]=ApeConsts.normal; | ||
| 64 | +ApeConsts.userTypes[ApeConsts.NR_ADMIN]=ApeConsts.record; | ||
| 65 | +ApeConsts.userTypes[ApeConsts.NR_HOST]=ApeConsts.host; | ||
| 66 | +ApeConsts.userTypes[ApeConsts.NR_PRESENTER]=ApeConsts.presenter; | ||
| 67 | +ApeConsts.userTypes[ApeConsts.NR_ASSISTANT]=ApeConsts.assistant; | ||
| 68 | +ApeConsts.userTypes[ApeConsts.NR_INVISIBLE]=ApeConsts.invisible; | ||
| 69 | + | ||
| 70 | +ApeConsts.userTypesToId={}; | ||
| 71 | +ApeConsts.userTypesToId[ApeConsts.normal]=ApeConsts.NR_NORMAL; | ||
| 72 | +ApeConsts.userTypesToId[ApeConsts.record]=ApeConsts.NR_ADMIN; | ||
| 73 | +ApeConsts.userTypesToId[ApeConsts.host]=ApeConsts.NR_HOST; | ||
| 74 | +ApeConsts.userTypesToId[ApeConsts.presenter]=ApeConsts.NR_PRESENTER; | ||
| 75 | +ApeConsts.userTypesToId[ApeConsts.assistant]=ApeConsts.NR_ASSISTANT; | ||
| 76 | +ApeConsts.userTypesToId[ApeConsts.invisible]=ApeConsts.NR_INVISIBLE; | ||
| 77 | + | ||
| 61 | ////最新定义的角色身份 20170220 | 78 | ////最新定义的角色身份 20170220 |
| 62 | //ApeConsts.USER_TYPE_HOST=1;//(主持人/老师) | 79 | //ApeConsts.USER_TYPE_HOST=1;//(主持人/老师) |
| 63 | //ApeConsts.USER_TYPE_ASSISTANT=2;//(助教) | 80 | //ApeConsts.USER_TYPE_ASSISTANT=2;//(助教) |
| @@ -162,7 +162,12 @@ class AudioApe extends Ape { | @@ -162,7 +162,12 @@ class AudioApe extends Ape { | ||
| 162 | } | 162 | } |
| 163 | //释放nodeId占用的所有频道 | 163 | //释放nodeId占用的所有频道 |
| 164 | _releaseNodeIdAllChannel(nodeId){ | 164 | _releaseNodeIdAllChannel(nodeId){ |
| 165 | - loger.log(nodeId,"_releaseNodeIdAllChannel"); | 165 | + loger.log(nodeId,"_releaseNodeIdAllChannel",this.mcu.connected); |
| 166 | + if(!this.mcu.connected){ | ||
| 167 | + loger.warn(GlobalConfig.getCurrentStatus()); | ||
| 168 | + return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"}; | ||
| 169 | + } | ||
| 170 | + | ||
| 166 | let openingChannel = this.mediaModule.getOpeningMediaChannel(nodeId); | 171 | let openingChannel = this.mediaModule.getOpeningMediaChannel(nodeId); |
| 167 | if (openingChannel == 0) { | 172 | if (openingChannel == 0) { |
| 168 | loger.warn(nodeId,"没有占用channel不需要处理"); | 173 | loger.warn(nodeId,"没有占用channel不需要处理"); |
| @@ -14,624 +14,651 @@ import EngineUtils from 'EngineUtils'; | @@ -14,624 +14,651 @@ import EngineUtils from 'EngineUtils'; | ||
| 14 | import TimerCounter from "TimerCounter"; | 14 | import TimerCounter from "TimerCounter"; |
| 15 | 15 | ||
| 16 | let loger = Loger.getLoger('ConferApe'); | 16 | let loger = Loger.getLoger('ConferApe'); |
| 17 | -let itemIdx=0;//table插入新数据的计数id,目前用时间戳 | 17 | +let itemIdx = 0;//table插入新数据的计数id,目前用时间戳 |
| 18 | 18 | ||
| 19 | class ConferApe extends Ape { | 19 | class ConferApe extends Ape { |
| 20 | - constructor() { | ||
| 21 | - super( | ||
| 22 | - ApeConsts.CONFERENCE_SESSION_ID, | ||
| 23 | - ApeConsts.CONFERENCE_SESSION_NAME, | ||
| 24 | - ApeConsts.CONFERENCE_SESSION_TAG | ||
| 25 | - ); | ||
| 26 | - | ||
| 27 | - // Attribures | ||
| 28 | - this.hostNodeId = -1;//主持人的nodeId | ||
| 29 | - // 用户的身份,5种类型: | ||
| 30 | - // host(主持人/老师) | ||
| 31 | - // presenter(主讲人) | ||
| 32 | - // assistant(助教) | ||
| 33 | - // normal(普通角色/学生) | ||
| 34 | - // record(暂时没用. | ||
| 35 | - // 默认值: normal | ||
| 36 | - this.hostUserId = '';//主持人的 第三方userId | ||
| 37 | - this.rosters = {};//用户列表 | ||
| 38 | - this.timerCounter=new TimerCounter();//计时器 | ||
| 39 | - | ||
| 40 | - // Ape Models | ||
| 41 | - this.registerKey(this._session_id, this._session_name, this._session_tag, new ArrayBuffer); | ||
| 42 | - | ||
| 43 | - this.registerObj(pdu.RCPDU_REG_REGISTER_ROSTER, ApeConsts.CONFERENCE_OBJ_ROSTER_ID, | ||
| 44 | - ApeConsts.CONFERENCE_OBJ_ROSTER_NAME, ApeConsts.CONFERENCE_OBJ_ROSTER_TAG, 0, new ArrayBuffer); | ||
| 45 | - | ||
| 46 | - this.registerObj(pdu.RCPDU_REG_REGISTER_QUEUE, ApeConsts.CONFERENCE_OBJ_QUEUE_ID, | ||
| 47 | - ApeConsts.CONFERENCE_OBJ_QUEUE_NAME, ApeConsts.CONFERENCE_OBJ_QUEUE_TAG, 0, new ArrayBuffer); | ||
| 48 | - | ||
| 49 | - this.registerObj(pdu.RCPDU_REG_REGISTER_TABLE, ApeConsts.CONFERENCE_OBJ_TABLE_ID, | ||
| 50 | - ApeConsts.CONFERENCE_OBJ_TABLE_NAME, ApeConsts.CONFERENCE_OBJ_TABLE_TAG, 0, new ArrayBuffer); | ||
| 51 | - | ||
| 52 | - this.registerObj(pdu.RCPDU_REG_REGISTER_COUNTER, ApeConsts.CONFERENCE_OBJ_COUNTER_ID, | ||
| 53 | - ApeConsts.CONFERENCE_OBJ_COUNTER_NAME, ApeConsts.CONFERENCE_OBJ_COUNTER_TAG, 0, new ArrayBuffer); | ||
| 54 | - | ||
| 55 | - this.on(pdu.RCPDU_SESSION_JOIN_RESPONSE, this._joinSessionHandler.bind(this)); | ||
| 56 | - | ||
| 57 | - this.on(pdu.RCPDU_SEND_CONFERENCE_DATA_REQUEST, this.conferMsgComingHandler.bind(this));//这个是会议消息类型,flash里在使用这里不再使用,各个模块的消息由模块自己来处理 | ||
| 58 | - this.on(pdu.RCPDU_CONFERENCE_RECORD_REQUEST,this.onSendConferRecordRequestHandler.bind(this));//发送录制和停止录制消息 | ||
| 59 | - } | ||
| 60 | - | ||
| 61 | - //加入会议 | ||
| 62 | - _joinSessionHandler(_data) { | ||
| 63 | - let nodeInfoRecordPdu = this.mcu.mcuClassInfo.self; | ||
| 64 | - loger.log("_joinSessionHandler nodeInfoRecordPdu="); | ||
| 65 | - console.log(nodeInfoRecordPdu); | ||
| 66 | - let userDataPdu = new pdu['RCNodeInfoUserDataPdu']; | ||
| 67 | - userDataPdu.qq = ''; | ||
| 68 | - userDataPdu.skype = ''; | ||
| 69 | - | ||
| 70 | - nodeInfoRecordPdu.userData = userDataPdu.toArrayBuffer(); | ||
| 71 | - nodeInfoRecordPdu.deviceType =GlobalConfig.deviceType;//设备类型 | ||
| 72 | - | ||
| 73 | - let item = new pdu['RCRegistryRosterItemPdu']; | ||
| 74 | - item.nodeId = nodeInfoRecordPdu.nodeId; | ||
| 75 | - item.nodeData = nodeInfoRecordPdu.toArrayBuffer(); | ||
| 76 | - | ||
| 77 | - let rosterUpdateItem = new pdu['RCRegistryRosterUpdateItemPdu']; | ||
| 78 | - rosterUpdateItem.type = pdu.RCPDU_REG_ROSTER_UPDATE_PDU; | ||
| 79 | - rosterUpdateItem.items.push(item); | ||
| 80 | - | ||
| 81 | - let updateObjPdu = new pdu['RCRegistryUpdateObjPdu']; | ||
| 82 | - updateObjPdu.objId = ApeConsts.CONFERENCE_OBJ_ROSTER_ID; | ||
| 83 | - updateObjPdu.subType = rosterUpdateItem.type; | ||
| 84 | - updateObjPdu.userData = rosterUpdateItem.toArrayBuffer(); | ||
| 85 | - | ||
| 86 | - //同步 | ||
| 87 | - let adapterItemPdu = new pdu['RCAdapterItemPdu']; | ||
| 88 | - adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ; | ||
| 89 | - adapterItemPdu.itemData = updateObjPdu.toArrayBuffer(); | ||
| 90 | - | ||
| 91 | - let adapterPdu = new pdu['RCAdapterPdu']; | ||
| 92 | - adapterPdu.type = pdu.RCPDU_REG_ADAPTER; | ||
| 93 | - adapterPdu.item.push(adapterItemPdu); | ||
| 94 | - this.sendUniform(adapterPdu, true); | ||
| 95 | - } | ||
| 96 | - | ||
| 97 | - sendConferMsg(_messageInfo) { | ||
| 98 | - if(this._classInfo==null||EngineUtils.isEmptyObject(this._classInfo)){ | ||
| 99 | - loger.log('不能发送会议消息.McuClient还未初始化数据!'); | ||
| 100 | - if(GlobalConfig.getCurrentStatus().code==0||GlobalConfig.getCurrentStatus().code==1){ | ||
| 101 | - this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN); | ||
| 102 | - return; | ||
| 103 | - } | ||
| 104 | - return ; | 20 | + constructor() { |
| 21 | + super( | ||
| 22 | + ApeConsts.CONFERENCE_SESSION_ID, | ||
| 23 | + ApeConsts.CONFERENCE_SESSION_NAME, | ||
| 24 | + ApeConsts.CONFERENCE_SESSION_TAG | ||
| 25 | + ); | ||
| 26 | + /* | ||
| 27 | + // Attribures | ||
| 28 | + this.hostNodeId = -1;//主持人的nodeId | ||
| 29 | + // 用户的身份,5种类型: | ||
| 30 | + // host(主持人/老师) | ||
| 31 | + // presenter(主讲人) | ||
| 32 | + // assistant(助教) | ||
| 33 | + // normal(普通角色/学生) | ||
| 34 | + // record(暂时没用. | ||
| 35 | + // 默认值: normal | ||
| 36 | + this.hostUserId = '';//主持人的 第三方userId | ||
| 37 | + */ | ||
| 38 | + | ||
| 39 | + this.rosters = {};//用户列表 | ||
| 40 | + this.timerCounter = new TimerCounter();//计时器 | ||
| 41 | + | ||
| 42 | + // Ape Models | ||
| 43 | + this.registerKey(this._session_id, this._session_name, this._session_tag, new ArrayBuffer); | ||
| 44 | + | ||
| 45 | + this.registerObj(pdu.RCPDU_REG_REGISTER_ROSTER, ApeConsts.CONFERENCE_OBJ_ROSTER_ID, | ||
| 46 | + ApeConsts.CONFERENCE_OBJ_ROSTER_NAME, ApeConsts.CONFERENCE_OBJ_ROSTER_TAG, 0, new ArrayBuffer); | ||
| 47 | + | ||
| 48 | + this.registerObj(pdu.RCPDU_REG_REGISTER_QUEUE, ApeConsts.CONFERENCE_OBJ_QUEUE_ID, | ||
| 49 | + ApeConsts.CONFERENCE_OBJ_QUEUE_NAME, ApeConsts.CONFERENCE_OBJ_QUEUE_TAG, 0, new ArrayBuffer); | ||
| 50 | + | ||
| 51 | + this.registerObj(pdu.RCPDU_REG_REGISTER_TABLE, ApeConsts.CONFERENCE_OBJ_TABLE_ID, | ||
| 52 | + ApeConsts.CONFERENCE_OBJ_TABLE_NAME, ApeConsts.CONFERENCE_OBJ_TABLE_TAG, 0, new ArrayBuffer); | ||
| 53 | + | ||
| 54 | + this.registerObj(pdu.RCPDU_REG_REGISTER_COUNTER, ApeConsts.CONFERENCE_OBJ_COUNTER_ID, | ||
| 55 | + ApeConsts.CONFERENCE_OBJ_COUNTER_NAME, ApeConsts.CONFERENCE_OBJ_COUNTER_TAG, 0, new ArrayBuffer); | ||
| 56 | + | ||
| 57 | + this.on(pdu.RCPDU_SESSION_JOIN_RESPONSE, this._joinSessionHandler.bind(this)); | ||
| 58 | + | ||
| 59 | + this.on(pdu.RCPDU_SEND_CONFERENCE_DATA_REQUEST, this.conferMsgComingHandler.bind(this));//这个是会议消息类型,flash里在使用这里不再使用,各个模块的消息由模块自己来处理 | ||
| 60 | + this.on(pdu.RCPDU_CONFERENCE_RECORD_REQUEST, this.onSendConferRecordRequestHandler.bind(this));//发送录制和停止录制消息 | ||
| 105 | } | 61 | } |
| 106 | 62 | ||
| 107 | - // to, message | ||
| 108 | - loger.log('发送会议消息.', _messageInfo); | ||
| 109 | - | ||
| 110 | - /* message RCConferenceSendDataRequestPdu { | ||
| 111 | - optional uint32 initiator = 1; | ||
| 112 | - optional uint32 peer = 2; | ||
| 113 | - required bool is_public = 3; | ||
| 114 | - required bytes user_data = 4; | ||
| 115 | - } | ||
| 116 | - */ | ||
| 117 | - | ||
| 118 | - let conferSendPdu = new pdu['RCConferenceSendDataRequestPdu']; | ||
| 119 | - conferSendPdu.type = pdu.RCPDU_SEND_CONFERENCE_DATA_REQUEST; | ||
| 120 | - conferSendPdu.initiator = this._classInfo.nodeId;//发起人 | ||
| 121 | - conferSendPdu.peer = parseInt(_messageInfo.to);//发送给谁,公聊的时候是0,私聊的时候是指定的用户id | ||
| 122 | - | ||
| 123 | - conferSendPdu.userData = this._rCArrayBufferUtil.strToUint8Array("h5" + _messageInfo.message); | ||
| 124 | - //conferSendPdu.userData =UTF8.setBytesFromString(_messageInfo.message); | ||
| 125 | - conferSendPdu.isPublic = true; | ||
| 126 | - conferSendPdu.actionType=_messageInfo.actionType; | ||
| 127 | - // if (!(conferSendPdu.isPublic || 0 === conferSendPdu.peer)) { | ||
| 128 | - if (!conferSendPdu.isPublic && 0!=conferSendPdu.peer) { | ||
| 129 | - //发送给制定的人 | ||
| 130 | - loger.log('发送私聊会议消息.'); | ||
| 131 | - this.send(conferSendPdu); | ||
| 132 | - } else { | ||
| 133 | - //发送给所有人 | ||
| 134 | - loger.log('发送公聊会议消息.'); | ||
| 135 | - this.sendChatUniform(conferSendPdu); | 63 | + //加入会议 |
| 64 | + _joinSessionHandler(_data) { | ||
| 65 | + let nodeInfoRecordPdu = this.mcu.mcuClassInfo.self; | ||
| 66 | + loger.log("_joinSessionHandler nodeInfoRecordPdu="); | ||
| 67 | + console.log(nodeInfoRecordPdu); | ||
| 68 | + let userDataPdu = new pdu['RCNodeInfoUserDataPdu']; | ||
| 69 | + userDataPdu.qq = ''; | ||
| 70 | + userDataPdu.skype = ''; | ||
| 71 | + | ||
| 72 | + nodeInfoRecordPdu.userData = userDataPdu.toArrayBuffer(); | ||
| 73 | + nodeInfoRecordPdu.deviceType = GlobalConfig.deviceType;//设备类型 | ||
| 74 | + | ||
| 75 | + let item = new pdu['RCRegistryRosterItemPdu']; | ||
| 76 | + item.nodeId = nodeInfoRecordPdu.nodeId; | ||
| 77 | + item.nodeData = nodeInfoRecordPdu.toArrayBuffer(); | ||
| 78 | + | ||
| 79 | + let rosterUpdateItem = new pdu['RCRegistryRosterUpdateItemPdu']; | ||
| 80 | + rosterUpdateItem.type = pdu.RCPDU_REG_ROSTER_UPDATE_PDU; | ||
| 81 | + rosterUpdateItem.items.push(item); | ||
| 82 | + | ||
| 83 | + let updateObjPdu = new pdu['RCRegistryUpdateObjPdu']; | ||
| 84 | + updateObjPdu.objId = ApeConsts.CONFERENCE_OBJ_ROSTER_ID; | ||
| 85 | + updateObjPdu.subType = rosterUpdateItem.type; | ||
| 86 | + updateObjPdu.userData = rosterUpdateItem.toArrayBuffer(); | ||
| 87 | + | ||
| 88 | + //同步 | ||
| 89 | + let adapterItemPdu = new pdu['RCAdapterItemPdu']; | ||
| 90 | + adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ; | ||
| 91 | + adapterItemPdu.itemData = updateObjPdu.toArrayBuffer(); | ||
| 92 | + | ||
| 93 | + let adapterPdu = new pdu['RCAdapterPdu']; | ||
| 94 | + adapterPdu.type = pdu.RCPDU_REG_ADAPTER; | ||
| 95 | + adapterPdu.item.push(adapterItemPdu); | ||
| 96 | + this.sendUniform(adapterPdu, true); | ||
| 136 | } | 97 | } |
| 137 | - } | ||
| 138 | 98 | ||
| 139 | - //发送录制或停止录制的消息,{"recordStatus":true};true为开始录制,false为停止录制 | ||
| 140 | - sendConferRecordMsg(_param) { | ||
| 141 | - if(!this.mcu.connected){ | ||
| 142 | - loger.warn(GlobalConfig.getCurrentStatus()); | ||
| 143 | - return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"}; | 99 | + sendConferMsg(_messageInfo) { |
| 100 | + if (this._classInfo == null || EngineUtils.isEmptyObject(this._classInfo)) { | ||
| 101 | + loger.log('不能发送会议消息.McuClient还未初始化数据!'); | ||
| 102 | + if (GlobalConfig.getCurrentStatus().code == 0 || GlobalConfig.getCurrentStatus().code == 1) { | ||
| 103 | + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN); | ||
| 104 | + return; | ||
| 105 | + } | ||
| 106 | + return; | ||
| 107 | + } | ||
| 108 | + | ||
| 109 | + // to, message | ||
| 110 | + loger.log('发送会议消息.', _messageInfo); | ||
| 111 | + | ||
| 112 | + /* message RCConferenceSendDataRequestPdu { | ||
| 113 | + optional uint32 initiator = 1; | ||
| 114 | + optional uint32 peer = 2; | ||
| 115 | + required bool is_public = 3; | ||
| 116 | + required bytes user_data = 4; | ||
| 117 | + } | ||
| 118 | + */ | ||
| 119 | + | ||
| 120 | + let conferSendPdu = new pdu['RCConferenceSendDataRequestPdu']; | ||
| 121 | + conferSendPdu.type = pdu.RCPDU_SEND_CONFERENCE_DATA_REQUEST; | ||
| 122 | + conferSendPdu.initiator = this._classInfo.nodeId;//发起人 | ||
| 123 | + conferSendPdu.peer = parseInt(_messageInfo.to);//发送给谁,公聊的时候是0,私聊的时候是指定的用户id | ||
| 124 | + | ||
| 125 | + conferSendPdu.userData = this._rCArrayBufferUtil.strToUint8Array("h5" + _messageInfo.message); | ||
| 126 | + //conferSendPdu.userData =UTF8.setBytesFromString(_messageInfo.message); | ||
| 127 | + conferSendPdu.isPublic = true; | ||
| 128 | + conferSendPdu.actionType = _messageInfo.actionType; | ||
| 129 | + // if (!(conferSendPdu.isPublic || 0 === conferSendPdu.peer)) { | ||
| 130 | + if (!conferSendPdu.isPublic && 0 != conferSendPdu.peer) { | ||
| 131 | + //发送给制定的人 | ||
| 132 | + loger.log('发送私聊会议消息.'); | ||
| 133 | + this.send(conferSendPdu); | ||
| 134 | + } else { | ||
| 135 | + //发送给所有人 | ||
| 136 | + loger.log('发送公聊会议消息.'); | ||
| 137 | + this.sendChatUniform(conferSendPdu); | ||
| 138 | + } | ||
| 144 | } | 139 | } |
| 145 | - // to, message | ||
| 146 | - loger.log('发送录制消息.', _param); | ||
| 147 | 140 | ||
| 148 | - if(_param==null){ | ||
| 149 | - loger.warn("控制录制状的消息发送失败,参数错误",_param); | ||
| 150 | - return; | 141 | + //发送录制或停止录制的消息,{"recordStatus":true};true为开始录制,false为停止录制 |
| 142 | + sendConferRecordMsg(_param) { | ||
| 143 | + if (!this.mcu.connected) { | ||
| 144 | + loger.warn(GlobalConfig.getCurrentStatus()); | ||
| 145 | + return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"}; | ||
| 146 | + } | ||
| 147 | + // to, message | ||
| 148 | + loger.log('发送录制消息.', _param); | ||
| 149 | + | ||
| 150 | + if (_param == null) { | ||
| 151 | + loger.warn("控制录制状的消息发送失败,参数错误", _param); | ||
| 152 | + return; | ||
| 153 | + } | ||
| 154 | + | ||
| 155 | + /* message RCConferenceRecordRequestPdu { | ||
| 156 | + optional uint32 initiator = 1; // 发起录像指令的node id | ||
| 157 | + optional bool record = 2; // 录像指令 true:开始录像, false:停止录像 | ||
| 158 | + optional uint32 class_time = 3; // 课堂进行时间(秒) | ||
| 159 | + optional string filename = 4; // 录像文件名称,filename中增加目录部分 | ||
| 160 | + }*/ | ||
| 161 | + | ||
| 162 | + //保存当前的录制状态 | ||
| 163 | + GlobalConfig.recordStatus = _param.recordStatus || false; | ||
| 164 | + | ||
| 165 | + let conferRecordSendPdu = new pdu['RCConferenceRecordRequestPdu']; | ||
| 166 | + conferRecordSendPdu.type = pdu.RCPDU_CONFERENCE_RECORD_REQUEST; | ||
| 167 | + conferRecordSendPdu.peer = 0;//channel 为0 | ||
| 168 | + conferRecordSendPdu.isPublic = true; | ||
| 169 | + | ||
| 170 | + conferRecordSendPdu.initiator = this._classInfo.nodeId;//发起人 | ||
| 171 | + conferRecordSendPdu.record = GlobalConfig.recordStatus; | ||
| 172 | + conferRecordSendPdu.classTime = GlobalConfig.classTimestamp; | ||
| 173 | + conferRecordSendPdu.filename = GlobalConfig.recordFileName || GlobalConfig.classId + "_" + EngineUtils.creatTimestampYMD() + ".rec"; | ||
| 174 | + this.sendChatUniform(conferRecordSendPdu); | ||
| 151 | } | 175 | } |
| 152 | 176 | ||
| 153 | - /* message RCConferenceRecordRequestPdu { | ||
| 154 | - optional uint32 initiator = 1; // 发起录像指令的node id | ||
| 155 | - optional bool record = 2; // 录像指令 true:开始录像, false:停止录像 | ||
| 156 | - optional uint32 class_time = 3; // 课堂进行时间(秒) | ||
| 157 | - optional string filename = 4; // 录像文件名称,filename中增加目录部分 | ||
| 158 | - }*/ | ||
| 159 | - | ||
| 160 | - //保存当前的录制状态 | ||
| 161 | - GlobalConfig.recordStatus=_param.recordStatus||false; | ||
| 162 | - | ||
| 163 | - let conferRecordSendPdu = new pdu['RCConferenceRecordRequestPdu']; | ||
| 164 | - conferRecordSendPdu.type = pdu.RCPDU_CONFERENCE_RECORD_REQUEST; | ||
| 165 | - conferRecordSendPdu.peer = 0;//channel 为0 | ||
| 166 | - conferRecordSendPdu.isPublic = true; | ||
| 167 | - | ||
| 168 | - conferRecordSendPdu.initiator = this._classInfo.nodeId;//发起人 | ||
| 169 | - conferRecordSendPdu.record =GlobalConfig.recordStatus; | ||
| 170 | - conferRecordSendPdu.classTime=GlobalConfig.classTimestamp; | ||
| 171 | - conferRecordSendPdu.filename=GlobalConfig.recordFileName||GlobalConfig.classId+"_"+EngineUtils.creatTimestampYMD()+".rec"; | ||
| 172 | - this.sendChatUniform(conferRecordSendPdu); | ||
| 173 | - } | ||
| 174 | - | ||
| 175 | - //开启录制 | ||
| 176 | - startRecord(){ | ||
| 177 | - loger.log('startRecord',"isHost",GlobalConfig.isHost,"recordStatus",GlobalConfig.recordStatus); | ||
| 178 | - //如果是host | ||
| 179 | - if(GlobalConfig.isHost){ | ||
| 180 | - GlobalConfig.classStopTime=EngineUtils.creatTimestampStr(); | ||
| 181 | - this.sendConferRecordMsg({"recordStatus":true}); | ||
| 182 | - this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE); | ||
| 183 | - this._emit(MessageTypes.CLASS_RECORD_START);//会议开始录制 | 177 | + //开启录制 |
| 178 | + startRecord() { | ||
| 179 | + loger.log('startRecord', "isHost", GlobalConfig.isHost, "recordStatus", GlobalConfig.recordStatus); | ||
| 180 | + //如果是host | ||
| 181 | + if (GlobalConfig.isHost) { | ||
| 182 | + GlobalConfig.classStopTime = EngineUtils.creatTimestampStr(); | ||
| 183 | + this.sendConferRecordMsg({"recordStatus": true}); | ||
| 184 | + this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE); | ||
| 185 | + this._emit(MessageTypes.CLASS_RECORD_START);//会议开始录制 | ||
| 186 | + } | ||
| 184 | } | 187 | } |
| 185 | - } | ||
| 186 | - | ||
| 187 | - //停止录制 | ||
| 188 | - stopRecord(){ | ||
| 189 | - loger.log('stopRecord',"isHost",GlobalConfig.isHost,"recordStatus",GlobalConfig.recordStatus); | ||
| 190 | - //如果是host,并且当前正在录制中 | ||
| 191 | - if(GlobalConfig.isHost&&GlobalConfig.recordStatus){ | ||
| 192 | - GlobalConfig.classStopTime=EngineUtils.creatTimestampStr(); | ||
| 193 | - this.sendConferRecordMsg({"recordStatus":false}); | ||
| 194 | - this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE); | 188 | + |
| 189 | + //停止录制 | ||
| 190 | + stopRecord() { | ||
| 191 | + loger.log('stopRecord', "isHost", GlobalConfig.isHost, "recordStatus", GlobalConfig.recordStatus); | ||
| 192 | + //如果是host,并且当前正在录制中 | ||
| 193 | + if (GlobalConfig.isHost && GlobalConfig.recordStatus) { | ||
| 194 | + GlobalConfig.classStopTime = EngineUtils.creatTimestampStr(); | ||
| 195 | + this.sendConferRecordMsg({"recordStatus": false}); | ||
| 196 | + this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE); | ||
| 197 | + } | ||
| 195 | } | 198 | } |
| 196 | - } | ||
| 197 | - | ||
| 198 | - | ||
| 199 | - //主动离开会议,发送通知到服务器 | ||
| 200 | - leaveClass(){ | ||
| 201 | - let nodeInfoRecordPdu = this.mcu.mcuClassInfo.self; | ||
| 202 | - let userDataPdu = new pdu['RCNodeInfoUserDataPdu']; | ||
| 203 | - userDataPdu.qq = ''; | ||
| 204 | - userDataPdu.skype = ''; | ||
| 205 | - | ||
| 206 | - nodeInfoRecordPdu.userData = userDataPdu.toArrayBuffer(); | ||
| 207 | - nodeInfoRecordPdu.deviceType = GlobalConfig.deviceType; | ||
| 208 | - | ||
| 209 | - let item = new pdu['RCRegistryRosterItemPdu']; | ||
| 210 | - item.nodeId = nodeInfoRecordPdu.nodeId; | ||
| 211 | - item.nodeData = nodeInfoRecordPdu.toArrayBuffer(); | ||
| 212 | - | ||
| 213 | - let rosterUpdateItem = new pdu['RCRegistryRosterDeleteItemPdu']; | ||
| 214 | - rosterUpdateItem.type = pdu.RCPDU_REG_ROSTER_DELETE_PDU; | ||
| 215 | - rosterUpdateItem.nodeId=GlobalConfig.nodeId; | ||
| 216 | - | ||
| 217 | - let updateObjPdu = new pdu['RCRegistryUpdateObjPdu']; | ||
| 218 | - updateObjPdu.objId = ApeConsts.CONFERENCE_OBJ_ROSTER_ID; | ||
| 219 | - updateObjPdu.subType = rosterUpdateItem.type; | ||
| 220 | - updateObjPdu.userData = rosterUpdateItem.toArrayBuffer(); | ||
| 221 | - | ||
| 222 | - let adapterItemPdu = new pdu['RCAdapterItemPdu']; | ||
| 223 | - adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ; | ||
| 224 | - adapterItemPdu.itemData = updateObjPdu.toArrayBuffer(); | ||
| 225 | - | ||
| 226 | - let adapterPdu = new pdu['RCAdapterPdu']; | ||
| 227 | - adapterPdu.type = pdu.RCPDU_REG_ADAPTER; | ||
| 228 | - adapterPdu.item.push(adapterItemPdu); | ||
| 229 | - | ||
| 230 | - this.sendUniform(adapterPdu, true); | ||
| 231 | - } | ||
| 232 | - | ||
| 233 | - //还原课堂状态 | ||
| 234 | - restorClass(){ | ||
| 235 | - GlobalConfig.classTimestamp=0; | ||
| 236 | - GlobalConfig.classStatus=ApeConsts.CLASS_STATUS_WAIT; | ||
| 237 | - GlobalConfig.classStopTime=EngineUtils.creatTimestampStr(); | ||
| 238 | - this.stopRecord(); | ||
| 239 | - this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE); | ||
| 240 | - this.sendUpdaterClassStatusInfo({"actionType":0}); | ||
| 241 | - loger.log('restorClass'); | ||
| 242 | - } | ||
| 243 | - | ||
| 244 | - //开始上课 | ||
| 245 | - startClass(_param){ | ||
| 246 | - if(GlobalConfig.isHost){ | ||
| 247 | - | ||
| 248 | - let timestamp=EngineUtils.creatTimestampStr(); | ||
| 249 | - GlobalConfig.classStopTime=timestamp; | ||
| 250 | - | ||
| 251 | - //如果录制的文件名不存在,需要创建一个名字 | ||
| 252 | - let timestampYMD=EngineUtils.creatTimestampYMD(); | ||
| 253 | - GlobalConfig.recordFileName=GlobalConfig.recordFileName|| | ||
| 254 | - GlobalConfig.siteId+"/"+timestampYMD+"/" | ||
| 255 | - +GlobalConfig.classId+"_"+timestampYMD+".rec";//4、文件名称 $RECORD_HOME/`site id`/`日期`/`filename` 例:/data/record/su/20161216/`filename` | ||
| 256 | - | ||
| 257 | - if(GlobalConfig.classStatus==ApeConsts.CLASS_STATUS_WAIT){ | ||
| 258 | - //之前是为开始状态,第一次点开始 | ||
| 259 | - GlobalConfig.classStartTime=timestamp; | ||
| 260 | - } | ||
| 261 | - | ||
| 262 | - GlobalConfig.classStatus=ApeConsts.CLASS_STATUS_STARTED; | ||
| 263 | - //开始录制 | ||
| 264 | - this.startRecord(); | ||
| 265 | - //会议状态改变 | ||
| 266 | - this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE); | ||
| 267 | - //同步会议状态 | ||
| 268 | - this.sendUpdaterClassStatusInfo({"actionType":1}); | ||
| 269 | - | ||
| 270 | - //开始计时 | ||
| 271 | - this.startTimerCounter(); | ||
| 272 | - }else { | ||
| 273 | - loger.warn('没有权限'); | 199 | + |
| 200 | + | ||
| 201 | + //主动离开会议,发送通知到服务器 | ||
| 202 | + leaveClass() { | ||
| 203 | + let nodeInfoRecordPdu = this.mcu.mcuClassInfo.self; | ||
| 204 | + let userDataPdu = new pdu['RCNodeInfoUserDataPdu']; | ||
| 205 | + userDataPdu.qq = ''; | ||
| 206 | + userDataPdu.skype = ''; | ||
| 207 | + | ||
| 208 | + nodeInfoRecordPdu.userData = userDataPdu.toArrayBuffer(); | ||
| 209 | + nodeInfoRecordPdu.deviceType = GlobalConfig.deviceType; | ||
| 210 | + | ||
| 211 | + let item = new pdu['RCRegistryRosterItemPdu']; | ||
| 212 | + item.nodeId = nodeInfoRecordPdu.nodeId; | ||
| 213 | + item.nodeData = nodeInfoRecordPdu.toArrayBuffer(); | ||
| 214 | + | ||
| 215 | + let rosterUpdateItem = new pdu['RCRegistryRosterDeleteItemPdu']; | ||
| 216 | + rosterUpdateItem.type = pdu.RCPDU_REG_ROSTER_DELETE_PDU; | ||
| 217 | + rosterUpdateItem.nodeId = GlobalConfig.nodeId; | ||
| 218 | + | ||
| 219 | + let updateObjPdu = new pdu['RCRegistryUpdateObjPdu']; | ||
| 220 | + updateObjPdu.objId = ApeConsts.CONFERENCE_OBJ_ROSTER_ID; | ||
| 221 | + updateObjPdu.subType = rosterUpdateItem.type; | ||
| 222 | + updateObjPdu.userData = rosterUpdateItem.toArrayBuffer(); | ||
| 223 | + | ||
| 224 | + let adapterItemPdu = new pdu['RCAdapterItemPdu']; | ||
| 225 | + adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ; | ||
| 226 | + adapterItemPdu.itemData = updateObjPdu.toArrayBuffer(); | ||
| 227 | + | ||
| 228 | + let adapterPdu = new pdu['RCAdapterPdu']; | ||
| 229 | + adapterPdu.type = pdu.RCPDU_REG_ADAPTER; | ||
| 230 | + adapterPdu.item.push(adapterItemPdu); | ||
| 231 | + | ||
| 232 | + this.sendUniform(adapterPdu, true); | ||
| 274 | } | 233 | } |
| 275 | - } | ||
| 276 | - //暂停上课 | ||
| 277 | - pauseClass(_param){ | ||
| 278 | - if(GlobalConfig.classStatus==ApeConsts.CLASS_STATUS_WAIT){ | ||
| 279 | - loger.warn('还没有开始,不能点暂停'); | ||
| 280 | - return; | 234 | + |
| 235 | + //还原课堂状态 | ||
| 236 | + restorClass() { | ||
| 237 | + GlobalConfig.classTimestamp = 0; | ||
| 238 | + GlobalConfig.classStatus = ApeConsts.CLASS_STATUS_WAIT; | ||
| 239 | + GlobalConfig.classStopTime = EngineUtils.creatTimestampStr(); | ||
| 240 | + this.stopRecord(); | ||
| 241 | + this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE); | ||
| 242 | + this.sendUpdaterClassStatusInfo({"actionType": 0}); | ||
| 243 | + loger.log('restorClass'); | ||
| 281 | } | 244 | } |
| 282 | 245 | ||
| 283 | - GlobalConfig.classStatus=ApeConsts.CLASS_STATUS_PAUSE; | ||
| 284 | - GlobalConfig.classStopTime=EngineUtils.creatTimestampStr(); | ||
| 285 | - | ||
| 286 | - this.stopRecord(); | ||
| 287 | - this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE); | ||
| 288 | - this.sendUpdaterClassStatusInfo({"actionType":2}); | ||
| 289 | - this.stopTimerCounter(); | ||
| 290 | - } | ||
| 291 | - //关闭课堂 | ||
| 292 | - closeClass(_param){ | ||
| 293 | - if(GlobalConfig.classStatus==ApeConsts.CLASS_STATUS_WAIT){ | ||
| 294 | - loger.warn('还没有开始,不能点关闭'); | ||
| 295 | - return; | 246 | + //开始上课 |
| 247 | + startClass(_param) { | ||
| 248 | + if (GlobalConfig.isHost) { | ||
| 249 | + | ||
| 250 | + let timestamp = EngineUtils.creatTimestampStr(); | ||
| 251 | + GlobalConfig.classStopTime = timestamp; | ||
| 252 | + | ||
| 253 | + //如果录制的文件名不存在,需要创建一个名字 | ||
| 254 | + let timestampYMD = EngineUtils.creatTimestampYMD(); | ||
| 255 | + GlobalConfig.recordFileName = GlobalConfig.recordFileName || | ||
| 256 | + GlobalConfig.siteId + "/" + timestampYMD + "/" | ||
| 257 | + + GlobalConfig.classId + "_" + timestampYMD + ".rec";//4、文件名称 $RECORD_HOME/`site id`/`日期`/`filename` 例:/data/record/su/20161216/`filename` | ||
| 258 | + | ||
| 259 | + if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_WAIT) { | ||
| 260 | + //之前是为开始状态,第一次点开始 | ||
| 261 | + GlobalConfig.classStartTime = timestamp; | ||
| 262 | + } | ||
| 263 | + | ||
| 264 | + GlobalConfig.classStatus = ApeConsts.CLASS_STATUS_STARTED; | ||
| 265 | + //开始录制 | ||
| 266 | + this.startRecord(); | ||
| 267 | + //会议状态改变 | ||
| 268 | + this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE); | ||
| 269 | + //同步会议状态 | ||
| 270 | + this.sendUpdaterClassStatusInfo({"actionType": 1}); | ||
| 271 | + | ||
| 272 | + //开始计时 | ||
| 273 | + this.startTimerCounter(); | ||
| 274 | + } else { | ||
| 275 | + loger.warn('没有权限'); | ||
| 276 | + } | ||
| 296 | } | 277 | } |
| 297 | 278 | ||
| 298 | - this.stopTimerCounter(); | ||
| 299 | - this.restorClass(); | ||
| 300 | - //把所有人都踢出课堂 | ||
| 301 | - this.sendConferMsg({"to":0,"message":"所有人退出会议","actionType":ApeConsts.CLASS_ACTION_CLOSE_ALL}); | ||
| 302 | - } | 279 | + //暂停上课 |
| 280 | + pauseClass(_param) { | ||
| 281 | + if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_WAIT) { | ||
| 282 | + loger.warn('还没有开始,不能点暂停'); | ||
| 283 | + return; | ||
| 284 | + } | ||
| 303 | 285 | ||
| 286 | + GlobalConfig.classStatus = ApeConsts.CLASS_STATUS_PAUSE; | ||
| 287 | + GlobalConfig.classStopTime = EngineUtils.creatTimestampStr(); | ||
| 304 | 288 | ||
| 305 | - //更新会议信息 | ||
| 306 | - sendUpdaterClassStatusInfo(_param){ | ||
| 307 | - loger.log('sendUpdaterClassStatusInfo'); | ||
| 308 | - if(_param==null||EngineUtils.isEmptyObject(_param)){ | ||
| 309 | - loger.log('sendUpdaterClassStatusInfo,参数错误'); | ||
| 310 | - this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG); | ||
| 311 | - return ; | 289 | + this.stopRecord(); |
| 290 | + this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE); | ||
| 291 | + this.sendUpdaterClassStatusInfo({"actionType": 2}); | ||
| 292 | + this.stopTimerCounter(); | ||
| 312 | } | 293 | } |
| 313 | - itemIdx=ApeConsts.CONFERENCE_OBJ_TABLE_ID;// itemIdx=_param.itemIdx; | ||
| 314 | - let modelPdu = this.packPdu(_param,itemIdx); | ||
| 315 | - //loger.log('sendUpdaterClassStatusInfo----2------'); | ||
| 316 | - console.log(modelPdu); | ||
| 317 | - | ||
| 318 | - if(modelPdu==null){ | ||
| 319 | - loger.log('sendUpdaterClassStatusInfo,参数错误'); | ||
| 320 | - this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG); | ||
| 321 | - return ; | 294 | + |
| 295 | + //关闭课堂 | ||
| 296 | + closeClass(_param) { | ||
| 297 | + if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_WAIT) { | ||
| 298 | + loger.warn('还没有开始,不能点关闭'); | ||
| 299 | + return; | ||
| 300 | + } | ||
| 301 | + | ||
| 302 | + this.stopTimerCounter(); | ||
| 303 | + this.restorClass(); | ||
| 304 | + //把所有人都踢出课堂 | ||
| 305 | + this.sendConferMsg({"to": 0, "message": "所有人退出会议", "actionType": ApeConsts.CLASS_ACTION_CLOSE_ALL}); | ||
| 322 | } | 306 | } |
| 323 | 307 | ||
| 324 | - let tableItemPdu = new pdu['RCRegistryTableItemPdu']; | ||
| 325 | - tableItemPdu.itemIdx=itemIdx; | ||
| 326 | - tableItemPdu.owner = 0;//收到flash的是这个值,不清楚先写固定 | ||
| 327 | - tableItemPdu.registerObjId=ApeConsts.CONFERENCE_OBJ_TABLE_ID; | ||
| 328 | - tableItemPdu.itemData =modelPdu.toArrayBuffer(); | ||
| 329 | 308 | ||
| 309 | + //更新会议信息 | ||
| 310 | + sendUpdaterClassStatusInfo(_param) { | ||
| 311 | + loger.log('sendUpdaterClassStatusInfo'); | ||
| 312 | + if (_param == null || EngineUtils.isEmptyObject(_param)) { | ||
| 313 | + loger.log('sendUpdaterClassStatusInfo,参数错误'); | ||
| 314 | + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG); | ||
| 315 | + return; | ||
| 316 | + } | ||
| 317 | + itemIdx = ApeConsts.CONFERENCE_OBJ_TABLE_ID;// itemIdx=_param.itemIdx; | ||
| 318 | + let modelPdu = this.packPdu(_param, itemIdx); | ||
| 319 | + //loger.log('sendUpdaterClassStatusInfo----2------'); | ||
| 320 | + console.log(modelPdu); | ||
| 321 | + | ||
| 322 | + if (modelPdu == null) { | ||
| 323 | + loger.log('sendUpdaterClassStatusInfo,参数错误'); | ||
| 324 | + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG); | ||
| 325 | + return; | ||
| 326 | + } | ||
| 327 | + | ||
| 328 | + let tableItemPdu = new pdu['RCRegistryTableItemPdu']; | ||
| 329 | + tableItemPdu.itemIdx = itemIdx; | ||
| 330 | + tableItemPdu.owner = 0;//收到flash的是这个值,不清楚先写固定 | ||
| 331 | + tableItemPdu.registerObjId = ApeConsts.CONFERENCE_OBJ_TABLE_ID; | ||
| 332 | + tableItemPdu.itemData = modelPdu.toArrayBuffer(); | ||
| 330 | 333 | ||
| 331 | - //updater | ||
| 332 | - let tableUpdateItem = new pdu['RCRegistryTableUpdateItemPdu']; | ||
| 333 | - //optional RCPduType_E type = 1 [default = RCPDU_REG_TABLE_UPDATE_PDU]; | ||
| 334 | - //repeated RCRegistryTableItemPdu items = 2; | ||
| 335 | - tableUpdateItem.type = pdu.RCPDU_REG_TABLE_UPDATE_PDU;// | ||
| 336 | - tableUpdateItem.items.push(tableItemPdu); | ||
| 337 | 334 | ||
| 335 | + //updater | ||
| 336 | + let tableUpdateItem = new pdu['RCRegistryTableUpdateItemPdu']; | ||
| 337 | + //optional RCPduType_E type = 1 [default = RCPDU_REG_TABLE_UPDATE_PDU]; | ||
| 338 | + //repeated RCRegistryTableItemPdu items = 2; | ||
| 339 | + tableUpdateItem.type = pdu.RCPDU_REG_TABLE_UPDATE_PDU;// | ||
| 340 | + tableUpdateItem.items.push(tableItemPdu); | ||
| 338 | 341 | ||
| 339 | - let updateObjPdu = new pdu['RCRegistryUpdateObjPdu']; | ||
| 340 | - updateObjPdu.objId = ApeConsts.CONFERENCE_OBJ_TABLE_ID; | ||
| 341 | - updateObjPdu.subType = tableUpdateItem.type; | ||
| 342 | - updateObjPdu.userData = tableUpdateItem.toArrayBuffer(); | ||
| 343 | 342 | ||
| 344 | - //同步 | ||
| 345 | - let adapterItemPdu = new pdu['RCAdapterItemPdu']; | ||
| 346 | - adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ; | ||
| 347 | - adapterItemPdu.itemData = updateObjPdu.toArrayBuffer(); | 343 | + let updateObjPdu = new pdu['RCRegistryUpdateObjPdu']; |
| 344 | + updateObjPdu.objId = ApeConsts.CONFERENCE_OBJ_TABLE_ID; | ||
| 345 | + updateObjPdu.subType = tableUpdateItem.type; | ||
| 346 | + updateObjPdu.userData = tableUpdateItem.toArrayBuffer(); | ||
| 348 | 347 | ||
| 349 | - let adapterPdu = new pdu['RCAdapterPdu']; | ||
| 350 | - adapterPdu.type = pdu.RCPDU_REG_ADAPTER; | ||
| 351 | - adapterPdu.item.push(adapterItemPdu); | 348 | + //同步 |
| 349 | + let adapterItemPdu = new pdu['RCAdapterItemPdu']; | ||
| 350 | + adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ; | ||
| 351 | + adapterItemPdu.itemData = updateObjPdu.toArrayBuffer(); | ||
| 352 | 352 | ||
| 353 | - console.log("会议发送更新数据============"); | ||
| 354 | - this.sendUniform(adapterPdu,true); | ||
| 355 | - } | 353 | + let adapterPdu = new pdu['RCAdapterPdu']; |
| 354 | + adapterPdu.type = pdu.RCPDU_REG_ADAPTER; | ||
| 355 | + adapterPdu.item.push(adapterItemPdu); | ||
| 356 | + | ||
| 357 | + console.log("会议发送更新数据============"); | ||
| 358 | + this.sendUniform(adapterPdu, true); | ||
| 359 | + } | ||
| 356 | 360 | ||
| 357 | 361 | ||
| 358 | - /////收到消息处理///////////////////////////////////////////////////////////////////////////////// | ||
| 359 | - //加入channel成功 | ||
| 360 | - onJoinChannelHandlerSuccess(){ | ||
| 361 | - loger.log('ConferApe.onJoinChannelHandlerSuccess',GlobalConfig.classStatus); | ||
| 362 | - this.timerCounter.addTimerCallBack(this.timerCounterUptate.bind(this),1); | ||
| 363 | - //如果当前会议正在进行中,开启计时器 | ||
| 364 | - if(GlobalConfig.classStatus==ApeConsts.CLASS_STATUS_STARTED){ | ||
| 365 | - //开始计时 | ||
| 366 | - this.startTimerCounter(); | 362 | + /////收到消息处理///////////////////////////////////////////////////////////////////////////////// |
| 363 | + //加入channel成功 | ||
| 364 | + onJoinChannelHandlerSuccess() { | ||
| 365 | + loger.log('ConferApe.onJoinChannelHandlerSuccess', GlobalConfig.classStatus); | ||
| 366 | + this.timerCounter.addTimerCallBack(this.timerCounterUptate.bind(this), 1); | ||
| 367 | + //如果当前会议正在进行中,开启计时器 | ||
| 368 | + if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_STARTED) { | ||
| 369 | + //开始计时 | ||
| 370 | + this.startTimerCounter(); | ||
| 367 | 371 | ||
| 368 | - //如果是host ,开始录制 | ||
| 369 | - this.startRecord(); | 372 | + //如果是host ,开始录制 |
| 373 | + this.startRecord(); | ||
| 374 | + } | ||
| 370 | } | 375 | } |
| 371 | - } | ||
| 372 | - //开启计时器 | ||
| 373 | - startTimerCounter(){ | ||
| 374 | - this.timerCounter.startTimer(); | ||
| 375 | - } | ||
| 376 | - //停止计时器 | ||
| 377 | - stopTimerCounter(){ | ||
| 378 | - this.timerCounter.stopTimer(); | ||
| 379 | - } | ||
| 380 | - timerCounterUptate(){ | ||
| 381 | - if(!this.mcu.connected){ | ||
| 382 | - loger.warn('MCU 连接已经断开'); | ||
| 383 | - this.stopTimerCounter(); | 376 | + |
| 377 | + //开启计时器 | ||
| 378 | + startTimerCounter() { | ||
| 379 | + this.timerCounter.startTimer(); | ||
| 384 | } | 380 | } |
| 385 | - //如果还没开始或已经暂停、关闭,不做计时处理 | ||
| 386 | - if(GlobalConfig.classStatus!=ApeConsts.CLASS_STATUS_STARTED){ | ||
| 387 | - loger.warn('当前课堂已经暂停或者未开始,不计时',"classStatus-->",GlobalConfig.classStatus); | ||
| 388 | - return; | 381 | + |
| 382 | + //停止计时器 | ||
| 383 | + stopTimerCounter() { | ||
| 384 | + this.timerCounter.stopTimer(); | ||
| 389 | } | 385 | } |
| 390 | - GlobalConfig.classTimestamp=GlobalConfig.classTimestamp+1;//计时 | ||
| 391 | - //loger.log('课堂进行时间',GlobalConfig.classTimestamp); | ||
| 392 | - this._emit(MessageTypes.CLASS_UPDATE_TIMER,{"classTimestamp":GlobalConfig.classTimestamp}); | ||
| 393 | - | ||
| 394 | - if(GlobalConfig.classTimestamp%GlobalConfig.updateClassInfoDelay==0){ | ||
| 395 | - //如果是host身份,需要同步时间给其他人,同时把当前的状态上传到服务器 | ||
| 396 | - if(GlobalConfig.isHost){ | ||
| 397 | - //保存数据到Sass | ||
| 398 | - this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE); | ||
| 399 | - | ||
| 400 | - //同步消息给其他人 | ||
| 401 | - this.sendUpdaterClassStatusInfo({"actionType":1}); | 386 | + |
| 387 | + timerCounterUptate() { | ||
| 388 | + if (!this.mcu.connected) { | ||
| 389 | + loger.warn('MCU 连接已经断开'); | ||
| 390 | + this.stopTimerCounter(); | ||
| 391 | + } | ||
| 392 | + //如果还没开始或已经暂停、关闭,不做计时处理 | ||
| 393 | + if (GlobalConfig.classStatus != ApeConsts.CLASS_STATUS_STARTED) { | ||
| 394 | + loger.warn('当前课堂已经暂停或者未开始,不计时', "classStatus-->", GlobalConfig.classStatus); | ||
| 395 | + return; | ||
| 396 | + } | ||
| 397 | + GlobalConfig.classTimestamp = GlobalConfig.classTimestamp + 1;//计时 | ||
| 398 | + //loger.log('课堂进行时间',GlobalConfig.classTimestamp); | ||
| 399 | + this._emit(MessageTypes.CLASS_UPDATE_TIMER, {"classTimestamp": GlobalConfig.classTimestamp}); | ||
| 400 | + | ||
| 401 | + if (GlobalConfig.classTimestamp % GlobalConfig.updateClassInfoDelay == 0) { | ||
| 402 | + //如果是host身份,需要同步时间给其他人,同时把当前的状态上传到服务器 | ||
| 403 | + if (GlobalConfig.isHost) { | ||
| 404 | + //保存数据到Sass | ||
| 405 | + this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE); | ||
| 406 | + | ||
| 407 | + //同步消息给其他人 | ||
| 408 | + this.sendUpdaterClassStatusInfo({"actionType": 1}); | ||
| 409 | + } | ||
| 402 | } | 410 | } |
| 403 | } | 411 | } |
| 404 | - } | ||
| 405 | - | ||
| 406 | - tableUpdateHandler(owner, itemIdx, itemData) { | ||
| 407 | - try { | ||
| 408 | - let model=this.unPackPdu(owner, itemIdx,itemData); | ||
| 409 | - loger.log('tableUpdateHandler'); | ||
| 410 | - console.log(model); | ||
| 411 | - | ||
| 412 | - //处理会议更新的信息 | ||
| 413 | - if(model&&model.classStatusInfo){ | ||
| 414 | - GlobalConfig.setClassStatusInfo(model.classStatusInfo); | ||
| 415 | - } | ||
| 416 | - //通知应用层更新会议状态 | ||
| 417 | - this._emit(MessageTypes.CLASS_UPTATE_STATUS,GlobalConfig.classStatusInfo); | ||
| 418 | - | ||
| 419 | - //如果MCU已经断开连接,停止计时器 | ||
| 420 | - if(!this.mcu.connected){ | ||
| 421 | - //停止计时 | ||
| 422 | - this.stopTimerCounter(); | ||
| 423 | - return; | ||
| 424 | - } | ||
| 425 | - | ||
| 426 | - if(GlobalConfig.classStatus==ApeConsts.CLASS_STATUS_STARTED){ | ||
| 427 | - //如果会议在进行中,开始计时器 | ||
| 428 | - this.startTimerCounter(); | ||
| 429 | - }else { | ||
| 430 | - //停止计时 | ||
| 431 | - this.stopTimerCounter(); | ||
| 432 | - } | ||
| 433 | - } catch (e) { | ||
| 434 | - loger.warn('ConferApe table update got exception. itemIdx',itemIdx); | ||
| 435 | - } | ||
| 436 | - } | ||
| 437 | - | ||
| 438 | - | ||
| 439 | - conferMsgComingHandler(_data) { | ||
| 440 | - //flash RCConferenceSendDataRequestPdu | ||
| 441 | - //loger.warn('conferMsgComingHandler needs to be handled.'); | ||
| 442 | - //const recordInfo = pdu['RCWhiteboardDataRequestPdu'].decode(pdu); | ||
| 443 | - //loger.log("conferMsgComingHandler",recordInfo); | ||
| 444 | - | ||
| 445 | - var chatReceivePdu = pdu['RCConferenceSendDataRequestPdu'].decode(_data); | ||
| 446 | - | ||
| 447 | - var chatMsg = {}; | ||
| 448 | - chatMsg.fromNodeID = chatReceivePdu.initiator; | ||
| 449 | - chatMsg.toNodeID = chatReceivePdu.peer; | ||
| 450 | - chatMsg.message = this._rCArrayBufferUtil.uint8ArrayToStr(chatReceivePdu.userData, 2); | ||
| 451 | - chatMsg.actionType=chatReceivePdu.actionType; | ||
| 452 | - loger.log("conferMsgComingHandler",chatMsg); | ||
| 453 | - switch (chatMsg.actionType){ | ||
| 454 | - case ApeConsts.CLASS_ACTION_CLOSE_ALL: | ||
| 455 | - loger.log(chatMsg.message); | ||
| 456 | - //会议关闭,所有人都退出 | ||
| 457 | - this._emit(MessageTypes.CLASS_EXIT); | ||
| 458 | - break; | ||
| 459 | - default: | ||
| 460 | - break; | ||
| 461 | - } | ||
| 462 | - } | ||
| 463 | - | ||
| 464 | - onSendConferRecordRequestHandler(_data){ | ||
| 465 | - loger.log("onSendConferRecordRequestHandler"); | ||
| 466 | - try{ | ||
| 467 | - let conferRecordSendPdu =pdu['RCConferenceRecordRequestPdu'].decode(_data); | ||
| 468 | - console.log(conferRecordSendPdu); | ||
| 469 | - }catch (err){ | ||
| 470 | - loger.warn("onSendConferRecordRequestHandler err",err.message); | 412 | + |
| 413 | + tableUpdateHandler(owner, itemIdx, itemData) { | ||
| 414 | + try { | ||
| 415 | + let model = this.unPackPdu(owner, itemIdx, itemData); | ||
| 416 | + loger.log('tableUpdateHandler'); | ||
| 417 | + console.log(model); | ||
| 418 | + | ||
| 419 | + //处理会议更新的信息 | ||
| 420 | + if (model && model.classStatusInfo) { | ||
| 421 | + GlobalConfig.setClassStatusInfo(model.classStatusInfo); | ||
| 422 | + } | ||
| 423 | + //通知应用层更新会议状态 | ||
| 424 | + this._emit(MessageTypes.CLASS_UPTATE_STATUS, GlobalConfig.classStatusInfo); | ||
| 425 | + | ||
| 426 | + //如果MCU已经断开连接,停止计时器 | ||
| 427 | + if (!this.mcu.connected) { | ||
| 428 | + //停止计时 | ||
| 429 | + this.stopTimerCounter(); | ||
| 430 | + return; | ||
| 431 | + } | ||
| 432 | + | ||
| 433 | + if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_STARTED) { | ||
| 434 | + //如果会议在进行中,开始计时器 | ||
| 435 | + this.startTimerCounter(); | ||
| 436 | + } else { | ||
| 437 | + //停止计时 | ||
| 438 | + this.stopTimerCounter(); | ||
| 439 | + } | ||
| 440 | + } catch (e) { | ||
| 441 | + loger.warn('ConferApe table update got exception. itemIdx', itemIdx); | ||
| 442 | + } | ||
| 471 | } | 443 | } |
| 472 | 444 | ||
| 473 | - } | ||
| 474 | 445 | ||
| 475 | - rosterInsertHandler(nodeId, nodeData) { | ||
| 476 | - if(GlobalConfig.nodeId==nodeId){ | ||
| 477 | - loger.log("自己加入 rosterInsertHandler"); | ||
| 478 | - }else { | ||
| 479 | - loger.log("有人加入 rosterInsertHandler"); | ||
| 480 | - this.rosterUpdateHandler(nodeId, nodeData); | ||
| 481 | - } | ||
| 482 | - } | ||
| 483 | - | ||
| 484 | - //更新人员列表数据 | ||
| 485 | - rosterUpdateHandler(nodeId, nodeData) { | ||
| 486 | - if (nodeData.role === ApeConsts.NR_MASTER || | ||
| 487 | - nodeData.role === ApeConsts.NR_SLAVE) { | ||
| 488 | - this.hostNodeId = nodeData.nodeId; | ||
| 489 | - this.hostUserId = nodeData.userId; | 446 | + conferMsgComingHandler(_data) { |
| 447 | + //flash RCConferenceSendDataRequestPdu | ||
| 448 | + //loger.warn('conferMsgComingHandler needs to be handled.'); | ||
| 449 | + //const recordInfo = pdu['RCWhiteboardDataRequestPdu'].decode(pdu); | ||
| 450 | + //loger.log("conferMsgComingHandler",recordInfo); | ||
| 451 | + | ||
| 452 | + var chatReceivePdu = pdu['RCConferenceSendDataRequestPdu'].decode(_data); | ||
| 453 | + | ||
| 454 | + var chatMsg = {}; | ||
| 455 | + chatMsg.fromNodeID = chatReceivePdu.initiator; | ||
| 456 | + chatMsg.toNodeID = chatReceivePdu.peer; | ||
| 457 | + chatMsg.message = this._rCArrayBufferUtil.uint8ArrayToStr(chatReceivePdu.userData, 2); | ||
| 458 | + chatMsg.actionType = chatReceivePdu.actionType; | ||
| 459 | + loger.log("conferMsgComingHandler", chatMsg); | ||
| 460 | + switch (chatMsg.actionType) { | ||
| 461 | + case ApeConsts.CLASS_ACTION_CLOSE_ALL: | ||
| 462 | + loger.log(chatMsg.message); | ||
| 463 | + //收到会议关闭,所有人都退出,执行自己关闭的流程 | ||
| 464 | + this._emit(MessageTypes.CLASS_EXIT); | ||
| 465 | + break; | ||
| 466 | + default: | ||
| 467 | + break; | ||
| 468 | + } | ||
| 490 | } | 469 | } |
| 491 | - if (nodeData.role === ApeConsts.NR_NORMAL && | ||
| 492 | - this.hostNodeId === nodeData.nodeId) { | ||
| 493 | - this.hostNodeId = -1; | ||
| 494 | - this.hostUserId = ''; | 470 | + |
| 471 | + onSendConferRecordRequestHandler(_data) { | ||
| 472 | + loger.log("onSendConferRecordRequestHandler"); | ||
| 473 | + try { | ||
| 474 | + let conferRecordSendPdu = pdu['RCConferenceRecordRequestPdu'].decode(_data); | ||
| 475 | + console.log(conferRecordSendPdu); | ||
| 476 | + } catch (err) { | ||
| 477 | + loger.warn("onSendConferRecordRequestHandler err", err.message); | ||
| 478 | + } | ||
| 479 | + | ||
| 495 | } | 480 | } |
| 496 | 481 | ||
| 497 | - //判断进入的用户身份,如果进入的人身份是host,助教,监课,并且和自己的身份冲突,自己会被踢掉 | 482 | + rosterInsertHandler(nodeId, nodeData) { |
| 483 | + if (GlobalConfig.nodeId == nodeId) { | ||
| 484 | + loger.log("自己加入 rosterInsertHandler"); | ||
| 485 | + } else { | ||
| 486 | + loger.log("有人加入 rosterInsertHandler"); | ||
| 487 | + this.rosterUpdateHandler(nodeId, nodeData); | ||
| 488 | + } | ||
| 489 | + } | ||
| 498 | 490 | ||
| 491 | + //更新人员列表数据 | ||
| 492 | + rosterUpdateHandler(nodeId, nodeData) { | ||
| 493 | + //如果是自己的信息,不处理跳过 | ||
| 494 | + if (nodeId == GlobalConfig.nodeId) { | ||
| 495 | + loger.log("自己加入课堂的消息,不需要处理"); | ||
| 496 | + this.rosters[nodeId] = nodeData; | ||
| 497 | + return; | ||
| 498 | + } | ||
| 499 | 499 | ||
| 500 | - let rosterExists = this.rosters[nodeId]; | ||
| 501 | - this.rosters[nodeId] = nodeData; | ||
| 502 | - let userDataObj=null; | ||
| 503 | - if (!rosterExists) { | ||
| 504 | - try{ | ||
| 505 | - userDataObj=pdu['RCNodeInfoUserDataPdu'].decode(nodeData.userData); | ||
| 506 | - }catch (err){ | ||
| 507 | - loger.log("RCNodeInfoUserDataPdu decode err",err.message); | ||
| 508 | - } | 500 | + loger.log(nodeId, "加入课堂,role-->", nodeData.role, ApeConsts.userTypes[nodeData.role]); |
| 501 | + | ||
| 502 | + //新加入的人员不是自己 | ||
| 503 | + //1.判断进入的用户身份,如果进入的人身份是host,助教,监课,并且和自己的身份冲突,自己会被踢掉 | ||
| 504 | + //2.最后进入的人会踢掉之前进入的人,nodeId是按时间戳生成的,最后进入的人nodeId的值比之前进入的人大 | ||
| 505 | + if (parseInt(nodeId) > GlobalConfig.nodeId) { | ||
| 506 | + if (nodeData.role == ApeConsts.NR_HOST && GlobalConfig.isHost) { | ||
| 507 | + this.kickOutRoster(); | ||
| 508 | + return; | ||
| 509 | + } else if (nodeData.role == ApeConsts.NR_PRESENTER && GlobalConfig.isPresenter) { | ||
| 510 | + this.kickOutRoster(); | ||
| 511 | + return; | ||
| 512 | + } else if (nodeData.role == ApeConsts.NR_ASSISTANT && GlobalConfig.isAssistant) { | ||
| 513 | + this.kickOutRoster(); | ||
| 514 | + return; | ||
| 515 | + } else if (nodeData.role == ApeConsts.NR_INVISIBLE && GlobalConfig.isInvisible) { | ||
| 516 | + this.kickOutRoster(); | ||
| 517 | + return; | ||
| 518 | + } | ||
| 519 | + } | ||
| 509 | 520 | ||
| 510 | - let newNodeData=nodeData; | ||
| 511 | - newNodeData.userData=userDataObj; | ||
| 512 | - loger.log("更新人员列表数据 rosterUpdateHandler",{"nodeId":nodeId}); | ||
| 513 | - this._emit(MessageTypes.CLASS_INSERT_ROSTER, {"nodeId":nodeId,"nodeData":newNodeData}); | ||
| 514 | - this.emitRosterChange(); | ||
| 515 | 521 | ||
| 522 | + //处理用户信息 | ||
| 523 | + let rosterExists = this.rosters[nodeId]; | ||
| 524 | + this.rosters[nodeId] = nodeData; | ||
| 525 | + let userDataObj = null; | ||
| 526 | + if (!rosterExists) { | ||
| 527 | + try { | ||
| 528 | + userDataObj = pdu['RCNodeInfoUserDataPdu'].decode(nodeData.userData); | ||
| 529 | + } catch (err) { | ||
| 530 | + loger.log("RCNodeInfoUserDataPdu decode err", err.message); | ||
| 531 | + } | ||
| 532 | + | ||
| 533 | + let newNodeData = nodeData; | ||
| 534 | + newNodeData.userData = userDataObj; | ||
| 535 | + this._emit(MessageTypes.CLASS_INSERT_ROSTER, {"nodeId": nodeId, "nodeData": newNodeData}); | ||
| 536 | + this.emitRosterChange(); | ||
| 537 | + } else { | ||
| 538 | + //loger.log("更新人员列表数据,rosterExists已经存在",rosterExists); | ||
| 539 | + } | ||
| 540 | + } | ||
| 516 | 541 | ||
| 517 | - }else { | ||
| 518 | - //loger.log("更新人员列表数据,rosterExists已经存在",rosterExists); | 542 | + //踢出用户 |
| 543 | + kickOutRoster() { | ||
| 544 | + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_KICK_OUT); | ||
| 545 | + this._emit(MessageTypes.CLASS_EXIT); | ||
| 519 | } | 546 | } |
| 520 | - } | ||
| 521 | - | ||
| 522 | - //视频模块发生更新,人员状态需要更新 | ||
| 523 | - updaterRosterStatus(_param){ | ||
| 524 | - if(_param){ | ||
| 525 | - //loger.log("媒体模块发生更新,人员状态需要更新,fromNodeId->",_param.fromNodeId); | ||
| 526 | - //loger.log(_param.status,_param.fromNodeId); | ||
| 527 | - //console.log(_param.fromNodeId); | ||
| 528 | - //如果是自己。改变自己的状态同步到MCU | ||
| 529 | - //if(_param.fromNodeId==GlobalConfig.nodeId){ | ||
| 530 | - // | ||
| 531 | - //} | ||
| 532 | - | ||
| 533 | - //如果视频消息中channel的占用人 fromNodeId在人员列表中不存在,需要释放这channel,因为这个有可能是之前没释放成功的 | ||
| 534 | - if(_param.status==ApeConsts.CHANNEL_STATUS_OPENING&&this.rosters[_param.fromNodeId]==null){ | ||
| 535 | - loger.log("媒体模块被占用,占有人已经不存在课堂中,释放Channel,_param->",_param); | ||
| 536 | - this._emit(MessageTypes.CLASS_NONENTITY_ROSTER,{"nodeId":_param.fromNodeId}); | ||
| 537 | - } | 547 | + |
| 548 | + //视频模块发生更新,人员状态需要更新 | ||
| 549 | + updaterRosterStatus(_param) { | ||
| 550 | + if (_param) { | ||
| 551 | + //loger.log("媒体模块发生更新,人员状态需要更新,fromNodeId->",_param.fromNodeId); | ||
| 552 | + //loger.log(_param.status,_param.fromNodeId); | ||
| 553 | + //console.log(_param.fromNodeId); | ||
| 554 | + //如果是自己。改变自己的状态同步到MCU | ||
| 555 | + //if(_param.fromNodeId==GlobalConfig.nodeId){ | ||
| 556 | + // | ||
| 557 | + //} | ||
| 558 | + | ||
| 559 | + //如果视频消息中channel的占用人 fromNodeId在人员列表中不存在,需要释放这channel,因为这个有可能是之前没释放成功的 | ||
| 560 | + if (_param.status == ApeConsts.CHANNEL_STATUS_OPENING && this.rosters[_param.fromNodeId] == null) { | ||
| 561 | + loger.log("媒体模块被占用,占有人已经不存在课堂中,释放Channel,_param->", _param); | ||
| 562 | + this._emit(MessageTypes.CLASS_NONENTITY_ROSTER, {"nodeId": _param.fromNodeId}); | ||
| 563 | + } | ||
| 564 | + } | ||
| 538 | } | 565 | } |
| 539 | - } | ||
| 540 | - //删除用户 | ||
| 541 | - rosterDelHandler(nodeId) { | ||
| 542 | - if(GlobalConfig.nodeId==nodeId){ | ||
| 543 | - loger.log("自己离开 rosterDelHandler"); | ||
| 544 | - // 自己退出 | ||
| 545 | - this._emit(MessageTypes.CLASS_EXIT); | ||
| 546 | - }else { | ||
| 547 | - loger.log("有人离开 rosterDelHandler"); | ||
| 548 | - delete this.rosters[nodeId]; | ||
| 549 | - this.emitRosterChange(); | ||
| 550 | - this._emit(MessageTypes.CLASS_DELETE_ROSTER, {"nodeId":nodeId}); | ||
| 551 | - | ||
| 552 | - //当前人员列表中抽一个人来检查离开人员是否占用频道 | ||
| 553 | - for (let key in this.rosters){ | ||
| 554 | - let randNodeId=parseInt(key); | ||
| 555 | - if(randNodeId==GlobalConfig.nodeId){ | ||
| 556 | - loger.log(randNodeId,"有权限检查离开的人员是否占用channel"); | ||
| 557 | - this._emit(MessageTypes.CLASS_NONENTITY_ROSTER, {"nodeId":nodeId}); | ||
| 558 | - }else { | ||
| 559 | - loger.warn(GlobalConfig.nodeId,"没有权限检查离开的人员是否占用channel"); | 566 | + |
| 567 | + //删除用户 | ||
| 568 | + rosterDelHandler(nodeId) { | ||
| 569 | + if (GlobalConfig.nodeId == nodeId) { | ||
| 570 | + loger.log("自己离开课堂"); | ||
| 571 | + // 自己退出 | ||
| 572 | + this._emit(MessageTypes.CLASS_EXIT); | ||
| 573 | + } else { | ||
| 574 | + loger.log(nodeId, "离开课堂"); | ||
| 575 | + delete this.rosters[nodeId]; | ||
| 576 | + this.emitRosterChange(); | ||
| 577 | + this._emit(MessageTypes.CLASS_DELETE_ROSTER, {"nodeId": nodeId}); | ||
| 578 | + | ||
| 579 | + //当前人员列表中抽一个人来检查离开人员是否占用频道 | ||
| 580 | + for (let key in this.rosters) { | ||
| 581 | + let randNodeId = parseInt(key); | ||
| 582 | + if (randNodeId == GlobalConfig.nodeId) { | ||
| 583 | + loger.log(randNodeId, "有权限检查离开的人员是否占用channel"); | ||
| 584 | + this._emit(MessageTypes.CLASS_NONENTITY_ROSTER, {"nodeId": nodeId}); | ||
| 585 | + } else { | ||
| 586 | + loger.warn(GlobalConfig.nodeId, "没有权限检查离开的人员是否占用channel"); | ||
| 587 | + } | ||
| 588 | + return; | ||
| 589 | + } | ||
| 560 | } | 590 | } |
| 561 | - return; | ||
| 562 | - } | ||
| 563 | } | 591 | } |
| 564 | - } | ||
| 565 | - | ||
| 566 | - //广播当前的人数 | ||
| 567 | - emitRosterChange() { | ||
| 568 | - this._emit(MessageTypes.CLASS_UPDATE_ROSTER_NUM, Object.keys(this.rosters).length); | ||
| 569 | - } | ||
| 570 | - | ||
| 571 | - ///////数据的封包和解包///////////////////////////////////////// | ||
| 572 | - packPdu(_param,_itemIdx){ | ||
| 573 | - loger.log("会议===packPdu "); | ||
| 574 | - //验证坐标点集合数组是否合法 | ||
| 575 | - if(_param==null||_itemIdx==null){ | ||
| 576 | - this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG); | ||
| 577 | - return null; | 592 | + |
| 593 | + //广播当前的人数 | ||
| 594 | + emitRosterChange() { | ||
| 595 | + this._emit(MessageTypes.CLASS_UPDATE_ROSTER_NUM, Object.keys(this.rosters).length); | ||
| 578 | } | 596 | } |
| 579 | - let classStatusInfo=new pdu['RCClassStatusInfoPdu']; | ||
| 580 | - classStatusInfo.nodeId=GlobalConfig.nodeId;//mcu中的唯一ID | ||
| 581 | - classStatusInfo.userId=GlobalConfig.userId; | ||
| 582 | - classStatusInfo.userName=GlobalConfig.userName; | ||
| 583 | - classStatusInfo.siteId=GlobalConfig.siteId;//站点号 | ||
| 584 | - classStatusInfo.classId=GlobalConfig.classId; | ||
| 585 | - classStatusInfo.className=GlobalConfig.className; | ||
| 586 | - classStatusInfo.classType=GlobalConfig.classType;//课堂类型 | ||
| 587 | - classStatusInfo.classStatus=GlobalConfig.classStatus;//课堂的状态 | ||
| 588 | - classStatusInfo.classStartTime=GlobalConfig.classStartTime;//课堂点击开始时间 | ||
| 589 | - classStatusInfo.classStopTime=GlobalConfig.classStopTime;//最后一次停止的时间(点暂停或结束),每次发送数据都获取当前时间戳 | ||
| 590 | - classStatusInfo.classTimestamp=GlobalConfig.classTimestamp;//相对于点开始课堂的时间戳 | ||
| 591 | - classStatusInfo.classBeginTime=GlobalConfig.classBeginTime;//课堂创建的时间,这个是Sass返回的 | ||
| 592 | - classStatusInfo.classEndTime=GlobalConfig.classEndTime;//课堂结束的时间,这个是Sass返回的 | ||
| 593 | - classStatusInfo.recordStatus=GlobalConfig.recordStatus;//当前录制状态 | ||
| 594 | - classStatusInfo.recordTimestamp=GlobalConfig.recordTimestamp;//相对于首次开始录制的时间戳 | ||
| 595 | - classStatusInfo.recordFileName=GlobalConfig.recordFileName;//录制的文件名 | ||
| 596 | - classStatusInfo.recordDownloadUrl=GlobalConfig.recordDownloadUrl;//下载地址 | ||
| 597 | - classStatusInfo.serverTimestamp=GlobalConfig.serverTimestamp;//当前的系统时间戳 | ||
| 598 | - classStatusInfo.activeDocId=GlobalConfig.activeDocId;//当前激活的文档id | ||
| 599 | - classStatusInfo.activeDocCurPage=GlobalConfig.activeDocCurPage;//当前激活的文档的当前页 | ||
| 600 | - | ||
| 601 | - loger.log("classStatusInfo-------------",classStatusInfo); | ||
| 602 | - | ||
| 603 | - /* | ||
| 604 | - optional uint32 item_idx=1; | ||
| 605 | - optional uint32 from=2; | ||
| 606 | - optional uint32 owner=3; | ||
| 607 | - optional uint32 action_type=4;//状态改变的类型 | ||
| 608 | - optional RCClassStatusInfoPdu class_status_info=5;//当前课堂状态的信息 | ||
| 609 | - */ | ||
| 610 | - //判断type类型,根据type设置不同的参数 | ||
| 611 | - let modelPdu =new pdu['RCClassSendDataModelPdu']; | ||
| 612 | - modelPdu.itemIdx=_itemIdx; | ||
| 613 | - modelPdu.from=GlobalConfig.nodeId; | ||
| 614 | - modelPdu.owner=GlobalConfig.nodeId; | ||
| 615 | - //modelPdu.actionType =_param.actionType; | ||
| 616 | - modelPdu.classStatusInfo=classStatusInfo; | ||
| 617 | - return modelPdu; | ||
| 618 | - } | ||
| 619 | - | ||
| 620 | - unPackPdu(owner, itemIdx,itemData){ | ||
| 621 | - loger.log("会议===unPackPdu "); | ||
| 622 | - if(owner==null||itemIdx==null||itemData==null){ | ||
| 623 | - this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG); | ||
| 624 | - return null; | 597 | + |
| 598 | + ///////数据的封包和解包///////////////////////////////////////// | ||
| 599 | + packPdu(_param, _itemIdx) { | ||
| 600 | + loger.log("会议===packPdu "); | ||
| 601 | + //验证坐标点集合数组是否合法 | ||
| 602 | + if (_param == null || _itemIdx == null) { | ||
| 603 | + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG); | ||
| 604 | + return null; | ||
| 605 | + } | ||
| 606 | + let classStatusInfo = new pdu['RCClassStatusInfoPdu']; | ||
| 607 | + classStatusInfo.nodeId = GlobalConfig.nodeId;//mcu中的唯一ID | ||
| 608 | + classStatusInfo.userId = GlobalConfig.userId; | ||
| 609 | + classStatusInfo.userName = GlobalConfig.userName; | ||
| 610 | + classStatusInfo.siteId = GlobalConfig.siteId;//站点号 | ||
| 611 | + classStatusInfo.classId = GlobalConfig.classId; | ||
| 612 | + classStatusInfo.className = GlobalConfig.className; | ||
| 613 | + classStatusInfo.classType = GlobalConfig.classType;//课堂类型 | ||
| 614 | + classStatusInfo.classStatus = GlobalConfig.classStatus;//课堂的状态 | ||
| 615 | + classStatusInfo.classStartTime = GlobalConfig.classStartTime;//课堂点击开始时间 | ||
| 616 | + classStatusInfo.classStopTime = GlobalConfig.classStopTime;//最后一次停止的时间(点暂停或结束),每次发送数据都获取当前时间戳 | ||
| 617 | + classStatusInfo.classTimestamp = GlobalConfig.classTimestamp;//相对于点开始课堂的时间戳 | ||
| 618 | + classStatusInfo.classBeginTime = GlobalConfig.classBeginTime;//课堂创建的时间,这个是Sass返回的 | ||
| 619 | + classStatusInfo.classEndTime = GlobalConfig.classEndTime;//课堂结束的时间,这个是Sass返回的 | ||
| 620 | + classStatusInfo.recordStatus = GlobalConfig.recordStatus;//当前录制状态 | ||
| 621 | + classStatusInfo.recordTimestamp = GlobalConfig.recordTimestamp;//相对于首次开始录制的时间戳 | ||
| 622 | + classStatusInfo.recordFileName = GlobalConfig.recordFileName;//录制的文件名 | ||
| 623 | + classStatusInfo.recordDownloadUrl = GlobalConfig.recordDownloadUrl;//下载地址 | ||
| 624 | + classStatusInfo.serverTimestamp = GlobalConfig.serverTimestamp;//当前的系统时间戳 | ||
| 625 | + classStatusInfo.activeDocId = GlobalConfig.activeDocId;//当前激活的文档id | ||
| 626 | + classStatusInfo.activeDocCurPage = GlobalConfig.activeDocCurPage;//当前激活的文档的当前页 | ||
| 627 | + | ||
| 628 | + loger.log("classStatusInfo-------------", classStatusInfo); | ||
| 629 | + | ||
| 630 | + /* | ||
| 631 | + optional uint32 item_idx=1; | ||
| 632 | + optional uint32 from=2; | ||
| 633 | + optional uint32 owner=3; | ||
| 634 | + optional uint32 action_type=4;//状态改变的类型 | ||
| 635 | + optional RCClassStatusInfoPdu class_status_info=5;//当前课堂状态的信息 | ||
| 636 | + */ | ||
| 637 | + //判断type类型,根据type设置不同的参数 | ||
| 638 | + let modelPdu = new pdu['RCClassSendDataModelPdu']; | ||
| 639 | + modelPdu.itemIdx = _itemIdx; | ||
| 640 | + modelPdu.from = GlobalConfig.nodeId; | ||
| 641 | + modelPdu.owner = GlobalConfig.nodeId; | ||
| 642 | + //modelPdu.actionType =_param.actionType; | ||
| 643 | + modelPdu.classStatusInfo = classStatusInfo; | ||
| 644 | + return modelPdu; | ||
| 625 | } | 645 | } |
| 626 | 646 | ||
| 627 | - try{ | ||
| 628 | - let modelPdu= pdu['RCClassSendDataModelPdu'].decode(itemData); | ||
| 629 | - return modelPdu; | ||
| 630 | - }catch (err){ | ||
| 631 | - loger.log("会议收到数据 unPackPdu Pdu解析错误,itemIdx="+itemIdx+" err:"+err.message); | 647 | + unPackPdu(owner, itemIdx, itemData) { |
| 648 | + loger.log("会议===unPackPdu "); | ||
| 649 | + if (owner == null || itemIdx == null || itemData == null) { | ||
| 650 | + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG); | ||
| 651 | + return null; | ||
| 652 | + } | ||
| 653 | + | ||
| 654 | + try { | ||
| 655 | + let modelPdu = pdu['RCClassSendDataModelPdu'].decode(itemData); | ||
| 656 | + return modelPdu; | ||
| 657 | + } catch (err) { | ||
| 658 | + loger.log("会议收到数据 unPackPdu Pdu解析错误,itemIdx=" + itemIdx + " err:" + err.message); | ||
| 659 | + } | ||
| 660 | + return null; | ||
| 632 | } | 661 | } |
| 633 | - return null; | ||
| 634 | - } | ||
| 635 | 662 | ||
| 636 | } | 663 | } |
| 637 | 664 |
| @@ -164,7 +164,12 @@ class VideoApe extends Ape { | @@ -164,7 +164,12 @@ class VideoApe extends Ape { | ||
| 164 | } | 164 | } |
| 165 | //释放nodeId占用的所有频道 | 165 | //释放nodeId占用的所有频道 |
| 166 | _releaseNodeIdAllChannel(nodeId){ | 166 | _releaseNodeIdAllChannel(nodeId){ |
| 167 | - loger.log(nodeId,"_releaseNodeIdAllChannel"); | 167 | + loger.log(nodeId,"_releaseNodeIdAllChannel",this.mcu.connected); |
| 168 | + if(!this.mcu.connected){ | ||
| 169 | + loger.warn(GlobalConfig.getCurrentStatus()); | ||
| 170 | + return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"}; | ||
| 171 | + } | ||
| 172 | + | ||
| 168 | let openingChannel = this.mediaModule.getOpeningMediaChannel(nodeId); | 173 | let openingChannel = this.mediaModule.getOpeningMediaChannel(nodeId); |
| 169 | if (openingChannel == 0) { | 174 | if (openingChannel == 0) { |
| 170 | loger.warn(nodeId,"没有占用channel不需要处理"); | 175 | loger.warn(nodeId,"没有占用channel不需要处理"); |
| @@ -181,7 +181,7 @@ class MCU extends Emiter { | @@ -181,7 +181,7 @@ class MCU extends Emiter { | ||
| 181 | nodeInfoRecordPdu.name = this.classInfo.userName; | 181 | nodeInfoRecordPdu.name = this.classInfo.userName; |
| 182 | nodeInfoRecordPdu.nodeId = this.classInfo.nodeId; | 182 | nodeInfoRecordPdu.nodeId = this.classInfo.nodeId; |
| 183 | nodeInfoRecordPdu.userId = this.classInfo.userId; | 183 | nodeInfoRecordPdu.userId = this.classInfo.userId; |
| 184 | - nodeInfoRecordPdu.role = 1; //NR_NORMAL | 184 | + nodeInfoRecordPdu.role = ApeConsts.userTypesToId[this.classInfo.userRole]||1; //NR_NORMAL用户的身份,根据用户登录时的身份设置 |
| 185 | nodeInfoRecordPdu.level = 0; | 185 | nodeInfoRecordPdu.level = 0; |
| 186 | 186 | ||
| 187 | let conferenceRecord = {}; //RCConferenceRecord_T | 187 | let conferenceRecord = {}; //RCConferenceRecord_T |
-
请 注册 或 登录 后发表评论