李勇

增加用户身份处理,同一个课堂只能有一个主持人,一个助教,一个主讲人,一个监课,如果新进入的用户是这几个身份,会踢掉当前课堂内同样身份的人

@@ -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,7 +14,7 @@ import EngineUtils from 'EngineUtils'; @@ -14,7 +14,7 @@ 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() { 20 constructor() {
@@ -23,7 +23,7 @@ class ConferApe extends Ape { @@ -23,7 +23,7 @@ class ConferApe extends Ape {
23 ApeConsts.CONFERENCE_SESSION_NAME, 23 ApeConsts.CONFERENCE_SESSION_NAME,
24 ApeConsts.CONFERENCE_SESSION_TAG 24 ApeConsts.CONFERENCE_SESSION_TAG
25 ); 25 );
26 - 26 + /*
27 // Attribures 27 // Attribures
28 this.hostNodeId = -1;//主持人的nodeId 28 this.hostNodeId = -1;//主持人的nodeId
29 // 用户的身份,5种类型: 29 // 用户的身份,5种类型:
@@ -34,8 +34,10 @@ class ConferApe extends Ape { @@ -34,8 +34,10 @@ class ConferApe extends Ape {
34 // record(暂时没用. 34 // record(暂时没用.
35 // 默认值: normal 35 // 默认值: normal
36 this.hostUserId = '';//主持人的 第三方userId 36 this.hostUserId = '';//主持人的 第三方userId
  37 + */
  38 +
37 this.rosters = {};//用户列表 39 this.rosters = {};//用户列表
38 - this.timerCounter=new TimerCounter();//计时器 40 + this.timerCounter = new TimerCounter();//计时器
39 41
40 // Ape Models 42 // Ape Models
41 this.registerKey(this._session_id, this._session_name, this._session_tag, new ArrayBuffer); 43 this.registerKey(this._session_id, this._session_name, this._session_tag, new ArrayBuffer);
@@ -55,7 +57,7 @@ class ConferApe extends Ape { @@ -55,7 +57,7 @@ class ConferApe extends Ape {
55 this.on(pdu.RCPDU_SESSION_JOIN_RESPONSE, this._joinSessionHandler.bind(this)); 57 this.on(pdu.RCPDU_SESSION_JOIN_RESPONSE, this._joinSessionHandler.bind(this));
56 58
57 this.on(pdu.RCPDU_SEND_CONFERENCE_DATA_REQUEST, this.conferMsgComingHandler.bind(this));//这个是会议消息类型,flash里在使用这里不再使用,各个模块的消息由模块自己来处理 59 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));//发送录制和停止录制消息 60 + this.on(pdu.RCPDU_CONFERENCE_RECORD_REQUEST, this.onSendConferRecordRequestHandler.bind(this));//发送录制和停止录制消息
59 } 61 }
60 62
61 //加入会议 63 //加入会议
@@ -68,7 +70,7 @@ class ConferApe extends Ape { @@ -68,7 +70,7 @@ class ConferApe extends Ape {
68 userDataPdu.skype = ''; 70 userDataPdu.skype = '';
69 71
70 nodeInfoRecordPdu.userData = userDataPdu.toArrayBuffer(); 72 nodeInfoRecordPdu.userData = userDataPdu.toArrayBuffer();
71 - nodeInfoRecordPdu.deviceType =GlobalConfig.deviceType;//设备类型 73 + nodeInfoRecordPdu.deviceType = GlobalConfig.deviceType;//设备类型
72 74
73 let item = new pdu['RCRegistryRosterItemPdu']; 75 let item = new pdu['RCRegistryRosterItemPdu'];
74 item.nodeId = nodeInfoRecordPdu.nodeId; 76 item.nodeId = nodeInfoRecordPdu.nodeId;
@@ -95,13 +97,13 @@ class ConferApe extends Ape { @@ -95,13 +97,13 @@ class ConferApe extends Ape {
95 } 97 }
96 98
97 sendConferMsg(_messageInfo) { 99 sendConferMsg(_messageInfo) {
98 - if(this._classInfo==null||EngineUtils.isEmptyObject(this._classInfo)){ 100 + if (this._classInfo == null || EngineUtils.isEmptyObject(this._classInfo)) {
99 loger.log('不能发送会议消息.McuClient还未初始化数据!'); 101 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 + if (GlobalConfig.getCurrentStatus().code == 0 || GlobalConfig.getCurrentStatus().code == 1) {
  103 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN);
102 return; 104 return;
103 } 105 }
104 - return ; 106 + return;
105 } 107 }
106 108
107 // to, message 109 // to, message
@@ -123,9 +125,9 @@ class ConferApe extends Ape { @@ -123,9 +125,9 @@ class ConferApe extends Ape {
123 conferSendPdu.userData = this._rCArrayBufferUtil.strToUint8Array("h5" + _messageInfo.message); 125 conferSendPdu.userData = this._rCArrayBufferUtil.strToUint8Array("h5" + _messageInfo.message);
124 //conferSendPdu.userData =UTF8.setBytesFromString(_messageInfo.message); 126 //conferSendPdu.userData =UTF8.setBytesFromString(_messageInfo.message);
125 conferSendPdu.isPublic = true; 127 conferSendPdu.isPublic = true;
126 - conferSendPdu.actionType=_messageInfo.actionType; 128 + conferSendPdu.actionType = _messageInfo.actionType;
127 // if (!(conferSendPdu.isPublic || 0 === conferSendPdu.peer)) { 129 // if (!(conferSendPdu.isPublic || 0 === conferSendPdu.peer)) {
128 - if (!conferSendPdu.isPublic && 0!=conferSendPdu.peer) { 130 + if (!conferSendPdu.isPublic && 0 != conferSendPdu.peer) {
129 //发送给制定的人 131 //发送给制定的人
130 loger.log('发送私聊会议消息.'); 132 loger.log('发送私聊会议消息.');
131 this.send(conferSendPdu); 133 this.send(conferSendPdu);
@@ -138,15 +140,15 @@ class ConferApe extends Ape { @@ -138,15 +140,15 @@ class ConferApe extends Ape {
138 140
139 //发送录制或停止录制的消息,{"recordStatus":true};true为开始录制,false为停止录制 141 //发送录制或停止录制的消息,{"recordStatus":true};true为开始录制,false为停止录制
140 sendConferRecordMsg(_param) { 142 sendConferRecordMsg(_param) {
141 - if(!this.mcu.connected){ 143 + if (!this.mcu.connected) {
142 loger.warn(GlobalConfig.getCurrentStatus()); 144 loger.warn(GlobalConfig.getCurrentStatus());
143 return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"}; 145 return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};
144 } 146 }
145 // to, message 147 // to, message
146 loger.log('发送录制消息.', _param); 148 loger.log('发送录制消息.', _param);
147 149
148 - if(_param==null){  
149 - loger.warn("控制录制状的消息发送失败,参数错误",_param); 150 + if (_param == null) {
  151 + loger.warn("控制录制状的消息发送失败,参数错误", _param);
150 return; 152 return;
151 } 153 }
152 154
@@ -158,7 +160,7 @@ class ConferApe extends Ape { @@ -158,7 +160,7 @@ class ConferApe extends Ape {
158 }*/ 160 }*/
159 161
160 //保存当前的录制状态 162 //保存当前的录制状态
161 - GlobalConfig.recordStatus=_param.recordStatus||false; 163 + GlobalConfig.recordStatus = _param.recordStatus || false;
162 164
163 let conferRecordSendPdu = new pdu['RCConferenceRecordRequestPdu']; 165 let conferRecordSendPdu = new pdu['RCConferenceRecordRequestPdu'];
164 conferRecordSendPdu.type = pdu.RCPDU_CONFERENCE_RECORD_REQUEST; 166 conferRecordSendPdu.type = pdu.RCPDU_CONFERENCE_RECORD_REQUEST;
@@ -166,38 +168,38 @@ class ConferApe extends Ape { @@ -166,38 +168,38 @@ class ConferApe extends Ape {
166 conferRecordSendPdu.isPublic = true; 168 conferRecordSendPdu.isPublic = true;
167 169
168 conferRecordSendPdu.initiator = this._classInfo.nodeId;//发起人 170 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"; 171 + conferRecordSendPdu.record = GlobalConfig.recordStatus;
  172 + conferRecordSendPdu.classTime = GlobalConfig.classTimestamp;
  173 + conferRecordSendPdu.filename = GlobalConfig.recordFileName || GlobalConfig.classId + "_" + EngineUtils.creatTimestampYMD() + ".rec";
172 this.sendChatUniform(conferRecordSendPdu); 174 this.sendChatUniform(conferRecordSendPdu);
173 } 175 }
174 176
175 //开启录制 177 //开启录制
176 - startRecord(){  
177 - loger.log('startRecord',"isHost",GlobalConfig.isHost,"recordStatus",GlobalConfig.recordStatus); 178 + startRecord() {
  179 + loger.log('startRecord', "isHost", GlobalConfig.isHost, "recordStatus", GlobalConfig.recordStatus);
178 //如果是host 180 //如果是host
179 - if(GlobalConfig.isHost){  
180 - GlobalConfig.classStopTime=EngineUtils.creatTimestampStr();  
181 - this.sendConferRecordMsg({"recordStatus":true}); 181 + if (GlobalConfig.isHost) {
  182 + GlobalConfig.classStopTime = EngineUtils.creatTimestampStr();
  183 + this.sendConferRecordMsg({"recordStatus": true});
182 this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE); 184 this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
183 this._emit(MessageTypes.CLASS_RECORD_START);//会议开始录制 185 this._emit(MessageTypes.CLASS_RECORD_START);//会议开始录制
184 } 186 }
185 } 187 }
186 188
187 //停止录制 189 //停止录制
188 - stopRecord(){  
189 - loger.log('stopRecord',"isHost",GlobalConfig.isHost,"recordStatus",GlobalConfig.recordStatus); 190 + stopRecord() {
  191 + loger.log('stopRecord', "isHost", GlobalConfig.isHost, "recordStatus", GlobalConfig.recordStatus);
190 //如果是host,并且当前正在录制中 192 //如果是host,并且当前正在录制中
191 - if(GlobalConfig.isHost&&GlobalConfig.recordStatus){  
192 - GlobalConfig.classStopTime=EngineUtils.creatTimestampStr();  
193 - this.sendConferRecordMsg({"recordStatus":false}); 193 + if (GlobalConfig.isHost && GlobalConfig.recordStatus) {
  194 + GlobalConfig.classStopTime = EngineUtils.creatTimestampStr();
  195 + this.sendConferRecordMsg({"recordStatus": false});
194 this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE); 196 this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
195 } 197 }
196 } 198 }
197 199
198 200
199 //主动离开会议,发送通知到服务器 201 //主动离开会议,发送通知到服务器
200 - leaveClass(){ 202 + leaveClass() {
201 let nodeInfoRecordPdu = this.mcu.mcuClassInfo.self; 203 let nodeInfoRecordPdu = this.mcu.mcuClassInfo.self;
202 let userDataPdu = new pdu['RCNodeInfoUserDataPdu']; 204 let userDataPdu = new pdu['RCNodeInfoUserDataPdu'];
203 userDataPdu.qq = ''; 205 userDataPdu.qq = '';
@@ -212,7 +214,7 @@ class ConferApe extends Ape { @@ -212,7 +214,7 @@ class ConferApe extends Ape {
212 214
213 let rosterUpdateItem = new pdu['RCRegistryRosterDeleteItemPdu']; 215 let rosterUpdateItem = new pdu['RCRegistryRosterDeleteItemPdu'];
214 rosterUpdateItem.type = pdu.RCPDU_REG_ROSTER_DELETE_PDU; 216 rosterUpdateItem.type = pdu.RCPDU_REG_ROSTER_DELETE_PDU;
215 - rosterUpdateItem.nodeId=GlobalConfig.nodeId; 217 + rosterUpdateItem.nodeId = GlobalConfig.nodeId;
216 218
217 let updateObjPdu = new pdu['RCRegistryUpdateObjPdu']; 219 let updateObjPdu = new pdu['RCRegistryUpdateObjPdu'];
218 updateObjPdu.objId = ApeConsts.CONFERENCE_OBJ_ROSTER_ID; 220 updateObjPdu.objId = ApeConsts.CONFERENCE_OBJ_ROSTER_ID;
@@ -231,66 +233,68 @@ class ConferApe extends Ape { @@ -231,66 +233,68 @@ class ConferApe extends Ape {
231 } 233 }
232 234
233 //还原课堂状态 235 //还原课堂状态
234 - restorClass(){  
235 - GlobalConfig.classTimestamp=0;  
236 - GlobalConfig.classStatus=ApeConsts.CLASS_STATUS_WAIT;  
237 - GlobalConfig.classStopTime=EngineUtils.creatTimestampStr(); 236 + restorClass() {
  237 + GlobalConfig.classTimestamp = 0;
  238 + GlobalConfig.classStatus = ApeConsts.CLASS_STATUS_WAIT;
  239 + GlobalConfig.classStopTime = EngineUtils.creatTimestampStr();
238 this.stopRecord(); 240 this.stopRecord();
239 this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE); 241 this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
240 - this.sendUpdaterClassStatusInfo({"actionType":0}); 242 + this.sendUpdaterClassStatusInfo({"actionType": 0});
241 loger.log('restorClass'); 243 loger.log('restorClass');
242 } 244 }
243 245
244 //开始上课 246 //开始上课
245 - startClass(_param){  
246 - if(GlobalConfig.isHost){ 247 + startClass(_param) {
  248 + if (GlobalConfig.isHost) {
247 249
248 - let timestamp=EngineUtils.creatTimestampStr();  
249 - GlobalConfig.classStopTime=timestamp; 250 + let timestamp = EngineUtils.creatTimestampStr();
  251 + GlobalConfig.classStopTime = timestamp;
250 252
251 //如果录制的文件名不存在,需要创建一个名字 253 //如果录制的文件名不存在,需要创建一个名字
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` 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`
256 258
257 - if(GlobalConfig.classStatus==ApeConsts.CLASS_STATUS_WAIT){ 259 + if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_WAIT) {
258 //之前是为开始状态,第一次点开始 260 //之前是为开始状态,第一次点开始
259 - GlobalConfig.classStartTime=timestamp; 261 + GlobalConfig.classStartTime = timestamp;
260 } 262 }
261 263
262 - GlobalConfig.classStatus=ApeConsts.CLASS_STATUS_STARTED; 264 + GlobalConfig.classStatus = ApeConsts.CLASS_STATUS_STARTED;
263 //开始录制 265 //开始录制
264 this.startRecord(); 266 this.startRecord();
265 //会议状态改变 267 //会议状态改变
266 this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE); 268 this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
267 //同步会议状态 269 //同步会议状态
268 - this.sendUpdaterClassStatusInfo({"actionType":1}); 270 + this.sendUpdaterClassStatusInfo({"actionType": 1});
269 271
270 //开始计时 272 //开始计时
271 this.startTimerCounter(); 273 this.startTimerCounter();
272 - }else { 274 + } else {
273 loger.warn('没有权限'); 275 loger.warn('没有权限');
274 } 276 }
275 } 277 }
  278 +
276 //暂停上课 279 //暂停上课
277 - pauseClass(_param){  
278 - if(GlobalConfig.classStatus==ApeConsts.CLASS_STATUS_WAIT){ 280 + pauseClass(_param) {
  281 + if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_WAIT) {
279 loger.warn('还没有开始,不能点暂停'); 282 loger.warn('还没有开始,不能点暂停');
280 return; 283 return;
281 } 284 }
282 285
283 - GlobalConfig.classStatus=ApeConsts.CLASS_STATUS_PAUSE;  
284 - GlobalConfig.classStopTime=EngineUtils.creatTimestampStr(); 286 + GlobalConfig.classStatus = ApeConsts.CLASS_STATUS_PAUSE;
  287 + GlobalConfig.classStopTime = EngineUtils.creatTimestampStr();
285 288
286 this.stopRecord(); 289 this.stopRecord();
287 this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE); 290 this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
288 - this.sendUpdaterClassStatusInfo({"actionType":2}); 291 + this.sendUpdaterClassStatusInfo({"actionType": 2});
289 this.stopTimerCounter(); 292 this.stopTimerCounter();
290 } 293 }
  294 +
291 //关闭课堂 295 //关闭课堂
292 - closeClass(_param){  
293 - if(GlobalConfig.classStatus==ApeConsts.CLASS_STATUS_WAIT){ 296 + closeClass(_param) {
  297 + if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_WAIT) {
294 loger.warn('还没有开始,不能点关闭'); 298 loger.warn('还没有开始,不能点关闭');
295 return; 299 return;
296 } 300 }
@@ -298,34 +302,34 @@ class ConferApe extends Ape { @@ -298,34 +302,34 @@ class ConferApe extends Ape {
298 this.stopTimerCounter(); 302 this.stopTimerCounter();
299 this.restorClass(); 303 this.restorClass();
300 //把所有人都踢出课堂 304 //把所有人都踢出课堂
301 - this.sendConferMsg({"to":0,"message":"所有人退出会议","actionType":ApeConsts.CLASS_ACTION_CLOSE_ALL}); 305 + this.sendConferMsg({"to": 0, "message": "所有人退出会议", "actionType": ApeConsts.CLASS_ACTION_CLOSE_ALL});
302 } 306 }
303 307
304 308
305 //更新会议信息 309 //更新会议信息
306 - sendUpdaterClassStatusInfo(_param){ 310 + sendUpdaterClassStatusInfo(_param) {
307 loger.log('sendUpdaterClassStatusInfo'); 311 loger.log('sendUpdaterClassStatusInfo');
308 - if(_param==null||EngineUtils.isEmptyObject(_param)){ 312 + if (_param == null || EngineUtils.isEmptyObject(_param)) {
309 loger.log('sendUpdaterClassStatusInfo,参数错误'); 313 loger.log('sendUpdaterClassStatusInfo,参数错误');
310 - this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);  
311 - return ; 314 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
  315 + return;
312 } 316 }
313 - itemIdx=ApeConsts.CONFERENCE_OBJ_TABLE_ID;// itemIdx=_param.itemIdx;  
314 - let modelPdu = this.packPdu(_param,itemIdx); 317 + itemIdx = ApeConsts.CONFERENCE_OBJ_TABLE_ID;// itemIdx=_param.itemIdx;
  318 + let modelPdu = this.packPdu(_param, itemIdx);
315 //loger.log('sendUpdaterClassStatusInfo----2------'); 319 //loger.log('sendUpdaterClassStatusInfo----2------');
316 console.log(modelPdu); 320 console.log(modelPdu);
317 321
318 - if(modelPdu==null){ 322 + if (modelPdu == null) {
319 loger.log('sendUpdaterClassStatusInfo,参数错误'); 323 loger.log('sendUpdaterClassStatusInfo,参数错误');
320 - this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);  
321 - return ; 324 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
  325 + return;
322 } 326 }
323 327
324 let tableItemPdu = new pdu['RCRegistryTableItemPdu']; 328 let tableItemPdu = new pdu['RCRegistryTableItemPdu'];
325 - tableItemPdu.itemIdx=itemIdx; 329 + tableItemPdu.itemIdx = itemIdx;
326 tableItemPdu.owner = 0;//收到flash的是这个值,不清楚先写固定 330 tableItemPdu.owner = 0;//收到flash的是这个值,不清楚先写固定
327 - tableItemPdu.registerObjId=ApeConsts.CONFERENCE_OBJ_TABLE_ID;  
328 - tableItemPdu.itemData =modelPdu.toArrayBuffer(); 331 + tableItemPdu.registerObjId = ApeConsts.CONFERENCE_OBJ_TABLE_ID;
  332 + tableItemPdu.itemData = modelPdu.toArrayBuffer();
329 333
330 334
331 //updater 335 //updater
@@ -351,17 +355,17 @@ class ConferApe extends Ape { @@ -351,17 +355,17 @@ class ConferApe extends Ape {
351 adapterPdu.item.push(adapterItemPdu); 355 adapterPdu.item.push(adapterItemPdu);
352 356
353 console.log("会议发送更新数据============"); 357 console.log("会议发送更新数据============");
354 - this.sendUniform(adapterPdu,true); 358 + this.sendUniform(adapterPdu, true);
355 } 359 }
356 360
357 361
358 /////收到消息处理///////////////////////////////////////////////////////////////////////////////// 362 /////收到消息处理/////////////////////////////////////////////////////////////////////////////////
359 //加入channel成功 363 //加入channel成功
360 - onJoinChannelHandlerSuccess(){  
361 - loger.log('ConferApe.onJoinChannelHandlerSuccess',GlobalConfig.classStatus);  
362 - this.timerCounter.addTimerCallBack(this.timerCounterUptate.bind(this),1); 364 + onJoinChannelHandlerSuccess() {
  365 + loger.log('ConferApe.onJoinChannelHandlerSuccess', GlobalConfig.classStatus);
  366 + this.timerCounter.addTimerCallBack(this.timerCounterUptate.bind(this), 1);
363 //如果当前会议正在进行中,开启计时器 367 //如果当前会议正在进行中,开启计时器
364 - if(GlobalConfig.classStatus==ApeConsts.CLASS_STATUS_STARTED){ 368 + if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_STARTED) {
365 //开始计时 369 //开始计时
366 this.startTimerCounter(); 370 this.startTimerCounter();
367 371
@@ -369,69 +373,72 @@ class ConferApe extends Ape { @@ -369,69 +373,72 @@ class ConferApe extends Ape {
369 this.startRecord(); 373 this.startRecord();
370 } 374 }
371 } 375 }
  376 +
372 //开启计时器 377 //开启计时器
373 - startTimerCounter(){ 378 + startTimerCounter() {
374 this.timerCounter.startTimer(); 379 this.timerCounter.startTimer();
375 } 380 }
  381 +
376 //停止计时器 382 //停止计时器
377 - stopTimerCounter(){ 383 + stopTimerCounter() {
378 this.timerCounter.stopTimer(); 384 this.timerCounter.stopTimer();
379 } 385 }
380 - timerCounterUptate(){  
381 - if(!this.mcu.connected){ 386 +
  387 + timerCounterUptate() {
  388 + if (!this.mcu.connected) {
382 loger.warn('MCU 连接已经断开'); 389 loger.warn('MCU 连接已经断开');
383 this.stopTimerCounter(); 390 this.stopTimerCounter();
384 } 391 }
385 //如果还没开始或已经暂停、关闭,不做计时处理 392 //如果还没开始或已经暂停、关闭,不做计时处理
386 - if(GlobalConfig.classStatus!=ApeConsts.CLASS_STATUS_STARTED){  
387 - loger.warn('当前课堂已经暂停或者未开始,不计时',"classStatus-->",GlobalConfig.classStatus); 393 + if (GlobalConfig.classStatus != ApeConsts.CLASS_STATUS_STARTED) {
  394 + loger.warn('当前课堂已经暂停或者未开始,不计时', "classStatus-->", GlobalConfig.classStatus);
388 return; 395 return;
389 } 396 }
390 - GlobalConfig.classTimestamp=GlobalConfig.classTimestamp+1;//计时 397 + GlobalConfig.classTimestamp = GlobalConfig.classTimestamp + 1;//计时
391 //loger.log('课堂进行时间',GlobalConfig.classTimestamp); 398 //loger.log('课堂进行时间',GlobalConfig.classTimestamp);
392 - this._emit(MessageTypes.CLASS_UPDATE_TIMER,{"classTimestamp":GlobalConfig.classTimestamp}); 399 + this._emit(MessageTypes.CLASS_UPDATE_TIMER, {"classTimestamp": GlobalConfig.classTimestamp});
393 400
394 - if(GlobalConfig.classTimestamp%GlobalConfig.updateClassInfoDelay==0){ 401 + if (GlobalConfig.classTimestamp % GlobalConfig.updateClassInfoDelay == 0) {
395 //如果是host身份,需要同步时间给其他人,同时把当前的状态上传到服务器 402 //如果是host身份,需要同步时间给其他人,同时把当前的状态上传到服务器
396 - if(GlobalConfig.isHost){ 403 + if (GlobalConfig.isHost) {
397 //保存数据到Sass 404 //保存数据到Sass
398 this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE); 405 this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
399 406
400 //同步消息给其他人 407 //同步消息给其他人
401 - this.sendUpdaterClassStatusInfo({"actionType":1}); 408 + this.sendUpdaterClassStatusInfo({"actionType": 1});
402 } 409 }
403 } 410 }
404 } 411 }
405 412
406 tableUpdateHandler(owner, itemIdx, itemData) { 413 tableUpdateHandler(owner, itemIdx, itemData) {
407 try { 414 try {
408 - let model=this.unPackPdu(owner, itemIdx,itemData); 415 + let model = this.unPackPdu(owner, itemIdx, itemData);
409 loger.log('tableUpdateHandler'); 416 loger.log('tableUpdateHandler');
410 console.log(model); 417 console.log(model);
411 418
412 //处理会议更新的信息 419 //处理会议更新的信息
413 - if(model&&model.classStatusInfo){ 420 + if (model && model.classStatusInfo) {
414 GlobalConfig.setClassStatusInfo(model.classStatusInfo); 421 GlobalConfig.setClassStatusInfo(model.classStatusInfo);
415 } 422 }
416 //通知应用层更新会议状态 423 //通知应用层更新会议状态
417 - this._emit(MessageTypes.CLASS_UPTATE_STATUS,GlobalConfig.classStatusInfo); 424 + this._emit(MessageTypes.CLASS_UPTATE_STATUS, GlobalConfig.classStatusInfo);
418 425
419 //如果MCU已经断开连接,停止计时器 426 //如果MCU已经断开连接,停止计时器
420 - if(!this.mcu.connected){ 427 + if (!this.mcu.connected) {
421 //停止计时 428 //停止计时
422 this.stopTimerCounter(); 429 this.stopTimerCounter();
423 return; 430 return;
424 } 431 }
425 432
426 - if(GlobalConfig.classStatus==ApeConsts.CLASS_STATUS_STARTED){ 433 + if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_STARTED) {
427 //如果会议在进行中,开始计时器 434 //如果会议在进行中,开始计时器
428 this.startTimerCounter(); 435 this.startTimerCounter();
429 - }else { 436 + } else {
430 //停止计时 437 //停止计时
431 this.stopTimerCounter(); 438 this.stopTimerCounter();
432 } 439 }
433 } catch (e) { 440 } catch (e) {
434 - loger.warn('ConferApe table update got exception. itemIdx',itemIdx); 441 + loger.warn('ConferApe table update got exception. itemIdx', itemIdx);
435 } 442 }
436 } 443 }
437 444
@@ -448,12 +455,12 @@ class ConferApe extends Ape { @@ -448,12 +455,12 @@ class ConferApe extends Ape {
448 chatMsg.fromNodeID = chatReceivePdu.initiator; 455 chatMsg.fromNodeID = chatReceivePdu.initiator;
449 chatMsg.toNodeID = chatReceivePdu.peer; 456 chatMsg.toNodeID = chatReceivePdu.peer;
450 chatMsg.message = this._rCArrayBufferUtil.uint8ArrayToStr(chatReceivePdu.userData, 2); 457 chatMsg.message = this._rCArrayBufferUtil.uint8ArrayToStr(chatReceivePdu.userData, 2);
451 - chatMsg.actionType=chatReceivePdu.actionType;  
452 - loger.log("conferMsgComingHandler",chatMsg);  
453 - switch (chatMsg.actionType){ 458 + chatMsg.actionType = chatReceivePdu.actionType;
  459 + loger.log("conferMsgComingHandler", chatMsg);
  460 + switch (chatMsg.actionType) {
454 case ApeConsts.CLASS_ACTION_CLOSE_ALL: 461 case ApeConsts.CLASS_ACTION_CLOSE_ALL:
455 loger.log(chatMsg.message); 462 loger.log(chatMsg.message);
456 - //会议关闭,所有人都退出 463 + //收到会议关闭,所有人都退出,执行自己关闭的流程
457 this._emit(MessageTypes.CLASS_EXIT); 464 this._emit(MessageTypes.CLASS_EXIT);
458 break; 465 break;
459 default: 466 default:
@@ -461,21 +468,21 @@ class ConferApe extends Ape { @@ -461,21 +468,21 @@ class ConferApe extends Ape {
461 } 468 }
462 } 469 }
463 470
464 - onSendConferRecordRequestHandler(_data){ 471 + onSendConferRecordRequestHandler(_data) {
465 loger.log("onSendConferRecordRequestHandler"); 472 loger.log("onSendConferRecordRequestHandler");
466 - try{  
467 - let conferRecordSendPdu =pdu['RCConferenceRecordRequestPdu'].decode(_data); 473 + try {
  474 + let conferRecordSendPdu = pdu['RCConferenceRecordRequestPdu'].decode(_data);
468 console.log(conferRecordSendPdu); 475 console.log(conferRecordSendPdu);
469 - }catch (err){  
470 - loger.warn("onSendConferRecordRequestHandler err",err.message); 476 + } catch (err) {
  477 + loger.warn("onSendConferRecordRequestHandler err", err.message);
471 } 478 }
472 479
473 } 480 }
474 481
475 rosterInsertHandler(nodeId, nodeData) { 482 rosterInsertHandler(nodeId, nodeData) {
476 - if(GlobalConfig.nodeId==nodeId){ 483 + if (GlobalConfig.nodeId == nodeId) {
477 loger.log("自己加入 rosterInsertHandler"); 484 loger.log("自己加入 rosterInsertHandler");
478 - }else { 485 + } else {
479 loger.log("有人加入 rosterInsertHandler"); 486 loger.log("有人加入 rosterInsertHandler");
480 this.rosterUpdateHandler(nodeId, nodeData); 487 this.rosterUpdateHandler(nodeId, nodeData);
481 } 488 }
@@ -483,45 +490,64 @@ class ConferApe extends Ape { @@ -483,45 +490,64 @@ class ConferApe extends Ape {
483 490
484 //更新人员列表数据 491 //更新人员列表数据
485 rosterUpdateHandler(nodeId, nodeData) { 492 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;  
490 - }  
491 - if (nodeData.role === ApeConsts.NR_NORMAL &&  
492 - this.hostNodeId === nodeData.nodeId) {  
493 - this.hostNodeId = -1;  
494 - this.hostUserId = ''; 493 + //如果是自己的信息,不处理跳过
  494 + if (nodeId == GlobalConfig.nodeId) {
  495 + loger.log("自己加入课堂的消息,不需要处理");
  496 + this.rosters[nodeId] = nodeData;
  497 + return;
495 } 498 }
496 499
497 - //判断进入的用户身份,如果进入的人身份是host,助教,监课,并且和自己的身份冲突,自己会被踢掉 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 + }
498 520
499 521
  522 + //处理用户信息
500 let rosterExists = this.rosters[nodeId]; 523 let rosterExists = this.rosters[nodeId];
501 this.rosters[nodeId] = nodeData; 524 this.rosters[nodeId] = nodeData;
502 - let userDataObj=null; 525 + let userDataObj = null;
503 if (!rosterExists) { 526 if (!rosterExists) {
504 - try{  
505 - userDataObj=pdu['RCNodeInfoUserDataPdu'].decode(nodeData.userData);  
506 - }catch (err){  
507 - loger.log("RCNodeInfoUserDataPdu decode err",err.message); 527 + try {
  528 + userDataObj = pdu['RCNodeInfoUserDataPdu'].decode(nodeData.userData);
  529 + } catch (err) {
  530 + loger.log("RCNodeInfoUserDataPdu decode err", err.message);
508 } 531 }
509 532
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}); 533 + let newNodeData = nodeData;
  534 + newNodeData.userData = userDataObj;
  535 + this._emit(MessageTypes.CLASS_INSERT_ROSTER, {"nodeId": nodeId, "nodeData": newNodeData});
514 this.emitRosterChange(); 536 this.emitRosterChange();
515 -  
516 -  
517 - }else { 537 + } else {
518 //loger.log("更新人员列表数据,rosterExists已经存在",rosterExists); 538 //loger.log("更新人员列表数据,rosterExists已经存在",rosterExists);
519 } 539 }
520 } 540 }
521 541
  542 + //踢出用户
  543 + kickOutRoster() {
  544 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_KICK_OUT);
  545 + this._emit(MessageTypes.CLASS_EXIT);
  546 + }
  547 +
522 //视频模块发生更新,人员状态需要更新 548 //视频模块发生更新,人员状态需要更新
523 - updaterRosterStatus(_param){  
524 - if(_param){ 549 + updaterRosterStatus(_param) {
  550 + if (_param) {
525 //loger.log("媒体模块发生更新,人员状态需要更新,fromNodeId->",_param.fromNodeId); 551 //loger.log("媒体模块发生更新,人员状态需要更新,fromNodeId->",_param.fromNodeId);
526 //loger.log(_param.status,_param.fromNodeId); 552 //loger.log(_param.status,_param.fromNodeId);
527 //console.log(_param.fromNodeId); 553 //console.log(_param.fromNodeId);
@@ -531,32 +557,33 @@ class ConferApe extends Ape { @@ -531,32 +557,33 @@ class ConferApe extends Ape {
531 //} 557 //}
532 558
533 //如果视频消息中channel的占用人 fromNodeId在人员列表中不存在,需要释放这channel,因为这个有可能是之前没释放成功的 559 //如果视频消息中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}); 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});
537 } 563 }
538 } 564 }
539 } 565 }
  566 +
540 //删除用户 567 //删除用户
541 rosterDelHandler(nodeId) { 568 rosterDelHandler(nodeId) {
542 - if(GlobalConfig.nodeId==nodeId){  
543 - loger.log("自己离开 rosterDelHandler"); 569 + if (GlobalConfig.nodeId == nodeId) {
  570 + loger.log("自己离开课堂");
544 // 自己退出 571 // 自己退出
545 this._emit(MessageTypes.CLASS_EXIT); 572 this._emit(MessageTypes.CLASS_EXIT);
546 - }else {  
547 - loger.log("有人离开 rosterDelHandler"); 573 + } else {
  574 + loger.log(nodeId, "离开课堂");
548 delete this.rosters[nodeId]; 575 delete this.rosters[nodeId];
549 this.emitRosterChange(); 576 this.emitRosterChange();
550 - this._emit(MessageTypes.CLASS_DELETE_ROSTER, {"nodeId":nodeId}); 577 + this._emit(MessageTypes.CLASS_DELETE_ROSTER, {"nodeId": nodeId});
551 578
552 //当前人员列表中抽一个人来检查离开人员是否占用频道 579 //当前人员列表中抽一个人来检查离开人员是否占用频道
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"); 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");
560 } 587 }
561 return; 588 return;
562 } 589 }
@@ -569,36 +596,36 @@ class ConferApe extends Ape { @@ -569,36 +596,36 @@ class ConferApe extends Ape {
569 } 596 }
570 597
571 ///////数据的封包和解包///////////////////////////////////////// 598 ///////数据的封包和解包/////////////////////////////////////////
572 - packPdu(_param,_itemIdx){ 599 + packPdu(_param, _itemIdx) {
573 loger.log("会议===packPdu "); 600 loger.log("会议===packPdu ");
574 //验证坐标点集合数组是否合法 601 //验证坐标点集合数组是否合法
575 - if(_param==null||_itemIdx==null){  
576 - this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG); 602 + if (_param == null || _itemIdx == null) {
  603 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
577 return null; 604 return null;
578 } 605 }
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); 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);
602 629
603 /* 630 /*
604 optional uint32 item_idx=1; 631 optional uint32 item_idx=1;
@@ -608,27 +635,27 @@ class ConferApe extends Ape { @@ -608,27 +635,27 @@ class ConferApe extends Ape {
608 optional RCClassStatusInfoPdu class_status_info=5;//当前课堂状态的信息 635 optional RCClassStatusInfoPdu class_status_info=5;//当前课堂状态的信息
609 */ 636 */
610 //判断type类型,根据type设置不同的参数 637 //判断type类型,根据type设置不同的参数
611 - let modelPdu =new pdu['RCClassSendDataModelPdu'];  
612 - modelPdu.itemIdx=_itemIdx;  
613 - modelPdu.from=GlobalConfig.nodeId;  
614 - modelPdu.owner=GlobalConfig.nodeId; 638 + let modelPdu = new pdu['RCClassSendDataModelPdu'];
  639 + modelPdu.itemIdx = _itemIdx;
  640 + modelPdu.from = GlobalConfig.nodeId;
  641 + modelPdu.owner = GlobalConfig.nodeId;
615 //modelPdu.actionType =_param.actionType; 642 //modelPdu.actionType =_param.actionType;
616 - modelPdu.classStatusInfo=classStatusInfo; 643 + modelPdu.classStatusInfo = classStatusInfo;
617 return modelPdu; 644 return modelPdu;
618 } 645 }
619 646
620 - unPackPdu(owner, itemIdx,itemData){ 647 + unPackPdu(owner, itemIdx, itemData) {
621 loger.log("会议===unPackPdu "); 648 loger.log("会议===unPackPdu ");
622 - if(owner==null||itemIdx==null||itemData==null){  
623 - this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG); 649 + if (owner == null || itemIdx == null || itemData == null) {
  650 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
624 return null; 651 return null;
625 } 652 }
626 653
627 - try{  
628 - let modelPdu= pdu['RCClassSendDataModelPdu'].decode(itemData); 654 + try {
  655 + let modelPdu = pdu['RCClassSendDataModelPdu'].decode(itemData);
629 return modelPdu; 656 return modelPdu;
630 - }catch (err){  
631 - loger.log("会议收到数据 unPackPdu Pdu解析错误,itemIdx="+itemIdx+" err:"+err.message); 657 + } catch (err) {
  658 + loger.log("会议收到数据 unPackPdu Pdu解析错误,itemIdx=" + itemIdx + " err:" + err.message);
632 } 659 }
633 return null; 660 return null;
634 } 661 }
@@ -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