李勇

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

@@ -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