Toggle navigation
Toggle navigation
此项目
正在载入...
Sign in
李勇
/
McuClient
转到一个项目
Toggle navigation
项目
群组
代码片段
帮助
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
AlexWang
2017-06-20 12:21:46 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
c1654e42cdf3e23d7d872496d5c23978cbccf566
c1654e42
1 parent
f4d772e7
实际内部Confer内部处理用户禁言及全局禁言
PDU新增字段
隐藏空白字符变更
内嵌
并排对比
正在显示
2 个修改的文件
包含
941 行增加
和
901 行删除
src/apes/ConferApe.js
src/pdus/pro.js
src/apes/ConferApe.js
查看文件 @
c1654e4
...
...
@@ -18,956 +18,994 @@ import Sass from 'Sass';
let
loger
=
Loger
.
getLoger
(
'ConferApe'
);
class
ConferApe
extends
Ape
{
constructor
()
{
super
(
ApeConsts
.
CONFERENCE_SESSION_ID
,
ApeConsts
.
CONFERENCE_SESSION_NAME
,
ApeConsts
.
CONFERENCE_SESSION_TAG
);
constructor
()
{
super
(
ApeConsts
.
CONFERENCE_SESSION_ID
,
ApeConsts
.
CONFERENCE_SESSION_NAME
,
ApeConsts
.
CONFERENCE_SESSION_TAG
);
this
.
rosters
=
{};
//用户列表
this
.
timerCounter
=
new
TimerCounter
();
//计时器
this
.
rosters
=
{};
//用户列表
this
.
timerCounter
=
new
TimerCounter
();
//计时器
//第三方消息控制 parent和Iframe直接的通讯
this
.
thirdMessage
=
new
ThirdMessage
();
this
.
thirdMessage
.
on
(
ThirdMessage
.
RECIVE_MESSAGE
,
this
.
onThirdReciveParentMessage
.
bind
(
this
));
//第三方消息控制 parent和Iframe直接的通讯
this
.
thirdMessage
=
new
ThirdMessage
();
this
.
thirdMessage
.
on
(
ThirdMessage
.
RECIVE_MESSAGE
,
this
.
onThirdReciveParentMessage
.
bind
(
this
));
// Ape Models
this
.
registerKey
(
this
.
_session_id
,
this
.
_session_name
,
this
.
_session_tag
,
new
ArrayBuffer
);
// Ape Models
this
.
registerKey
(
this
.
_session_id
,
this
.
_session_name
,
this
.
_session_tag
,
new
ArrayBuffer
);
this
.
registerObj
(
pdu
.
RCPDU_REG_REGISTER_ROSTER
,
ApeConsts
.
CONFERENCE_OBJ_ROSTER_ID
,
ApeConsts
.
CONFERENCE_OBJ_ROSTER_NAME
,
ApeConsts
.
CONFERENCE_OBJ_ROSTER_TAG
,
0
,
new
ArrayBuffer
);
this
.
registerObj
(
pdu
.
RCPDU_REG_REGISTER_ROSTER
,
ApeConsts
.
CONFERENCE_OBJ_ROSTER_ID
,
ApeConsts
.
CONFERENCE_OBJ_ROSTER_NAME
,
ApeConsts
.
CONFERENCE_OBJ_ROSTER_TAG
,
0
,
new
ArrayBuffer
);
this
.
registerObj
(
pdu
.
RCPDU_REG_REGISTER_QUEUE
,
ApeConsts
.
CONFERENCE_OBJ_QUEUE_ID
,
ApeConsts
.
CONFERENCE_OBJ_QUEUE_NAME
,
ApeConsts
.
CONFERENCE_OBJ_QUEUE_TAG
,
0
,
new
ArrayBuffer
);
this
.
registerObj
(
pdu
.
RCPDU_REG_REGISTER_QUEUE
,
ApeConsts
.
CONFERENCE_OBJ_QUEUE_ID
,
ApeConsts
.
CONFERENCE_OBJ_QUEUE_NAME
,
ApeConsts
.
CONFERENCE_OBJ_QUEUE_TAG
,
0
,
new
ArrayBuffer
);
this
.
registerObj
(
pdu
.
RCPDU_REG_REGISTER_TABLE
,
ApeConsts
.
CONFERENCE_OBJ_TABLE_ID
,
ApeConsts
.
CONFERENCE_OBJ_TABLE_NAME
,
ApeConsts
.
CONFERENCE_OBJ_TABLE_TAG
,
0
,
new
ArrayBuffer
);
this
.
registerObj
(
pdu
.
RCPDU_REG_REGISTER_TABLE
,
ApeConsts
.
CONFERENCE_OBJ_TABLE_ID
,
ApeConsts
.
CONFERENCE_OBJ_TABLE_NAME
,
ApeConsts
.
CONFERENCE_OBJ_TABLE_TAG
,
0
,
new
ArrayBuffer
);
this
.
registerObj
(
pdu
.
RCPDU_REG_REGISTER_COUNTER
,
ApeConsts
.
CONFERENCE_OBJ_COUNTER_ID
,
ApeConsts
.
CONFERENCE_OBJ_COUNTER_NAME
,
ApeConsts
.
CONFERENCE_OBJ_COUNTER_TAG
,
0
,
new
ArrayBuffer
);
this
.
registerObj
(
pdu
.
RCPDU_REG_REGISTER_COUNTER
,
ApeConsts
.
CONFERENCE_OBJ_COUNTER_ID
,
ApeConsts
.
CONFERENCE_OBJ_COUNTER_NAME
,
ApeConsts
.
CONFERENCE_OBJ_COUNTER_TAG
,
0
,
new
ArrayBuffer
);
this
.
on
(
pdu
.
RCPDU_SESSION_JOIN_RESPONSE
,
this
.
_joinSessionHandler
.
bind
(
this
));
this
.
on
(
pdu
.
RCPDU_SESSION_JOIN_RESPONSE
,
this
.
_joinSessionHandler
.
bind
(
this
));
this
.
on
(
pdu
.
RCPDU_SEND_CONFERENCE_DATA_REQUEST
,
this
.
conferMsgComingHandler
.
bind
(
this
));
//这个是课堂消息类型,flash里在使用这里不再使用,各个模块的消息由模块自己来处理
this
.
on
(
pdu
.
RCPDU_CONFERENCE_RECORD_REQUEST
,
this
.
onSendConferRecordRequestHandler
.
bind
(
this
));
//发送录制和停止录制消息
this
.
on
(
pdu
.
RCPDU_THIRD_BROADCAST_DATA_REQUEST
,
this
.
onThirdBroadcastDataHandler
.
bind
(
this
));
//第三方广播消息
}
this
.
on
(
pdu
.
RCPDU_SEND_CONFERENCE_DATA_REQUEST
,
this
.
conferMsgComingHandler
.
bind
(
this
));
//这个是课堂消息类型,flash里在使用这里不再使用,各个模块的消息由模块自己来处理
this
.
on
(
pdu
.
RCPDU_CONFERENCE_RECORD_REQUEST
,
this
.
onSendConferRecordRequestHandler
.
bind
(
this
));
//发送录制和停止录制消息
this
.
on
(
pdu
.
RCPDU_THIRD_BROADCAST_DATA_REQUEST
,
this
.
onThirdBroadcastDataHandler
.
bind
(
this
));
//第三方广播消息
}
//加入课堂
_joinSessionHandler
(
_data
)
{
//let nodeInfoRecordPdu = this.mcu.mcuClassInfo.self;
let
nodeInfoRecordPdu
=
this
.
getNodeInfo
();
//加入课堂
_joinSessionHandler
(
_data
)
{
//let nodeInfoRecordPdu = this.mcu.mcuClassInfo.self;
let
nodeInfoRecordPdu
=
this
.
getNodeInfo
();
let
userDataPdu
=
new
pdu
[
'RCNodeInfoUserDataPdu'
];
userDataPdu
.
qq
=
''
;
userDataPdu
.
skype
=
''
;
let
userDataPdu
=
new
pdu
[
'RCNodeInfoUserDataPdu'
];
userDataPdu
.
qq
=
''
;
userDataPdu
.
skype
=
''
;
nodeInfoRecordPdu
.
userData
=
userDataPdu
.
toArrayBuffer
();
nodeInfoRecordPdu
.
deviceType
=
GlobalConfig
.
deviceType
;
//设备类型
nodeInfoRecordPdu
.
userData
=
userDataPdu
.
toArrayBuffer
();
nodeInfoRecordPdu
.
deviceType
=
GlobalConfig
.
deviceType
;
//设备类型
loger
.
log
(
'开始加入->'
,
nodeInfoRecordPdu
);
loger
.
log
(
'开始加入->'
,
nodeInfoRecordPdu
);
let
item
=
new
pdu
[
'RCRegistryRosterItemPdu'
];
item
.
nodeId
=
nodeInfoRecordPdu
.
nodeId
;
item
.
nodeData
=
nodeInfoRecordPdu
.
toArrayBuffer
();
let
item
=
new
pdu
[
'RCRegistryRosterItemPdu'
];
item
.
nodeId
=
nodeInfoRecordPdu
.
nodeId
;
item
.
nodeData
=
nodeInfoRecordPdu
.
toArrayBuffer
();
let
rosterUpdateItem
=
new
pdu
[
'RCRegistryRosterUpdateItemPdu'
];
rosterUpdateItem
.
type
=
pdu
.
RCPDU_REG_ROSTER_UPDATE_PDU
;
rosterUpdateItem
.
items
.
push
(
item
);
let
rosterUpdateItem
=
new
pdu
[
'RCRegistryRosterUpdateItemPdu'
];
rosterUpdateItem
.
type
=
pdu
.
RCPDU_REG_ROSTER_UPDATE_PDU
;
rosterUpdateItem
.
items
.
push
(
item
);
let
updateObjPdu
=
new
pdu
[
'RCRegistryUpdateObjPdu'
];
updateObjPdu
.
objId
=
ApeConsts
.
CONFERENCE_OBJ_ROSTER_ID
;
updateObjPdu
.
subType
=
rosterUpdateItem
.
type
;
updateObjPdu
.
userData
=
rosterUpdateItem
.
toArrayBuffer
();
let
updateObjPdu
=
new
pdu
[
'RCRegistryUpdateObjPdu'
];
updateObjPdu
.
objId
=
ApeConsts
.
CONFERENCE_OBJ_ROSTER_ID
;
updateObjPdu
.
subType
=
rosterUpdateItem
.
type
;
updateObjPdu
.
userData
=
rosterUpdateItem
.
toArrayBuffer
();
//同步
let
adapterItemPdu
=
new
pdu
[
'RCAdapterItemPdu'
];
adapterItemPdu
.
type
=
pdu
.
RCPDU_REG_UPDATE_OBJ
;
adapterItemPdu
.
itemData
=
updateObjPdu
.
toArrayBuffer
();
//同步
let
adapterItemPdu
=
new
pdu
[
'RCAdapterItemPdu'
];
adapterItemPdu
.
type
=
pdu
.
RCPDU_REG_UPDATE_OBJ
;
adapterItemPdu
.
itemData
=
updateObjPdu
.
toArrayBuffer
();
let
adapterPdu
=
new
pdu
[
'RCAdapterPdu'
];
adapterPdu
.
type
=
pdu
.
RCPDU_REG_ADAPTER
;
adapterPdu
.
item
.
push
(
adapterItemPdu
);
this
.
sendUniform
(
adapterPdu
,
true
);
let
adapterPdu
=
new
pdu
[
'RCAdapterPdu'
];
adapterPdu
.
type
=
pdu
.
RCPDU_REG_ADAPTER
;
adapterPdu
.
item
.
push
(
adapterItemPdu
);
this
.
sendUniform
(
adapterPdu
,
true
);
}
//获取角色信息
getNodeInfo
(){
let
nodeInfoRecordPdu
=
new
pdu
[
'RCNodeInfoRecordPdu'
];
nodeInfoRecordPdu
.
nodeId
=
GlobalConfig
.
nodeId
;
nodeInfoRecordPdu
.
name
=
GlobalConfig
.
userName
;
nodeInfoRecordPdu
.
role
=
ApeConsts
.
userTypesToId
[
GlobalConfig
.
userRole
]
||
1
;
//NR_NORMAL用户的身份,根据用户登录时的身份设置;
nodeInfoRecordPdu
.
level
=
GlobalConfig
.
level
;
//nodeInfoRecordPdu.audioRecords= GlobalConfig.audioRecords;
//nodeInfoRecordPdu.videoRecords= GlobalConfig.videoRecords;
//nodeInfoRecordPdu.status= GlobalConfig.status;
nodeInfoRecordPdu
.
userData
=
GlobalConfig
.
userData
;
nodeInfoRecordPdu
.
userId
=
GlobalConfig
.
userId
;
nodeInfoRecordPdu
.
handUpTime
=
GlobalConfig
.
handUpTime
;
//nodeInfoRecordPdu.deviceType= GlobalConfig.deviceType;
//nodeInfoRecordPdu.mobileDirection= GlobalConfig.mobileDirection;
nodeInfoRecordPdu
.
microphones
=
GlobalConfig
.
microphones
;
nodeInfoRecordPdu
.
cameras
=
GlobalConfig
.
cameras
;
nodeInfoRecordPdu
.
openCamera
=
GlobalConfig
.
openCamera
;
nodeInfoRecordPdu
.
openMicrophones
=
GlobalConfig
.
openMicrophones
;
nodeInfoRecordPdu
.
videoQuality
=
GlobalConfig
.
videoQuality
;
nodeInfoRecordPdu
.
userIp
=
GlobalConfig
.
userIp
;
nodeInfoRecordPdu
.
curVideoQuality
=
GlobalConfig
.
curVideoQuality
;
nodeInfoRecordPdu
.
micGain
=
GlobalConfig
.
micGain
;
nodeInfoRecordPdu
.
speakerVolume
=
GlobalConfig
.
speakerVolume
;
nodeInfoRecordPdu
.
micCode
=
GlobalConfig
.
micCode
;
nodeInfoRecordPdu
.
curCamera
=
GlobalConfig
.
curCamera
;
nodeInfoRecordPdu
.
curMicrophone
=
GlobalConfig
.
curMicrophone
;
nodeInfoRecordPdu
.
country
=
GlobalConfig
.
country
;
//国家
nodeInfoRecordPdu
.
city
=
GlobalConfig
.
city
;
//城市
nodeInfoRecordPdu
.
province
=
GlobalConfig
.
province
;
//服务商
nodeInfoRecordPdu
.
isp
=
GlobalConfig
.
isp
;
//服务商
//用户的MS列表
let
msListAll
=
GlobalConfig
.
msListAll
;
for
(
let
k
=
0
;
k
<
msListAll
.
length
;
k
++
){
let
msItem
=
msListAll
[
k
];
if
(
msItem
){
let
msListItemPdu
=
new
pdu
[
'MsListItemPdu'
];
msListItemPdu
.
ip
=
msItem
.
ip
||
""
;
msListItemPdu
.
port
=
msItem
.
port
||
""
;
msListItemPdu
.
country
=
msItem
.
country
||
""
;
msListItemPdu
.
province
=
msItem
.
province
||
""
;
msListItemPdu
.
city
=
msItem
.
city
||
""
;
nodeInfoRecordPdu
.
msList
.
push
(
msListItemPdu
);
}
}
return
nodeInfoRecordPdu
;
}
//更新角色数据
updateUserInfo
(){
let
nodeInfoRecordPdu
=
this
.
getNodeInfo
();
loger
.
log
(
'更新用户信息->'
,
nodeInfoRecordPdu
);
let
userDataPdu
=
new
pdu
[
'RCNodeInfoUserDataPdu'
];
userDataPdu
.
qq
=
''
;
userDataPdu
.
skype
=
''
;
nodeInfoRecordPdu
.
userData
=
userDataPdu
.
toArrayBuffer
();
nodeInfoRecordPdu
.
deviceType
=
GlobalConfig
.
deviceType
;
//设备类型
let
item
=
new
pdu
[
'RCRegistryRosterItemPdu'
];
item
.
nodeId
=
nodeInfoRecordPdu
.
nodeId
;
item
.
nodeData
=
nodeInfoRecordPdu
.
toArrayBuffer
();
let
rosterUpdateItem
=
new
pdu
[
'RCRegistryRosterUpdateItemPdu'
];
rosterUpdateItem
.
type
=
pdu
.
RCPDU_REG_ROSTER_UPDATE_PDU
;
rosterUpdateItem
.
items
.
push
(
item
);
let
updateObjPdu
=
new
pdu
[
'RCRegistryUpdateObjPdu'
];
updateObjPdu
.
objId
=
ApeConsts
.
CONFERENCE_OBJ_ROSTER_ID
;
updateObjPdu
.
subType
=
rosterUpdateItem
.
type
;
updateObjPdu
.
userData
=
rosterUpdateItem
.
toArrayBuffer
();
//同步
let
adapterItemPdu
=
new
pdu
[
'RCAdapterItemPdu'
];
adapterItemPdu
.
type
=
pdu
.
RCPDU_REG_UPDATE_OBJ
;
adapterItemPdu
.
itemData
=
updateObjPdu
.
toArrayBuffer
();
let
adapterPdu
=
new
pdu
[
'RCAdapterPdu'
];
adapterPdu
.
type
=
pdu
.
RCPDU_REG_ADAPTER
;
adapterPdu
.
item
.
push
(
adapterItemPdu
);
this
.
sendUniform
(
adapterPdu
,
true
);
}
sendConferMsg
(
_messageInfo
)
{
if
(
this
.
_classInfo
==
null
||
EngineUtils
.
isEmptyObject
(
this
.
_classInfo
))
{
loger
.
log
(
'不能发送课堂消息.McuClient还未初始化数据!'
);
if
(
GlobalConfig
.
getCurrentStatus
().
code
==
0
||
GlobalConfig
.
getCurrentStatus
().
code
==
1
)
{
this
.
_emit
(
MessageTypes
.
MCU_ERROR
,
MessageTypes
.
ERR_APE_SEND_FAILED_NO_JOIN
);
return
;
}
return
;
}
// to, message
loger
.
log
(
'发送课堂控制消息.'
,
_messageInfo
);
let
conferSendPdu
=
new
pdu
[
'RCConferenceSendDataRequestPdu'
];
conferSendPdu
.
type
=
pdu
.
RCPDU_SEND_CONFERENCE_DATA_REQUEST
;
conferSendPdu
.
initiator
=
this
.
_classInfo
.
nodeId
;
//发起人
conferSendPdu
.
peer
=
parseInt
(
_messageInfo
.
to
);
//发送给谁,公聊的时候是0,私聊的时候是指定的用户id
conferSendPdu
.
userData
=
this
.
_rCArrayBufferUtil
.
strToUint8Array
(
"h5"
+
_messageInfo
.
message
);
//conferSendPdu.userData =UTF8.setBytesFromString(_messageInfo.message);
conferSendPdu
.
isPublic
=
true
;
conferSendPdu
.
actionType
=
_messageInfo
.
actionType
;
// if (!(conferSendPdu.isPublic || 0 === conferSendPdu.peer)) {
if
(
!
conferSendPdu
.
isPublic
&&
0
!=
conferSendPdu
.
peer
)
{
//发送给制定的人
//loger.log('发送私聊课堂消息.');
this
.
send
(
conferSendPdu
);
}
else
{
//发送给所有人
// loger.log('发送公聊课堂消息.');
this
.
sendChatUniform
(
conferSendPdu
);
}
}
//发送录制或停止录制的消息,{"recordStatus":true};true为开始录制,false为停止录制
sendConferRecordMsg
(
_param
)
{
if
(
!
this
.
mcu
.
connected
)
{
loger
.
warn
(
GlobalConfig
.
getCurrentStatus
());
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"已经断开连接"
};
}
if
(
_param
==
null
)
{
loger
.
warn
(
"控制录制状的消息发送失败,参数错误"
,
_param
);
return
;
}
/* message RCConferenceRecordRequestPdu {
optional uint32 initiator = 1; // 发起录像指令的node id
optional bool record = 2; // 录像指令 true:开始录像, false:停止录像
optional uint32 class_time = 3; // 课堂进行时间(秒)
optional string filename = 4; // 录像文件名称,filename中增加目录部分
}*/
//保存当前的录制状态
GlobalConfig
.
recordStatus
=
_param
.
recordStatus
||
false
;
let
conferRecordSendPdu
=
new
pdu
[
'RCConferenceRecordRequestPdu'
];
conferRecordSendPdu
.
type
=
pdu
.
RCPDU_CONFERENCE_RECORD_REQUEST
;
conferRecordSendPdu
.
peer
=
0
;
//channel 为0
conferRecordSendPdu
.
isPublic
=
true
;
conferRecordSendPdu
.
initiator
=
this
.
_classInfo
.
nodeId
;
//发起人
conferRecordSendPdu
.
record
=
GlobalConfig
.
recordStatus
;
//conferRecordSendPdu.classTime = GlobalConfig.classTimestamp;//不能使用课堂进行时间,这个时间结束课堂的时候会被清除
conferRecordSendPdu
.
classTime
=
GlobalConfig
.
recordTimestamp
;
//课堂录制的累积时间,不会被清除
conferRecordSendPdu
.
filename
=
GlobalConfig
.
recordFileName
||
GlobalConfig
.
classId
+
"_"
+
EngineUtils
.
creatTimestampYMD
()
+
".rec"
;
this
.
sendChatUniform
(
conferRecordSendPdu
);
// to, message
loger
.
warn
(
'发送录制消息-》'
,
_param
);
}
//开启录制
startRecord
()
{
//如果录制的时间长超出设定的最大录制时间就不再录制
if
(
GlobalConfig
.
recordTimestamp
>=
GlobalConfig
.
allowRecordMaxTime
){
loger
.
warn
(
'不能再录制,录制时间已经达到最大限制'
,
GlobalConfig
.
recordTimestamp
);
return
;
}
loger
.
log
(
'startRecord'
,
"isHost"
,
GlobalConfig
.
isHost
,
"recordStatus"
,
GlobalConfig
.
recordStatus
);
//如果是host
if
(
GlobalConfig
.
isHost
)
{
GlobalConfig
.
classStopTime
=
EngineUtils
.
creatTimestampStr
();
this
.
sendConferRecordMsg
({
"recordStatus"
:
true
});
this
.
_emit
(
MessageTypes
.
CLASS_STATUS_INFO_CHANGE
);
this
.
_emit
(
MessageTypes
.
CLASS_RECORD_START
);
//课堂开始录制
}
}
//停止录制
stopRecord
(
isForce
)
{
loger
.
log
(
'stopRecord'
,
"isHost"
,
GlobalConfig
.
isHost
,
"recordStatus"
,
GlobalConfig
.
recordStatus
);
if
(
isForce
&&
isForce
==
true
){
//强制停止,可以是host之外的身份(比如当前课堂老师异常退出,没有老师,会随机选择一个人来做释放操作)
if
(
GlobalConfig
.
recordStatus
)
{
GlobalConfig
.
classStopTime
=
EngineUtils
.
creatTimestampStr
();
this
.
sendConferRecordMsg
({
"recordStatus"
:
false
});
this
.
_emit
(
MessageTypes
.
CLASS_STATUS_INFO_CHANGE
);
}
}
else
{
//身份是host,并且当前正在录制中
if
(
GlobalConfig
.
isHost
&&
GlobalConfig
.
recordStatus
)
{
GlobalConfig
.
classStopTime
=
EngineUtils
.
creatTimestampStr
();
this
.
sendConferRecordMsg
({
"recordStatus"
:
false
});
this
.
_emit
(
MessageTypes
.
CLASS_STATUS_INFO_CHANGE
);
}
}
}
//主动离开课堂,发送通知到服务器
leaveClass
()
{
let
nodeInfoRecordPdu
=
this
.
mcu
.
mcuClassInfo
.
self
;
let
userDataPdu
=
new
pdu
[
'RCNodeInfoUserDataPdu'
];
userDataPdu
.
qq
=
''
;
userDataPdu
.
skype
=
''
;
nodeInfoRecordPdu
.
userData
=
userDataPdu
.
toArrayBuffer
();
nodeInfoRecordPdu
.
deviceType
=
GlobalConfig
.
deviceType
;
let
item
=
new
pdu
[
'RCRegistryRosterItemPdu'
];
item
.
nodeId
=
nodeInfoRecordPdu
.
nodeId
;
item
.
nodeData
=
nodeInfoRecordPdu
.
toArrayBuffer
();
let
rosterUpdateItem
=
new
pdu
[
'RCRegistryRosterDeleteItemPdu'
];
rosterUpdateItem
.
type
=
pdu
.
RCPDU_REG_ROSTER_DELETE_PDU
;
rosterUpdateItem
.
nodeId
=
GlobalConfig
.
nodeId
;
let
updateObjPdu
=
new
pdu
[
'RCRegistryUpdateObjPdu'
];
updateObjPdu
.
objId
=
ApeConsts
.
CONFERENCE_OBJ_ROSTER_ID
;
updateObjPdu
.
subType
=
rosterUpdateItem
.
type
;
updateObjPdu
.
userData
=
rosterUpdateItem
.
toArrayBuffer
();
let
adapterItemPdu
=
new
pdu
[
'RCAdapterItemPdu'
];
adapterItemPdu
.
type
=
pdu
.
RCPDU_REG_UPDATE_OBJ
;
adapterItemPdu
.
itemData
=
updateObjPdu
.
toArrayBuffer
();
let
adapterPdu
=
new
pdu
[
'RCAdapterPdu'
];
adapterPdu
.
type
=
pdu
.
RCPDU_REG_ADAPTER
;
adapterPdu
.
item
.
push
(
adapterItemPdu
);
this
.
sendUniform
(
adapterPdu
,
true
);
}
//还原课堂状态
restorClass
()
{
GlobalConfig
.
classTimestamp
=
0
;
GlobalConfig
.
classStatus
=
ApeConsts
.
CLASS_STATUS_WAIT
;
getNodeInfo
()
{
let
nodeInfoRecordPdu
=
new
pdu
[
'RCNodeInfoRecordPdu'
];
nodeInfoRecordPdu
.
nodeId
=
GlobalConfig
.
nodeId
;
nodeInfoRecordPdu
.
selfSilence
=
JSON
.
stringify
(
GlobalConfig
.
selfSilence
);
nodeInfoRecordPdu
.
name
=
GlobalConfig
.
userName
;
nodeInfoRecordPdu
.
role
=
ApeConsts
.
userTypesToId
[
GlobalConfig
.
userRole
]
||
1
;
//NR_NORMAL用户的身份,根据用户登录时的身份设置;
nodeInfoRecordPdu
.
level
=
GlobalConfig
.
level
;
//nodeInfoRecordPdu.audioRecords= GlobalConfig.audioRecords;
//nodeInfoRecordPdu.videoRecords= GlobalConfig.videoRecords;
//nodeInfoRecordPdu.status= GlobalConfig.status;
nodeInfoRecordPdu
.
userData
=
GlobalConfig
.
userData
;
nodeInfoRecordPdu
.
userId
=
GlobalConfig
.
userId
;
nodeInfoRecordPdu
.
handUpTime
=
GlobalConfig
.
handUpTime
;
//nodeInfoRecordPdu.deviceType= GlobalConfig.deviceType;
//nodeInfoRecordPdu.mobileDirection= GlobalConfig.mobileDirection;
nodeInfoRecordPdu
.
microphones
=
GlobalConfig
.
microphones
;
nodeInfoRecordPdu
.
cameras
=
GlobalConfig
.
cameras
;
nodeInfoRecordPdu
.
openCamera
=
GlobalConfig
.
openCamera
;
nodeInfoRecordPdu
.
openMicrophones
=
GlobalConfig
.
openMicrophones
;
nodeInfoRecordPdu
.
videoQuality
=
GlobalConfig
.
videoQuality
;
nodeInfoRecordPdu
.
userIp
=
GlobalConfig
.
userIp
;
nodeInfoRecordPdu
.
curVideoQuality
=
GlobalConfig
.
curVideoQuality
;
nodeInfoRecordPdu
.
micGain
=
GlobalConfig
.
micGain
;
nodeInfoRecordPdu
.
speakerVolume
=
GlobalConfig
.
speakerVolume
;
nodeInfoRecordPdu
.
micCode
=
GlobalConfig
.
micCode
;
nodeInfoRecordPdu
.
curCamera
=
GlobalConfig
.
curCamera
;
nodeInfoRecordPdu
.
curMicrophone
=
GlobalConfig
.
curMicrophone
;
nodeInfoRecordPdu
.
country
=
GlobalConfig
.
country
;
//国家
nodeInfoRecordPdu
.
city
=
GlobalConfig
.
city
;
//城市
nodeInfoRecordPdu
.
province
=
GlobalConfig
.
province
;
//服务商
nodeInfoRecordPdu
.
isp
=
GlobalConfig
.
isp
;
//服务商
//用户的MS列表
let
msListAll
=
GlobalConfig
.
msListAll
;
for
(
let
k
=
0
;
k
<
msListAll
.
length
;
k
++
)
{
let
msItem
=
msListAll
[
k
];
if
(
msItem
)
{
let
msListItemPdu
=
new
pdu
[
'MsListItemPdu'
];
msListItemPdu
.
ip
=
msItem
.
ip
||
""
;
msListItemPdu
.
port
=
msItem
.
port
||
""
;
msListItemPdu
.
country
=
msItem
.
country
||
""
;
msListItemPdu
.
province
=
msItem
.
province
||
""
;
msListItemPdu
.
city
=
msItem
.
city
||
""
;
nodeInfoRecordPdu
.
msList
.
push
(
msListItemPdu
);
}
}
return
nodeInfoRecordPdu
;
}
//更新角色数据
updateUserInfo
()
{
let
nodeInfoRecordPdu
=
this
.
getNodeInfo
();
loger
.
log
(
'更新用户信息->'
,
nodeInfoRecordPdu
);
let
userDataPdu
=
new
pdu
[
'RCNodeInfoUserDataPdu'
];
userDataPdu
.
qq
=
''
;
userDataPdu
.
skype
=
''
;
nodeInfoRecordPdu
.
userData
=
userDataPdu
.
toArrayBuffer
();
nodeInfoRecordPdu
.
deviceType
=
GlobalConfig
.
deviceType
;
//设备类型
let
item
=
new
pdu
[
'RCRegistryRosterItemPdu'
];
item
.
nodeId
=
nodeInfoRecordPdu
.
nodeId
;
item
.
nodeData
=
nodeInfoRecordPdu
.
toArrayBuffer
();
let
rosterUpdateItem
=
new
pdu
[
'RCRegistryRosterUpdateItemPdu'
];
rosterUpdateItem
.
type
=
pdu
.
RCPDU_REG_ROSTER_UPDATE_PDU
;
rosterUpdateItem
.
items
.
push
(
item
);
let
updateObjPdu
=
new
pdu
[
'RCRegistryUpdateObjPdu'
];
updateObjPdu
.
objId
=
ApeConsts
.
CONFERENCE_OBJ_ROSTER_ID
;
updateObjPdu
.
subType
=
rosterUpdateItem
.
type
;
updateObjPdu
.
userData
=
rosterUpdateItem
.
toArrayBuffer
();
//同步
let
adapterItemPdu
=
new
pdu
[
'RCAdapterItemPdu'
];
adapterItemPdu
.
type
=
pdu
.
RCPDU_REG_UPDATE_OBJ
;
adapterItemPdu
.
itemData
=
updateObjPdu
.
toArrayBuffer
();
let
adapterPdu
=
new
pdu
[
'RCAdapterPdu'
];
adapterPdu
.
type
=
pdu
.
RCPDU_REG_ADAPTER
;
adapterPdu
.
item
.
push
(
adapterItemPdu
);
this
.
sendUniform
(
adapterPdu
,
true
);
}
sendConferMsg
(
_messageInfo
)
{
if
(
this
.
_classInfo
==
null
||
EngineUtils
.
isEmptyObject
(
this
.
_classInfo
))
{
loger
.
log
(
'不能发送课堂消息.McuClient还未初始化数据!'
);
if
(
GlobalConfig
.
getCurrentStatus
().
code
==
0
||
GlobalConfig
.
getCurrentStatus
().
code
==
1
)
{
this
.
_emit
(
MessageTypes
.
MCU_ERROR
,
MessageTypes
.
ERR_APE_SEND_FAILED_NO_JOIN
);
return
;
}
return
;
}
// to, message
loger
.
log
(
'发送课堂控制消息.'
,
_messageInfo
);
let
conferSendPdu
=
new
pdu
[
'RCConferenceSendDataRequestPdu'
];
conferSendPdu
.
type
=
pdu
.
RCPDU_SEND_CONFERENCE_DATA_REQUEST
;
conferSendPdu
.
initiator
=
this
.
_classInfo
.
nodeId
;
//发起人
conferSendPdu
.
peer
=
parseInt
(
_messageInfo
.
to
);
//发送给谁,公聊的时候是0,私聊的时候是指定的用户id
conferSendPdu
.
userData
=
this
.
_rCArrayBufferUtil
.
strToUint8Array
(
"h5"
+
_messageInfo
.
message
);
//conferSendPdu.userData =UTF8.setBytesFromString(_messageInfo.message);
conferSendPdu
.
isPublic
=
true
;
conferSendPdu
.
actionType
=
_messageInfo
.
actionType
;
// if (!(conferSendPdu.isPublic || 0 === conferSendPdu.peer)) {
if
(
!
conferSendPdu
.
isPublic
&&
0
!=
conferSendPdu
.
peer
)
{
//发送给制定的人
//loger.log('发送私聊课堂消息.');
this
.
send
(
conferSendPdu
);
}
else
{
//发送给所有人
// loger.log('发送公聊课堂消息.');
this
.
sendChatUniform
(
conferSendPdu
);
}
}
//发送录制或停止录制的消息,{"recordStatus":true};true为开始录制,false为停止录制
sendConferRecordMsg
(
_param
)
{
if
(
!
this
.
mcu
.
connected
)
{
loger
.
warn
(
GlobalConfig
.
getCurrentStatus
());
return
{
"code"
:
ApeConsts
.
RETURN_FAILED
,
"data"
:
"已经断开连接"
};
}
if
(
_param
==
null
)
{
loger
.
warn
(
"控制录制状的消息发送失败,参数错误"
,
_param
);
return
;
}
/* message RCConferenceRecordRequestPdu {
optional uint32 initiator = 1; // 发起录像指令的node id
optional bool record = 2; // 录像指令 true:开始录像, false:停止录像
optional uint32 class_time = 3; // 课堂进行时间(秒)
optional string filename = 4; // 录像文件名称,filename中增加目录部分
}*/
//保存当前的录制状态
GlobalConfig
.
recordStatus
=
_param
.
recordStatus
||
false
;
let
conferRecordSendPdu
=
new
pdu
[
'RCConferenceRecordRequestPdu'
];
conferRecordSendPdu
.
type
=
pdu
.
RCPDU_CONFERENCE_RECORD_REQUEST
;
conferRecordSendPdu
.
peer
=
0
;
//channel 为0
conferRecordSendPdu
.
isPublic
=
true
;
conferRecordSendPdu
.
initiator
=
this
.
_classInfo
.
nodeId
;
//发起人
conferRecordSendPdu
.
record
=
GlobalConfig
.
recordStatus
;
//conferRecordSendPdu.classTime = GlobalConfig.classTimestamp;//不能使用课堂进行时间,这个时间结束课堂的时候会被清除
conferRecordSendPdu
.
classTime
=
GlobalConfig
.
recordTimestamp
;
//课堂录制的累积时间,不会被清除
conferRecordSendPdu
.
filename
=
GlobalConfig
.
recordFileName
||
GlobalConfig
.
classId
+
"_"
+
EngineUtils
.
creatTimestampYMD
()
+
".rec"
;
this
.
sendChatUniform
(
conferRecordSendPdu
);
// to, message
loger
.
warn
(
'发送录制消息-》'
,
_param
);
}
//开启录制
startRecord
()
{
//如果录制的时间长超出设定的最大录制时间就不再录制
if
(
GlobalConfig
.
recordTimestamp
>=
GlobalConfig
.
allowRecordMaxTime
)
{
loger
.
warn
(
'不能再录制,录制时间已经达到最大限制'
,
GlobalConfig
.
recordTimestamp
);
return
;
}
loger
.
log
(
'startRecord'
,
"isHost"
,
GlobalConfig
.
isHost
,
"recordStatus"
,
GlobalConfig
.
recordStatus
);
//如果是host
if
(
GlobalConfig
.
isHost
)
{
GlobalConfig
.
classStopTime
=
EngineUtils
.
creatTimestampStr
();
this
.
sendConferRecordMsg
({
"recordStatus"
:
true
});
this
.
_emit
(
MessageTypes
.
CLASS_STATUS_INFO_CHANGE
);
this
.
_emit
(
MessageTypes
.
CLASS_RECORD_START
);
//课堂开始录制
}
}
//停止录制
stopRecord
(
isForce
)
{
loger
.
log
(
'stopRecord'
,
"isHost"
,
GlobalConfig
.
isHost
,
"recordStatus"
,
GlobalConfig
.
recordStatus
);
if
(
isForce
&&
isForce
==
true
)
{
//强制停止,可以是host之外的身份(比如当前课堂老师异常退出,没有老师,会随机选择一个人来做释放操作)
if
(
GlobalConfig
.
recordStatus
)
{
GlobalConfig
.
classStopTime
=
EngineUtils
.
creatTimestampStr
();
this
.
s
topRecord
(
);
this
.
s
endConferRecordMsg
({
"recordStatus"
:
false
}
);
this
.
_emit
(
MessageTypes
.
CLASS_STATUS_INFO_CHANGE
);
this
.
sendUpdaterClassStatusInfo
({
"actionType"
:
0
,
isStopAllPublishMedia
:
true
});
loger
.
log
(
'restorClass'
);
}
//开始上课
startClass
(
_param
)
{
if
(
GlobalConfig
.
isHost
)
{
let
timestamp
=
EngineUtils
.
creatTimestampStr
();
GlobalConfig
.
classStopTime
=
timestamp
;
//如果录制的文件名不存在,需要创建一个名字
let
timestampYMD
=
EngineUtils
.
creatTimestampYMD
();
GlobalConfig
.
recordFileName
=
GlobalConfig
.
recordFileName
||
GlobalConfig
.
siteId
+
"/"
+
timestampYMD
+
"/"
+
GlobalConfig
.
classId
+
"_"
+
timestampYMD
+
".rec"
;
//4、文件名称 $RECORD_HOME/`site id`/`日期`/`filename` 例:/data/record/su/20161216/`filename`
if
(
GlobalConfig
.
classStatus
==
ApeConsts
.
CLASS_STATUS_WAIT
)
{
//之前是为开始状态,第一次点开始
GlobalConfig
.
classStartTime
=
timestamp
;
}
GlobalConfig
.
classStatus
=
ApeConsts
.
CLASS_STATUS_STARTED
;
//开始录制
this
.
startRecord
();
//课堂状态改变
this
.
_emit
(
MessageTypes
.
CLASS_STATUS_INFO_CHANGE
);
//同步课堂状态
this
.
sendUpdaterClassStatusInfo
({
"actionType"
:
1
,
isStopAllPublishMedia
:
true
});
//开始计时
this
.
startTimerCounter
();
}
else
{
loger
.
warn
(
'没有开始课堂的权限'
);
}
}
//暂停上课 {isForce:true} isForce->是否强制提交(true为是)
pauseClass
(
_param
)
{
if
(
GlobalConfig
.
classStatus
==
ApeConsts
.
CLASS_STATUS_WAIT
)
{
loger
.
warn
(
'还没有开始,不能点暂停'
);
return
;
}
GlobalConfig
.
classStatus
=
ApeConsts
.
CLASS_STATUS_PAUSE
;
}
}
else
{
//身份是host,并且当前正在录制中
if
(
GlobalConfig
.
isHost
&&
GlobalConfig
.
recordStatus
)
{
GlobalConfig
.
classStopTime
=
EngineUtils
.
creatTimestampStr
();
this
.
stopRecord
();
this
.
_emit
(
MessageTypes
.
CLASS_STATUS_INFO_CHANGE
,
_param
);
this
.
sendUpdaterClassStatusInfo
({
"actionType"
:
2
,
isStopAllPublishMedia
:
true
});
this
.
stopTimerCounter
();
}
//关闭课堂
closeClass
(
_param
)
{
if
(
GlobalConfig
.
classStatus
==
ApeConsts
.
CLASS_STATUS_WAIT
)
{
loger
.
warn
(
'还没有开始,不能点关闭'
);
return
;
}
this
.
stopTimerCounter
();
this
.
restorClass
();
//把所有人都踢出课堂
this
.
sendConferMsg
({
"to"
:
0
,
"message"
:
"所有人退出课堂"
,
"actionType"
:
ApeConsts
.
CLASS_ACTION_CLOSE_ALL
});
this
.
sendConferRecordMsg
({
"recordStatus"
:
false
});
this
.
_emit
(
MessageTypes
.
CLASS_STATUS_INFO_CHANGE
);
}
}
}
//主动离开课堂,发送通知到服务器
leaveClass
()
{
let
nodeInfoRecordPdu
=
this
.
mcu
.
mcuClassInfo
.
self
;
let
userDataPdu
=
new
pdu
[
'RCNodeInfoUserDataPdu'
];
userDataPdu
.
qq
=
''
;
userDataPdu
.
skype
=
''
;
nodeInfoRecordPdu
.
userData
=
userDataPdu
.
toArrayBuffer
();
nodeInfoRecordPdu
.
deviceType
=
GlobalConfig
.
deviceType
;
let
item
=
new
pdu
[
'RCRegistryRosterItemPdu'
];
item
.
nodeId
=
nodeInfoRecordPdu
.
nodeId
;
item
.
nodeData
=
nodeInfoRecordPdu
.
toArrayBuffer
();
let
rosterUpdateItem
=
new
pdu
[
'RCRegistryRosterDeleteItemPdu'
];
rosterUpdateItem
.
type
=
pdu
.
RCPDU_REG_ROSTER_DELETE_PDU
;
rosterUpdateItem
.
nodeId
=
GlobalConfig
.
nodeId
;
let
updateObjPdu
=
new
pdu
[
'RCRegistryUpdateObjPdu'
];
updateObjPdu
.
objId
=
ApeConsts
.
CONFERENCE_OBJ_ROSTER_ID
;
updateObjPdu
.
subType
=
rosterUpdateItem
.
type
;
updateObjPdu
.
userData
=
rosterUpdateItem
.
toArrayBuffer
();
let
adapterItemPdu
=
new
pdu
[
'RCAdapterItemPdu'
];
adapterItemPdu
.
type
=
pdu
.
RCPDU_REG_UPDATE_OBJ
;
adapterItemPdu
.
itemData
=
updateObjPdu
.
toArrayBuffer
();
let
adapterPdu
=
new
pdu
[
'RCAdapterPdu'
];
adapterPdu
.
type
=
pdu
.
RCPDU_REG_ADAPTER
;
adapterPdu
.
item
.
push
(
adapterItemPdu
);
this
.
sendUniform
(
adapterPdu
,
true
);
}
//还原课堂状态
restorClass
()
{
GlobalConfig
.
classTimestamp
=
0
;
GlobalConfig
.
classStatus
=
ApeConsts
.
CLASS_STATUS_WAIT
;
GlobalConfig
.
classStopTime
=
EngineUtils
.
creatTimestampStr
();
this
.
stopRecord
();
this
.
_emit
(
MessageTypes
.
CLASS_STATUS_INFO_CHANGE
);
this
.
sendUpdaterClassStatusInfo
({
"actionType"
:
0
,
isStopAllPublishMedia
:
true
});
loger
.
log
(
'restorClass'
);
}
// 全局禁言
silenceClass
(
isSilence
)
{
if
(
GlobalConfig
.
isHost
)
{
GlobalConfig
.
silence
=
!!
isSilence
;
//禁言状态改变
this
.
_emit
(
MessageTypes
.
CLASS_SILENCE_CHANGE
,
GlobalConfig
.
silence
);
//同步禁言状态
this
.
sendUpdaterClassStatusInfo
();
}
else
{
loger
.
warn
(
'没有开始课堂的权限'
);
}
}
//开始上课
startClass
(
_param
)
{
if
(
GlobalConfig
.
isHost
)
{
let
timestamp
=
EngineUtils
.
creatTimestampStr
();
GlobalConfig
.
classStopTime
=
timestamp
;
//如果录制的文件名不存在,需要创建一个名字
let
timestampYMD
=
EngineUtils
.
creatTimestampYMD
();
GlobalConfig
.
recordFileName
=
GlobalConfig
.
recordFileName
||
GlobalConfig
.
siteId
+
"/"
+
timestampYMD
+
"/"
+
GlobalConfig
.
classId
+
"_"
+
timestampYMD
+
".rec"
;
//4、文件名称 $RECORD_HOME/`site id`/`日期`/`filename` 例:/data/record/su/20161216/`filename`
if
(
GlobalConfig
.
classStatus
==
ApeConsts
.
CLASS_STATUS_WAIT
)
{
//之前是为开始状态,第一次点开始
GlobalConfig
.
classStartTime
=
timestamp
;
}
GlobalConfig
.
classStatus
=
ApeConsts
.
CLASS_STATUS_STARTED
;
//开始录制
this
.
startRecord
();
//课堂状态改变
this
.
_emit
(
MessageTypes
.
CLASS_STATUS_INFO_CHANGE
);
//同步课堂状态
this
.
sendUpdaterClassStatusInfo
({
"actionType"
:
1
,
isStopAllPublishMedia
:
true
});
//开始计时
this
.
startTimerCounter
();
}
else
{
loger
.
warn
(
'没有开始课堂的权限'
);
}
}
//暂停上课 {isForce:true} isForce->是否强制提交(true为是)
pauseClass
(
_param
)
{
if
(
GlobalConfig
.
classStatus
==
ApeConsts
.
CLASS_STATUS_WAIT
)
{
loger
.
warn
(
'还没有开始,不能点暂停'
);
return
;
}
GlobalConfig
.
classStatus
=
ApeConsts
.
CLASS_STATUS_PAUSE
;
GlobalConfig
.
classStopTime
=
EngineUtils
.
creatTimestampStr
();
this
.
stopRecord
();
this
.
_emit
(
MessageTypes
.
CLASS_STATUS_INFO_CHANGE
,
_param
);
this
.
sendUpdaterClassStatusInfo
({
"actionType"
:
2
,
isStopAllPublishMedia
:
true
});
this
.
stopTimerCounter
();
}
//关闭课堂
closeClass
(
_param
)
{
if
(
GlobalConfig
.
classStatus
==
ApeConsts
.
CLASS_STATUS_WAIT
)
{
loger
.
warn
(
'还没有开始,不能点关闭'
);
return
;
}
this
.
stopTimerCounter
();
this
.
restorClass
();
//把所有人都踢出课堂
this
.
sendConferMsg
({
"to"
:
0
,
"message"
:
"所有人退出课堂"
,
"actionType"
:
ApeConsts
.
CLASS_ACTION_CLOSE_ALL
});
}
//更新设备信息
updateDeviceInfo
(
_param
){
loger
.
log
(
'更新用户的设备信息->'
,
_param
);
this
.
updateUserInfo
();
}
//控制举手状态
controlHandUpStatus
(
_param
){
//控制用户的举手状态
if
(
!
_param
||!
_param
.
nodeId
){
loger
.
log
(
'控制举手状态->失败->参数错误'
,
_param
);
return
;
}
let
msgObj
=
{};
msgObj
.
nodeId
=
_param
.
nodeId
;
msgObj
.
isHandUp
=
false
;
if
(
_param
&&
_param
.
isHandUp
==
true
){
msgObj
.
isHandUp
=
true
;
}
this
.
sendConferMsg
({
"to"
:
_param
.
nodeId
,
"message"
:
JSON
.
stringify
(
msgObj
),
"actionType"
:
ApeConsts
.
CLASS_ACTION_HANDUP_STATUS_CHANGE
});
}
//切换举手状态
changeHandUpStatus
(
_param
){
loger
.
log
(
'切换举手状态->'
,
_param
);
if
(
_param
&&
_param
.
isHandUp
==
true
){
//举手
GlobalConfig
.
handUpTime
=
EngineUtils
.
creatTimestamp
();
}
else
{
GlobalConfig
.
handUpTime
=
0
;
//默认0是没有举手的状态(大于0就是举手)
}
this
.
updateUserInfo
();
updateDeviceInfo
(
_param
)
{
loger
.
log
(
'更新用户的设备信息->'
,
_param
);
this
.
updateUserInfo
();
}
// 禁言控制
controlSilenceStatus
(
_param
)
{
//控制用户的禁言状态
if
(
!
_param
||
!
_param
.
nodeId
)
{
loger
.
log
(
'控制禁言状态->失败->参数错误'
,
_param
);
return
;
}
let
msgObj
=
{};
msgObj
.
nodeId
=
_param
.
nodeId
;
msgObj
.
silence
=
_param
.
silence
||
''
;
this
.
sendConferMsg
({
"to"
:
_param
.
nodeId
,
"message"
:
JSON
.
stringify
(
msgObj
),
"actionType"
:
ApeConsts
.
USER_ACTION_SILENCE_STATUS_CHANGE
});
}
changeSilenceStatus
(
_param
)
{
loger
.
log
(
'切换禁言状态->'
,
_param
);
GlobalConfig
.
selfSilence
=
_param
.
silence
;
this
.
updateUserInfo
();
}
//控制举手状态
controlHandUpStatus
(
_param
)
{
//控制用户的举手状态
if
(
!
_param
||
!
_param
.
nodeId
)
{
loger
.
log
(
'控制举手状态->失败->参数错误'
,
_param
);
return
;
}
let
msgObj
=
{};
msgObj
.
nodeId
=
_param
.
nodeId
;
msgObj
.
isHandUp
=
false
;
if
(
_param
&&
_param
.
isHandUp
==
true
)
{
msgObj
.
isHandUp
=
true
;
}
this
.
sendConferMsg
({
"to"
:
_param
.
nodeId
,
"message"
:
JSON
.
stringify
(
msgObj
),
"actionType"
:
ApeConsts
.
CLASS_ACTION_HANDUP_STATUS_CHANGE
});
}
//切换举手状态
changeHandUpStatus
(
_param
)
{
loger
.
log
(
'切换举手状态->'
,
_param
);
if
(
_param
&&
_param
.
isHandUp
==
true
)
{
//举手
GlobalConfig
.
handUpTime
=
EngineUtils
.
creatTimestamp
();
}
else
{
GlobalConfig
.
handUpTime
=
0
;
//默认0是没有举手的状态(大于0就是举手)
}
this
.
updateUserInfo
();
}
//课堂的场景模块发送改变
sceneTableChange
(
_param
){
if
(
GlobalConfig
.
isRecordPlayBack
){
return
;
}
loger
.
log
(
'切换文档-媒体-屏幕模块切换->'
,
_param
);
//如果是host身份
if
(
GlobalConfig
.
isHost
)
{
if
(
_param
){
GlobalConfig
.
currentSceneTableId
=
parseInt
(
_param
.
currentSceneTableId
)
||
0
;
//当前场景显示的模块 0=文档模块、1=屏幕共享、2=媒体共享
//保存数据到Sass
this
.
_emit
(
MessageTypes
.
CLASS_STATUS_INFO_CHANGE
);
//同步消息给其他人
this
.
sendUpdaterClassStatusInfo
({
"actionType"
:
1
,
isStopAllPublishMedia
:
false
});
}
}
sceneTableChange
(
_param
)
{
if
(
GlobalConfig
.
isRecordPlayBack
)
{
return
;
}
loger
.
log
(
'切换文档-媒体-屏幕模块切换->'
,
_param
);
//如果是host身份
if
(
GlobalConfig
.
isHost
)
{
if
(
_param
)
{
GlobalConfig
.
currentSceneTableId
=
parseInt
(
_param
.
currentSceneTableId
)
||
0
;
//当前场景显示的模块 0=文档模块、1=屏幕共享、2=媒体共享
//保存数据到Sass
this
.
_emit
(
MessageTypes
.
CLASS_STATUS_INFO_CHANGE
);
//同步消息给其他人
this
.
sendUpdaterClassStatusInfo
({
"actionType"
:
1
,
isStopAllPublishMedia
:
false
});
}
}
}
//更新课堂信息
sendUpdaterClassStatusInfo
(
_param
)
{
//{"actionType": 1,isStopAllPublishMedia:false} //actionType课堂状态 isStopAllPublishMedia是否停止当前的所有推流
loger
.
log
(
'发送更新课堂信息->'
);
if
(
_param
==
null
||
EngineUtils
.
isEmptyObject
(
_param
))
{
loger
.
log
(
'发送更新课堂信息->参数错误'
);
this
.
_emit
(
MessageTypes
.
MCU_ERROR
,
MessageTypes
.
ERR_APE_INTERFACE_PARAM_WRONG
);
return
;
}
let
itemIdx
=
ApeConsts
.
CONFERENCE_OBJ_TABLE_ID
;
// itemIdx=_param.itemIdx;
let
modelPdu
=
this
.
packPdu
(
_param
,
itemIdx
);
loger
.
log
(
modelPdu
);
if
(
modelPdu
==
null
)
{
loger
.
log
(
'发送更新课堂信息->参数错误'
);
this
.
_emit
(
MessageTypes
.
MCU_ERROR
,
MessageTypes
.
ERR_APE_INTERFACE_PARAM_WRONG
);
return
;
}
let
tableItemPdu
=
new
pdu
[
'RCRegistryTableItemPdu'
];
tableItemPdu
.
itemIdx
=
itemIdx
;
tableItemPdu
.
owner
=
0
;
//收到flash的是这个值,不清楚先写固定
tableItemPdu
.
registerObjId
=
ApeConsts
.
CONFERENCE_OBJ_TABLE_ID
;
tableItemPdu
.
itemData
=
modelPdu
.
toArrayBuffer
();
//updater
let
tableUpdateItem
=
new
pdu
[
'RCRegistryTableUpdateItemPdu'
];
//optional RCPduType_E type = 1 [default = RCPDU_REG_TABLE_UPDATE_PDU];
//repeated RCRegistryTableItemPdu items = 2;
tableUpdateItem
.
type
=
pdu
.
RCPDU_REG_TABLE_UPDATE_PDU
;
//
tableUpdateItem
.
items
.
push
(
tableItemPdu
);
let
updateObjPdu
=
new
pdu
[
'RCRegistryUpdateObjPdu'
];
updateObjPdu
.
objId
=
ApeConsts
.
CONFERENCE_OBJ_TABLE_ID
;
updateObjPdu
.
subType
=
tableUpdateItem
.
type
;
updateObjPdu
.
userData
=
tableUpdateItem
.
toArrayBuffer
();
//同步
let
adapterItemPdu
=
new
pdu
[
'RCAdapterItemPdu'
];
adapterItemPdu
.
type
=
pdu
.
RCPDU_REG_UPDATE_OBJ
;
adapterItemPdu
.
itemData
=
updateObjPdu
.
toArrayBuffer
();
let
adapterPdu
=
new
pdu
[
'RCAdapterPdu'
];
adapterPdu
.
type
=
pdu
.
RCPDU_REG_ADAPTER
;
adapterPdu
.
item
.
push
(
adapterItemPdu
);
this
.
sendUniform
(
adapterPdu
,
true
);
}
/////收到消息处理/////////////////////////////////////////////////////////////////////////////////
//加入channel成功
onJoinChannelHandlerSuccess
()
{
loger
.
log
(
'ConferApe.onJoinChannelHandlerSuccess'
,
GlobalConfig
.
classStatus
);
this
.
timerCounter
.
addTimerCallBack
(
this
.
timerCounterUptate
.
bind
(
this
),
1
);
//如果当前课堂正在进行中,开启计时器
if
(
GlobalConfig
.
classStatus
==
ApeConsts
.
CLASS_STATUS_STARTED
)
{
//开始计时
this
.
startTimerCounter
();
//如果是host ,开始录制
this
.
startRecord
();
}
else
if
(
GlobalConfig
.
classStatus
==
ApeConsts
.
CLASS_STATUS_WAIT
&&
GlobalConfig
.
isHost
&&
GlobalConfig
.
isAutoStartClass
&&
!
GlobalConfig
.
isRecordPlayBack
){
//自动开始上课的4个条件
//1.如果自己是host,2.Sass配置的是自动开始上课,3.并且当前是未开始状态,4.当前不是录制回放,开始自动上课
loger
.
log
(
'自动开始上课->classStatus:'
,
GlobalConfig
.
classStatus
,
" isHost:"
,
GlobalConfig
.
isHost
,
" isAutoStartClass:"
,
GlobalConfig
.
isAutoStartClass
,
" isRecordPlayBack:"
,
GlobalConfig
.
isRecordPlayBack
);
this
.
startClass
();
}
}
//开启计时器
startTimerCounter
()
{
this
.
stopTimerCounter
();
if
(
this
.
timerCounter
){
this
.
timerCounter
.
startTimer
();
}
sendUpdaterClassStatusInfo
(
_param
)
{
//{"actionType": 1,isStopAllPublishMedia:false} //actionType课堂状态 isStopAllPublishMedia是否停止当前的所有推流
loger
.
log
(
'发送更新课堂信息->'
);
if
(
_param
==
null
||
EngineUtils
.
isEmptyObject
(
_param
))
{
loger
.
log
(
'发送更新课堂信息->参数错误'
);
this
.
_emit
(
MessageTypes
.
MCU_ERROR
,
MessageTypes
.
ERR_APE_INTERFACE_PARAM_WRONG
);
return
;
}
let
itemIdx
=
ApeConsts
.
CONFERENCE_OBJ_TABLE_ID
;
// itemIdx=_param.itemIdx;
let
modelPdu
=
this
.
packPdu
(
_param
,
itemIdx
);
loger
.
log
(
modelPdu
);
if
(
modelPdu
==
null
)
{
loger
.
log
(
'发送更新课堂信息->参数错误'
);
this
.
_emit
(
MessageTypes
.
MCU_ERROR
,
MessageTypes
.
ERR_APE_INTERFACE_PARAM_WRONG
);
return
;
}
let
tableItemPdu
=
new
pdu
[
'RCRegistryTableItemPdu'
];
tableItemPdu
.
itemIdx
=
itemIdx
;
tableItemPdu
.
owner
=
0
;
//收到flash的是这个值,不清楚先写固定
tableItemPdu
.
registerObjId
=
ApeConsts
.
CONFERENCE_OBJ_TABLE_ID
;
tableItemPdu
.
itemData
=
modelPdu
.
toArrayBuffer
();
//updater
let
tableUpdateItem
=
new
pdu
[
'RCRegistryTableUpdateItemPdu'
];
//optional RCPduType_E type = 1 [default = RCPDU_REG_TABLE_UPDATE_PDU];
//repeated RCRegistryTableItemPdu items = 2;
tableUpdateItem
.
type
=
pdu
.
RCPDU_REG_TABLE_UPDATE_PDU
;
//
tableUpdateItem
.
items
.
push
(
tableItemPdu
);
let
updateObjPdu
=
new
pdu
[
'RCRegistryUpdateObjPdu'
];
updateObjPdu
.
objId
=
ApeConsts
.
CONFERENCE_OBJ_TABLE_ID
;
updateObjPdu
.
subType
=
tableUpdateItem
.
type
;
updateObjPdu
.
userData
=
tableUpdateItem
.
toArrayBuffer
();
//同步
let
adapterItemPdu
=
new
pdu
[
'RCAdapterItemPdu'
];
adapterItemPdu
.
type
=
pdu
.
RCPDU_REG_UPDATE_OBJ
;
adapterItemPdu
.
itemData
=
updateObjPdu
.
toArrayBuffer
();
let
adapterPdu
=
new
pdu
[
'RCAdapterPdu'
];
adapterPdu
.
type
=
pdu
.
RCPDU_REG_ADAPTER
;
adapterPdu
.
item
.
push
(
adapterItemPdu
);
this
.
sendUniform
(
adapterPdu
,
true
);
}
/////收到消息处理/////////////////////////////////////////////////////////////////////////////////
//加入channel成功
onJoinChannelHandlerSuccess
()
{
loger
.
log
(
'ConferApe.onJoinChannelHandlerSuccess'
,
GlobalConfig
.
classStatus
);
this
.
timerCounter
.
addTimerCallBack
(
this
.
timerCounterUptate
.
bind
(
this
),
1
);
//如果当前课堂正在进行中,开启计时器
if
(
GlobalConfig
.
classStatus
==
ApeConsts
.
CLASS_STATUS_STARTED
)
{
//开始计时
this
.
startTimerCounter
();
//如果是host ,开始录制
this
.
startRecord
();
}
else
if
(
GlobalConfig
.
classStatus
==
ApeConsts
.
CLASS_STATUS_WAIT
&&
GlobalConfig
.
isHost
&&
GlobalConfig
.
isAutoStartClass
&&
!
GlobalConfig
.
isRecordPlayBack
)
{
//自动开始上课的4个条件
//1.如果自己是host,2.Sass配置的是自动开始上课,3.并且当前是未开始状态,4.当前不是录制回放,开始自动上课
loger
.
log
(
'自动开始上课->classStatus:'
,
GlobalConfig
.
classStatus
,
" isHost:"
,
GlobalConfig
.
isHost
,
" isAutoStartClass:"
,
GlobalConfig
.
isAutoStartClass
,
" isRecordPlayBack:"
,
GlobalConfig
.
isRecordPlayBack
);
this
.
startClass
();
}
}
//开启计时器
startTimerCounter
()
{
this
.
stopTimerCounter
();
if
(
this
.
timerCounter
)
{
this
.
timerCounter
.
startTimer
();
}
}
//停止计时器
stopTimerCounter
()
{
if
(
this
.
timerCounter
)
{
this
.
timerCounter
.
stopTimer
();
}
}
timerCounterUptate
()
{
if
(
!
this
.
mcu
.
connected
)
{
loger
.
warn
(
'MCU 连接已经断开'
);
this
.
stopTimerCounter
();
}
//如果还没开始或已经暂停、关闭,不做计时处理
if
(
GlobalConfig
.
classStatus
!=
ApeConsts
.
CLASS_STATUS_STARTED
)
{
loger
.
warn
(
'当前课堂已经暂停或者未开始,不计时'
,
"classStatus-->"
,
GlobalConfig
.
classStatus
);
return
;
}
GlobalConfig
.
classTimestamp
=
GlobalConfig
.
classTimestamp
+
1
;
//计时
//老师身份的时候要记录录制的时间
if
(
GlobalConfig
.
isHost
)
{
GlobalConfig
.
recordTimestamp
=
GlobalConfig
.
recordTimestamp
+
1
;
}
//loger.log('课堂进行时间',GlobalConfig.classTimestamp);
this
.
_emit
(
MessageTypes
.
CLASS_UPDATE_TIMER
,
{
"classTimestamp"
:
GlobalConfig
.
classTimestamp
});
if
(
GlobalConfig
.
classTimestamp
%
GlobalConfig
.
updateClassInfoDelay
==
0
)
{
//如果是host身份,需要同步时间给其他人,同时把当前的状态上传到服务器
if
(
GlobalConfig
.
isHost
)
{
//保存数据到Sass
this
.
_emit
(
MessageTypes
.
CLASS_STATUS_INFO_CHANGE
);
//同步消息给其他人
this
.
sendUpdaterClassStatusInfo
({
"actionType"
:
1
,
isStopAllPublishMedia
:
false
});
}
}
//停止计时器
stopTimerCounter
()
{
if
(
this
.
timerCounter
){
this
.
timerCounter
.
stopTimer
();
}
//进行MS动态选点,选择最快的MS服务器地址(录制回放不做处理)
if
(
!
GlobalConfig
.
isRecordPlayBack
&&
GlobalConfig
.
classTimestamp
%
GlobalConfig
.
msDynamicChooseIpDelay
==
0
)
{
this
.
_emit
(
MessageTypes
.
SWITCH_MS_IP
);
}
}
timerCounterUptate
()
{
if
(
!
this
.
mcu
.
connected
)
{
loger
.
warn
(
'MCU 连接已经断开'
);
this
.
stopTimerCounter
();
}
//如果还没开始或已经暂停、关闭,不做计时处理
if
(
GlobalConfig
.
classStatus
!=
ApeConsts
.
CLASS_STATUS_STARTED
)
{
loger
.
warn
(
'当前课堂已经暂停或者未开始,不计时'
,
"classStatus-->"
,
GlobalConfig
.
classStatus
);
return
;
}
GlobalConfig
.
classTimestamp
=
GlobalConfig
.
classTimestamp
+
1
;
//计时
//老师身份的时候要记录录制的时间
if
(
GlobalConfig
.
isHost
){
GlobalConfig
.
recordTimestamp
=
GlobalConfig
.
recordTimestamp
+
1
;
}
//loger.log('课堂进行时间',GlobalConfig.classTimestamp);
this
.
_emit
(
MessageTypes
.
CLASS_UPDATE_TIMER
,
{
"classTimestamp"
:
GlobalConfig
.
classTimestamp
});
if
(
GlobalConfig
.
classTimestamp
%
GlobalConfig
.
updateClassInfoDelay
==
0
)
{
//如果是host身份,需要同步时间给其他人,同时把当前的状态上传到服务器
if
(
GlobalConfig
.
isHost
)
{
//保存数据到Sass
this
.
_emit
(
MessageTypes
.
CLASS_STATUS_INFO_CHANGE
);
tableUpdateHandler
(
owner
,
itemIdx
,
itemData
)
{
try
{
let
model
=
this
.
unPackPdu
(
owner
,
itemIdx
,
itemData
);
loger
.
log
(
'课堂数据更新->'
,
model
);
//同步消息给其他人
this
.
sendUpdaterClassStatusInfo
({
"actionType"
:
1
,
isStopAllPublishMedia
:
false
});
}
}
//进行MS动态选点,选择最快的MS服务器地址(录制回放不做处理)
if
(
!
GlobalConfig
.
isRecordPlayBack
&&
GlobalConfig
.
classTimestamp
%
GlobalConfig
.
msDynamicChooseIpDelay
==
0
)
{
this
.
_emit
(
MessageTypes
.
SWITCH_MS_IP
);
}
}
//处理课堂更新的信息
if
(
model
&&
model
.
classStatusInfo
)
{
GlobalConfig
.
setClassStatusInfo
(
model
.
classStatusInfo
);
tableUpdateHandler
(
owner
,
itemIdx
,
itemData
)
{
try
{
let
model
=
this
.
unPackPdu
(
owner
,
itemIdx
,
itemData
);
loger
.
log
(
'课堂数据更新->'
,
model
);
//处理课堂更新的信息
if
(
model
&&
model
.
classStatusInfo
)
{
GlobalConfig
.
setClassStatusInfo
(
model
.
classStatusInfo
);
if
(
model
.
classStatusInfo
.
isStopAllPublishMedia
){
//课堂状态发送改变 需要对当前正在推的流进行停止,因为录制的问题;
this
.
_emit
(
MessageTypes
.
STOP_ALL_MEDIA_PUBLISH
);
}
}
//通知应用层更新课堂状态
let
classInfo
=
GlobalConfig
.
classStatusInfo
;
loger
.
log
(
'通知应用层更新课堂状态->CLASS_UPTATE_STATUS'
)
this
.
_emit
(
MessageTypes
.
CLASS_UPTATE_STATUS
,
classInfo
);
//如果MCU已经断开连接,停止计时器
if
(
!
this
.
mcu
.
connected
)
{
//停止计时
this
.
stopTimerCounter
();
return
;
}
if
(
GlobalConfig
.
classStatus
==
ApeConsts
.
CLASS_STATUS_STARTED
)
{
//如果课堂在进行中,开始计时器
this
.
startTimerCounter
();
}
else
{
//停止计时
this
.
stopTimerCounter
();
}
}
catch
(
err
)
{
loger
.
warn
(
'ConferApe table update got exception->err'
,
err
.
message
);
if
(
model
.
classStatusInfo
.
isStopAllPublishMedia
)
{
//课堂状态发送改变 需要对当前正在推的流进行停止,因为录制的问题;
this
.
_emit
(
MessageTypes
.
STOP_ALL_MEDIA_PUBLISH
);
}
}
}
conferMsgComingHandler
(
_data
)
{
//flash RCConferenceSendDataRequestPdu
//loger.warn('conferMsgComingHandler needs to be handled.');
//const recordInfo = pdu['RCWhiteboardDataRequestPdu'].decode(pdu);
//loger.log("conferMsgComingHandler",recordInfo);
let
chatReceivePdu
=
pdu
[
'RCConferenceSendDataRequestPdu'
].
decode
(
_data
);
let
chatMsg
=
{};
chatMsg
.
fromNodeID
=
chatReceivePdu
.
initiator
;
chatMsg
.
toNodeID
=
chatReceivePdu
.
peer
;
chatMsg
.
message
=
this
.
_rCArrayBufferUtil
.
uint8ArrayToStr
(
chatReceivePdu
.
userData
,
2
);
chatMsg
.
actionType
=
chatReceivePdu
.
actionType
;
loger
.
log
(
"conferMsgComingHandler"
,
chatMsg
);
//{"fromNodeID":418883112,"toNodeID":0,"message":"所有人退出课堂","actionType":1}
switch
(
chatMsg
.
actionType
)
{
case
ApeConsts
.
CLASS_ACTION_CLOSE_ALL
:
loger
.
log
(
chatMsg
.
message
);
//收到课堂关闭,所有人都退出,执行自己关闭的流程
this
.
_emit
(
MessageTypes
.
CLASS_RUN_EXIT
,{
'type'
:
1
});
break
;
case
ApeConsts
.
CLASS_ACTION_HANDUP_STATUS_CHANGE
:
console
.
log
(
'chatMsg'
,
chatMsg
);
let
msgObj
=
null
;
try
{
msgObj
=
JSON
.
parse
(
chatMsg
.
message
);
if
(
msgObj
&&
msgObj
.
nodeId
==
GlobalConfig
.
nodeId
){
this
.
changeHandUpStatus
(
msgObj
);
}
}
catch
(
err
){
loger
.
warn
(
'chatMsg->JSON数据解析失败'
);
}
break
;
default
:
break
;
}
}
//通知应用层更新课堂状态
let
classInfo
=
GlobalConfig
.
classStatusInfo
;
loger
.
log
(
'通知应用层更新课堂状态->CLASS_UPTATE_STATUS'
)
this
.
_emit
(
MessageTypes
.
CLASS_UPTATE_STATUS
,
classInfo
);
//-------------第三方消息------------------------------
//收到父级页面的消息,需要广播发送出去
onThirdReciveParentMessage
(
_msg
){
loger
.
log
(
'收到页面的消息->广播给其他模块->'
,
_msg
);
this
.
sendThirdBroadcastData
({
to
:
0
,
message
:
_msg
});
//如果MCU已经断开连接,停止计时器
if
(
!
this
.
mcu
.
connected
)
{
//停止计时
this
.
stopTimerCounter
();
return
;
}
if
(
GlobalConfig
.
classStatus
==
ApeConsts
.
CLASS_STATUS_STARTED
)
{
//如果课堂在进行中,开始计时器
this
.
startTimerCounter
();
}
else
{
//停止计时
this
.
stopTimerCounter
();
}
}
catch
(
err
)
{
loger
.
warn
(
'ConferApe table update got exception->err'
,
err
.
message
);
}
}
conferMsgComingHandler
(
_data
)
{
//flash RCConferenceSendDataRequestPdu
//loger.warn('conferMsgComingHandler needs to be handled.');
//const recordInfo = pdu['RCWhiteboardDataRequestPdu'].decode(pdu);
//loger.log("conferMsgComingHandler",recordInfo);
let
chatReceivePdu
=
pdu
[
'RCConferenceSendDataRequestPdu'
].
decode
(
_data
);
let
chatMsg
=
{};
chatMsg
.
fromNodeID
=
chatReceivePdu
.
initiator
;
chatMsg
.
toNodeID
=
chatReceivePdu
.
peer
;
chatMsg
.
message
=
this
.
_rCArrayBufferUtil
.
uint8ArrayToStr
(
chatReceivePdu
.
userData
,
2
);
chatMsg
.
actionType
=
chatReceivePdu
.
actionType
;
loger
.
log
(
"conferMsgComingHandler"
,
chatMsg
);
//{"fromNodeID":418883112,"toNodeID":0,"message":"所有人退出课堂","actionType":1}
switch
(
chatMsg
.
actionType
)
{
case
ApeConsts
.
CLASS_ACTION_CLOSE_ALL
:
loger
.
log
(
chatMsg
.
message
);
//收到课堂关闭,所有人都退出,执行自己关闭的流程
this
.
_emit
(
MessageTypes
.
CLASS_RUN_EXIT
,
{
'type'
:
1
});
break
;
case
ApeConsts
.
CLASS_ACTION_HANDUP_STATUS_CHANGE
:
console
.
log
(
'chatMsg'
,
chatMsg
);
let
msgObj
=
null
;
try
{
msgObj
=
JSON
.
parse
(
chatMsg
.
message
);
if
(
msgObj
&&
msgObj
.
nodeId
==
GlobalConfig
.
nodeId
)
{
this
.
changeHandUpStatus
(
msgObj
);
}
}
catch
(
err
)
{
loger
.
warn
(
'chatMsg->JSON数据解析失败'
);
}
break
;
case
ApeConsts
.
USER_ACTION_SILENCE_STATUS_CHANGE
:
let
msgObj
=
null
;
try
{
msgObj
=
JSON
.
parse
(
chatMsg
.
message
);
if
(
msgObj
&&
msgObj
.
nodeId
==
GlobalConfig
.
nodeId
)
{
this
.
changeSilenceStatus
(
msgObj
);
}
}
catch
(
err
)
{
loger
.
warn
(
'chatMsg->JSON数据解析失败'
);
}
break
;
default
:
break
;
}
}
//-------------第三方消息------------------------------
//收到父级页面的消息,需要广播发送出去
onThirdReciveParentMessage
(
_msg
)
{
loger
.
log
(
'收到页面的消息->广播给其他模块->'
,
_msg
);
this
.
sendThirdBroadcastData
({
to
:
0
,
message
:
_msg
});
}
//发送第三方广播消息
sendThirdBroadcastData
(
_param
){
loger
.
log
(
"发送第三方广播消息->"
,
_param
);
if
(
this
.
_classInfo
==
null
||
EngineUtils
.
isEmptyObject
(
this
.
_classInfo
))
{
loger
.
log
(
'发送第三方广播消息->失败->SDK还未初始化数据!'
);
if
(
GlobalConfig
.
getCurrentStatus
().
code
==
0
||
GlobalConfig
.
getCurrentStatus
().
code
==
1
)
{
this
.
_emit
(
MessageTypes
.
MCU_ERROR
,
MessageTypes
.
ERR_APE_SEND_FAILED_NO_JOIN
);
return
;
}
return
;
}
let
thirdBroadcastSendPdu
=
new
pdu
[
'RCThirdSendBroadcastDataRequestPdu'
];
thirdBroadcastSendPdu
.
type
=
pdu
.
RCPDU_THIRD_BROADCAST_DATA_REQUEST
;
thirdBroadcastSendPdu
.
initiator
=
this
.
_classInfo
.
nodeId
;
//发起人
thirdBroadcastSendPdu
.
peer
=
parseInt
(
_param
.
to
)
||
0
;
//发送给谁,公聊的时候是0,私聊的时候是指定的用户id
thirdBroadcastSendPdu
.
isPublic
=
true
;
thirdBroadcastSendPdu
.
message
=
this
.
_rCArrayBufferUtil
.
strToUint8Array
(
"h5"
+
_param
.
message
);
if
(
!
thirdBroadcastSendPdu
.
isPublic
&&
0
!=
thirdBroadcastSendPdu
.
peer
)
{
//发送给制定的人
this
.
send
(
thirdBroadcastSendPdu
);
}
else
{
//发送给所有人
this
.
sendChatUniform
(
thirdBroadcastSendPdu
);
}
}
//监听第三方消息通道消息
onThirdBroadcastDataHandler
(
_data
){
//loger.log("监听第三方消息通道消息->",_data);
let
thirdBroadcastReceivePdu
=
pdu
[
'RCThirdSendBroadcastDataRequestPdu'
].
decode
(
_data
);
let
thirdMessage
=
{};
thirdMessage
.
fromNodeID
=
thirdBroadcastReceivePdu
.
initiator
;
thirdMessage
.
toNodeID
=
thirdBroadcastReceivePdu
.
peer
;
//loger.log("监听第三方消息通道消息->1", thirdMessage);
thirdMessage
.
message
=
this
.
_rCArrayBufferUtil
.
uint8ArrayToStr
(
thirdBroadcastReceivePdu
.
message
,
2
);
loger
.
log
(
"监听第三方消息通道消息->"
,
thirdMessage
);
if
(
this
.
thirdMessage
){
this
.
thirdMessage
.
sendMessageToParent
(
thirdMessage
.
message
);
}
}
//------------------第三方消息 end-----------------------------------------
onSendConferRecordRequestHandler
(
_data
)
{
try
{
let
conferRecordSendPdu
=
pdu
[
'RCConferenceRecordRequestPdu'
].
decode
(
_data
);
// {"initiator":820461225,"record":false,"classTime":3213,"filename":"h5dev/20170410/1437784290_20170410.rec"}
loger
.
log
(
"录制回放控制操作成功->"
,
conferRecordSendPdu
);
if
(
conferRecordSendPdu
&&
conferRecordSendPdu
.
record
==
true
||
conferRecordSendPdu
.
record
==
"true"
){
//每次开启录制的时候,需要把当前显示的文档数据更新一次,否则无法录制已经显示的文件
this
.
_emit
(
MessageTypes
.
CLASS_RECORD_SUCCESS
);
}
}
catch
(
err
)
{
loger
.
warn
(
"录制回放控制操作错误->"
,
err
.
message
);
}
}
rosterInsertHandler
(
nodeId
,
nodeData
)
{
//loger.log("人员进入--->");
if
(
GlobalConfig
.
nodeId
==
nodeId
)
{
}
else
{
// loger.log("有人加入 rosterInsertHandler");
this
.
rosterUpdateHandler
(
nodeId
,
nodeData
);
sendThirdBroadcastData
(
_param
)
{
loger
.
log
(
"发送第三方广播消息->"
,
_param
);
if
(
this
.
_classInfo
==
null
||
EngineUtils
.
isEmptyObject
(
this
.
_classInfo
))
{
loger
.
log
(
'发送第三方广播消息->失败->SDK还未初始化数据!'
);
if
(
GlobalConfig
.
getCurrentStatus
().
code
==
0
||
GlobalConfig
.
getCurrentStatus
().
code
==
1
)
{
this
.
_emit
(
MessageTypes
.
MCU_ERROR
,
MessageTypes
.
ERR_APE_SEND_FAILED_NO_JOIN
);
return
;
}
return
;
}
let
thirdBroadcastSendPdu
=
new
pdu
[
'RCThirdSendBroadcastDataRequestPdu'
];
thirdBroadcastSendPdu
.
type
=
pdu
.
RCPDU_THIRD_BROADCAST_DATA_REQUEST
;
thirdBroadcastSendPdu
.
initiator
=
this
.
_classInfo
.
nodeId
;
//发起人
thirdBroadcastSendPdu
.
peer
=
parseInt
(
_param
.
to
)
||
0
;
//发送给谁,公聊的时候是0,私聊的时候是指定的用户id
thirdBroadcastSendPdu
.
isPublic
=
true
;
thirdBroadcastSendPdu
.
message
=
this
.
_rCArrayBufferUtil
.
strToUint8Array
(
"h5"
+
_param
.
message
);
if
(
!
thirdBroadcastSendPdu
.
isPublic
&&
0
!=
thirdBroadcastSendPdu
.
peer
)
{
//发送给制定的人
this
.
send
(
thirdBroadcastSendPdu
);
}
else
{
//发送给所有人
this
.
sendChatUniform
(
thirdBroadcastSendPdu
);
}
}
//监听第三方消息通道消息
onThirdBroadcastDataHandler
(
_data
)
{
//loger.log("监听第三方消息通道消息->",_data);
let
thirdBroadcastReceivePdu
=
pdu
[
'RCThirdSendBroadcastDataRequestPdu'
].
decode
(
_data
);
let
thirdMessage
=
{};
thirdMessage
.
fromNodeID
=
thirdBroadcastReceivePdu
.
initiator
;
thirdMessage
.
toNodeID
=
thirdBroadcastReceivePdu
.
peer
;
//loger.log("监听第三方消息通道消息->1", thirdMessage);
thirdMessage
.
message
=
this
.
_rCArrayBufferUtil
.
uint8ArrayToStr
(
thirdBroadcastReceivePdu
.
message
,
2
);
loger
.
log
(
"监听第三方消息通道消息->"
,
thirdMessage
);
if
(
this
.
thirdMessage
)
{
this
.
thirdMessage
.
sendMessageToParent
(
thirdMessage
.
message
);
}
}
//------------------第三方消息 end-----------------------------------------
onSendConferRecordRequestHandler
(
_data
)
{
try
{
let
conferRecordSendPdu
=
pdu
[
'RCConferenceRecordRequestPdu'
].
decode
(
_data
);
// {"initiator":820461225,"record":false,"classTime":3213,"filename":"h5dev/20170410/1437784290_20170410.rec"}
loger
.
log
(
"录制回放控制操作成功->"
,
conferRecordSendPdu
);
if
(
conferRecordSendPdu
&&
conferRecordSendPdu
.
record
==
true
||
conferRecordSendPdu
.
record
==
"true"
)
{
//每次开启录制的时候,需要把当前显示的文档数据更新一次,否则无法录制已经显示的文件
this
.
_emit
(
MessageTypes
.
CLASS_RECORD_SUCCESS
);
}
}
catch
(
err
)
{
loger
.
warn
(
"录制回放控制操作错误->"
,
err
.
message
);
}
}
rosterInsertHandler
(
nodeId
,
nodeData
)
{
//loger.log("人员进入--->");
if
(
GlobalConfig
.
nodeId
==
nodeId
)
{
}
else
{
// loger.log("有人加入 rosterInsertHandler");
this
.
rosterUpdateHandler
(
nodeId
,
nodeData
);
}
}
//更新人员列表数据
rosterUpdateHandler
(
nodeId
,
nodeData
)
{
nodeData
.
userRole
=
ApeConsts
.
userTypes
[
nodeData
.
role
];
//如果是自己的信息,不处理跳过
if
(
nodeId
==
GlobalConfig
.
nodeId
)
{
//loger.log("自己加入课堂的消息->",nodeId,"role-->", nodeData.role, ApeConsts.userTypes[nodeData.role]);
//自己加入的时候,需要做一下判断操作,如果满足以下3个条件就要暂停课堂:
// 1.当前课堂只有自己;2.自己的身份不是host;3当前的课堂状态为(CLASS_STATUS_STARTED= 1;//直播中)
let
rosterLen
=
Object
.
keys
(
this
.
rosters
).
length
;
if
(
rosterLen
<
1
&&
!
GlobalConfig
.
isHost
&&
GlobalConfig
.
classStatus
==
ApeConsts
.
CLASS_STATUS_STARTED
)
{
loger
.
warn
(
"当前课堂没有老师->暂停课堂"
);
this
.
pauseClass
({
isForce
:
true
});
this
.
stopRecord
(
true
);
}
}
//更新人员列表数据
rosterUpdateHandler
(
nodeId
,
nodeData
)
{
nodeData
.
userRole
=
ApeConsts
.
userTypes
[
nodeData
.
role
];
//如果是自己的信息,不处理跳过
if
(
nodeId
==
GlobalConfig
.
nodeId
)
{
//loger.log("自己加入课堂的消息->",nodeId,"role-->", nodeData.role, ApeConsts.userTypes[nodeData.role]);
//自己加入的时候,需要做一下判断操作,如果满足以下3个条件就要暂停课堂:
// 1.当前课堂只有自己;2.自己的身份不是host;3当前的课堂状态为(CLASS_STATUS_STARTED= 1;//直播中)
let
rosterLen
=
Object
.
keys
(
this
.
rosters
).
length
;
if
(
rosterLen
<
1
&&!
GlobalConfig
.
isHost
&&
GlobalConfig
.
classStatus
==
ApeConsts
.
CLASS_STATUS_STARTED
){
loger
.
warn
(
"当前课堂没有老师->暂停课堂"
);
this
.
pauseClass
({
isForce
:
true
});
this
.
stopRecord
(
true
);
}
//处理用户信息
this
.
unPackRosterInfo
(
nodeId
,
nodeData
);
return
;
}
//loger.log(nodeId, "加入课堂,role-->", nodeData.role, ApeConsts.userTypes[nodeData.role]);
//新加入的人员不是自己
//1.判断进入的用户身份,如果进入的人身份是host,助教,监课,并且和自己的身份冲突,自己会被踢掉
//2.最后进入的人会踢掉之前进入的人,nodeId是按时间戳生成的,最后进入的人nodeId的值比之前进入的人大
if
(
parseInt
(
nodeId
)
>
GlobalConfig
.
nodeId
)
{
if
(
nodeData
.
role
==
ApeConsts
.
NR_HOST
&&
GlobalConfig
.
isHost
)
{
this
.
kickOutRoster
();
return
;
}
else
if
(
nodeData
.
userId
==
GlobalConfig
.
userId
&&
GlobalConfig
.
userId
!=
"0"
){
loger
.
log
(
"异地登陆->userId->"
,
GlobalConfig
.
userId
);
this
.
_emit
(
MessageTypes
.
MCU_ERROR
,
MessageTypes
.
ERR_CLASS_REMOTE_LANDING
);
this
.
_emit
(
MessageTypes
.
CLASS_RUN_EXIT
,{
'type'
:
1
});
}
}
/*if (parseInt(nodeId) > GlobalConfig.nodeId) {
if (nodeData.role == ApeConsts.NR_HOST && GlobalConfig.isHost) {
this.kickOutRoster();
return;
} else if (nodeData.role == ApeConsts.NR_PRESENTER && GlobalConfig.isPresenter) {
this.kickOutRoster();
return;
} else if (nodeData.role == ApeConsts.NR_ASSISTANT && GlobalConfig.isAssistant) {
this.kickOutRoster();
return;
} else if (nodeData.role == ApeConsts.NR_INVISIBLE && GlobalConfig.isInvisible) {
this.kickOutRoster();
return;
}else if(nodeData.userId==GlobalConfig.userId&&GlobalConfig.userId!="0"){
loger.log("异地登陆->userId->",GlobalConfig.userId);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_REMOTE_LANDING);
this._emit(MessageTypes.CLASS_RUN_EXIT,{'type':1});
}
}*/
//处理用户信息
this
.
unPackRosterInfo
(
nodeId
,
nodeData
);
this
.
unPackRosterInfo
(
nodeId
,
nodeData
);
return
;
}
//loger.log(nodeId, "加入课堂,role-->", nodeData.role, ApeConsts.userTypes[nodeData.role]);
//新加入的人员不是自己
//1.判断进入的用户身份,如果进入的人身份是host,助教,监课,并且和自己的身份冲突,自己会被踢掉
//2.最后进入的人会踢掉之前进入的人,nodeId是按时间戳生成的,最后进入的人nodeId的值比之前进入的人大
if
(
parseInt
(
nodeId
)
>
GlobalConfig
.
nodeId
)
{
if
(
nodeData
.
role
==
ApeConsts
.
NR_HOST
&&
GlobalConfig
.
isHost
)
{
this
.
kickOutRoster
();
return
;
}
else
if
(
nodeData
.
userId
==
GlobalConfig
.
userId
&&
GlobalConfig
.
userId
!=
"0"
)
{
loger
.
log
(
"异地登陆->userId->"
,
GlobalConfig
.
userId
);
this
.
_emit
(
MessageTypes
.
MCU_ERROR
,
MessageTypes
.
ERR_CLASS_REMOTE_LANDING
);
this
.
_emit
(
MessageTypes
.
CLASS_RUN_EXIT
,
{
'type'
:
1
});
}
}
/*if (parseInt(nodeId) > GlobalConfig.nodeId) {
if (nodeData.role == ApeConsts.NR_HOST && GlobalConfig.isHost) {
this.kickOutRoster();
return;
} else if (nodeData.role == ApeConsts.NR_PRESENTER && GlobalConfig.isPresenter) {
this.kickOutRoster();
return;
} else if (nodeData.role == ApeConsts.NR_ASSISTANT && GlobalConfig.isAssistant) {
this.kickOutRoster();
return;
} else if (nodeData.role == ApeConsts.NR_INVISIBLE && GlobalConfig.isInvisible) {
this.kickOutRoster();
return;
}else if(nodeData.userId==GlobalConfig.userId&&GlobalConfig.userId!="0"){
loger.log("异地登陆->userId->",GlobalConfig.userId);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_REMOTE_LANDING);
this._emit(MessageTypes.CLASS_RUN_EXIT,{'type':1});
}
}*/
//处理用户信息
this
.
unPackRosterInfo
(
nodeId
,
nodeData
);
}
//处理用户信息
unPackRosterInfo
(
nodeId
,
nodeData
){
let
rosterExists
=
this
.
rosters
[
nodeId
];
this
.
rosters
[
nodeId
]
=
nodeData
;
let
userDataObj
=
null
;
try
{
userDataObj
=
pdu
[
'RCNodeInfoUserDataPdu'
].
decode
(
nodeData
.
userData
);
}
catch
(
err
)
{
loger
.
log
(
"RCNodeInfoUserDataPdu decode err"
,
err
.
message
);
}
let
newNodeData
=
nodeData
;
newNodeData
.
userData
=
userDataObj
;
//如果是监课,不告诉其他人
if
(
nodeData
.
role
==
ApeConsts
.
NR_INVISIBLE
&&
GlobalConfig
.
userRole
!=
ApeConsts
.
invisible
)
{
loger
.
log
(
"NR_INVISIBLE"
);
return
;
}
if
(
!
rosterExists
)
{
loger
.
log
(
"人员加入->"
,
newNodeData
);
this
.
_emit
(
MessageTypes
.
CLASS_INSERT_ROSTER
,
{
"nodeId"
:
nodeId
,
"nodeData"
:
newNodeData
});
this
.
emitRosterChange
();
}
else
{
//loger.log("更新人员列表数据,rosterExists已经存在",rosterExists);
loger
.
log
(
"人员更新信息->"
,
newNodeData
);
this
.
_emit
(
MessageTypes
.
CLASS_UPDATE_ROSTER
,
{
"nodeId"
:
nodeId
,
"nodeData"
:
newNodeData
});
}
}
//踢出用户
kickOutRoster
()
{
this
.
_emit
(
MessageTypes
.
MCU_ERROR
,
MessageTypes
.
ERR_CLASS_KICK_OUT
);
this
.
_emit
(
MessageTypes
.
CLASS_RUN_EXIT
,{
'type'
:
1
});
}
//视频模块发生更新,人员状态需要更新
updaterRosterStatus
(
_param
)
{
//loger.log("媒体模块发生更新,人员状态需要更新,fromNodeId->",_param);
//如果视频消息中channel的占用人 fromNodeId在人员列表中不存在,需要释放这channel,因为这个有可能是之前没释放成功的
if
(
_param
&&
_param
.
status
==
ApeConsts
.
CHANNEL_STATUS_OPENING
&&
this
.
rosters
[
_param
.
fromNodeId
]
==
null
)
{
loger
.
log
(
"媒体模块被占用->占有人已经不存在课堂中->释放->"
,
_param
);
this
.
_emit
(
MessageTypes
.
CLASS_NONENTITY_ROSTER
,
{
"nodeId"
:
_param
.
fromNodeId
});
}
/* if (_param && _param.status == ApeConsts.CHANNEL_STATUS_OPENING) {
if(this.rosters[_param.fromNodeId] == null){
loger.log("媒体模块被占用,占有人已经不存在课堂中,释放Channel,_param->", _param);
this._emit(MessageTypes.CLASS_NONENTITY_ROSTER, {"nodeId": _param.fromNodeId});
}
//如果音视频消息是自己的,需要设置麦克风和摄像头状态
if(_param.fromNodeId==GlobalConfig.nodeId){
if(_param.mediaId==ApeConsts.MEDIA_TYPE_AUDIO){
GlobalConfig.openMicrophones=EngineUtils.creatTimestamp();
GlobalConfig.openCamera=0;
}else {
GlobalConfig.openCamera=EngineUtils.creatTimestamp();
GlobalConfig.openMicrophones=GlobalConfig.openCamera;
}
this.updateUserInfo();
}
}else if (_param && _param.status == ApeConsts.CHANNEL_STATUS_RELEASED) {
//如果音视频消息是自己的,需要设置麦克风和摄像头状态
if(_param.fromNodeId==GlobalConfig.nodeId){
GlobalConfig.openCamera=0;
GlobalConfig.openMicrophones=0;
this.updateUserInfo();
}
}*/
unPackRosterInfo
(
nodeId
,
nodeData
)
{
let
rosterExists
=
this
.
rosters
[
nodeId
];
this
.
rosters
[
nodeId
]
=
nodeData
;
let
userDataObj
=
null
;
try
{
userDataObj
=
pdu
[
'RCNodeInfoUserDataPdu'
].
decode
(
nodeData
.
userData
);
}
catch
(
err
)
{
loger
.
log
(
"RCNodeInfoUserDataPdu decode err"
,
err
.
message
);
}
let
newNodeData
=
nodeData
;
newNodeData
.
userData
=
userDataObj
;
//如果是监课,不告诉其他人
if
(
nodeData
.
role
==
ApeConsts
.
NR_INVISIBLE
&&
GlobalConfig
.
userRole
!=
ApeConsts
.
invisible
)
{
loger
.
log
(
"NR_INVISIBLE"
);
return
;
}
if
(
!
rosterExists
)
{
loger
.
log
(
"人员加入->"
,
newNodeData
);
this
.
_emit
(
MessageTypes
.
CLASS_INSERT_ROSTER
,
{
"nodeId"
:
nodeId
,
"nodeData"
:
newNodeData
});
this
.
emitRosterChange
();
}
else
{
//loger.log("更新人员列表数据,rosterExists已经存在",rosterExists);
loger
.
log
(
"人员更新信息->"
,
newNodeData
);
this
.
_emit
(
MessageTypes
.
CLASS_UPDATE_ROSTER
,
{
"nodeId"
:
nodeId
,
"nodeData"
:
newNodeData
});
}
}
//踢出用户
kickOutRoster
()
{
this
.
_emit
(
MessageTypes
.
MCU_ERROR
,
MessageTypes
.
ERR_CLASS_KICK_OUT
);
this
.
_emit
(
MessageTypes
.
CLASS_RUN_EXIT
,
{
'type'
:
1
});
}
//视频模块发生更新,人员状态需要更新
updaterRosterStatus
(
_param
)
{
//loger.log("媒体模块发生更新,人员状态需要更新,fromNodeId->",_param);
//如果视频消息中channel的占用人 fromNodeId在人员列表中不存在,需要释放这channel,因为这个有可能是之前没释放成功的
if
(
_param
&&
_param
.
status
==
ApeConsts
.
CHANNEL_STATUS_OPENING
&&
this
.
rosters
[
_param
.
fromNodeId
]
==
null
)
{
loger
.
log
(
"媒体模块被占用->占有人已经不存在课堂中->释放->"
,
_param
);
this
.
_emit
(
MessageTypes
.
CLASS_NONENTITY_ROSTER
,
{
"nodeId"
:
_param
.
fromNodeId
});
}
/* if (_param && _param.status == ApeConsts.CHANNEL_STATUS_OPENING) {
if(this.rosters[_param.fromNodeId] == null){
loger.log("媒体模块被占用,占有人已经不存在课堂中,释放Channel,_param->", _param);
this._emit(MessageTypes.CLASS_NONENTITY_ROSTER, {"nodeId": _param.fromNodeId});
}
//如果音视频消息是自己的,需要设置麦克风和摄像头状态
if(_param.fromNodeId==GlobalConfig.nodeId){
if(_param.mediaId==ApeConsts.MEDIA_TYPE_AUDIO){
GlobalConfig.openMicrophones=EngineUtils.creatTimestamp();
GlobalConfig.openCamera=0;
}else {
GlobalConfig.openCamera=EngineUtils.creatTimestamp();
GlobalConfig.openMicrophones=GlobalConfig.openCamera;
}
this.updateUserInfo();
}
}else if (_param && _param.status == ApeConsts.CHANNEL_STATUS_RELEASED) {
//如果音视频消息是自己的,需要设置麦克风和摄像头状态
if(_param.fromNodeId==GlobalConfig.nodeId){
GlobalConfig.openCamera=0;
GlobalConfig.openMicrophones=0;
this.updateUserInfo();
}
}*/
}
//设备状态更新
updaterUserDeviecStatusChange
(
_data
){
loger
.
log
(
"音视频设备状态更新->"
,
_data
);
this
.
updateUserInfo
();
}
//删除用户
rosterDelHandler
(
nodeId
)
{
if
(
GlobalConfig
.
nodeId
==
nodeId
)
{
loger
.
log
(
"自己离开课堂"
);
// 自己退出
this
.
_emit
(
MessageTypes
.
CLASS_RUN_EXIT
,{
'type'
:
0
});
updaterUserDeviecStatusChange
(
_data
)
{
loger
.
log
(
"音视频设备状态更新->"
,
_data
);
this
.
updateUserInfo
();
}
//删除用户
rosterDelHandler
(
nodeId
)
{
if
(
GlobalConfig
.
nodeId
==
nodeId
)
{
loger
.
log
(
"自己离开课堂"
);
// 自己退出
this
.
_emit
(
MessageTypes
.
CLASS_RUN_EXIT
,
{
'type'
:
0
});
}
else
{
let
user
=
this
.
rosters
[
nodeId
];
if
(
user
)
{
loger
.
log
(
nodeId
,
"->离开课堂->身份->"
,
user
.
role
);
}
delete
this
.
rosters
[
nodeId
];
this
.
emitRosterChange
();
this
.
_emit
(
MessageTypes
.
CLASS_DELETE_ROSTER
,
{
"nodeId"
:
nodeId
});
//当前人员列表中抽一个人来检查离开人员是否占用频道
for
(
let
key
in
this
.
rosters
)
{
let
randNodeId
=
parseInt
(
key
);
//如果抽到的人是自己就处理以下操作
if
(
randNodeId
==
GlobalConfig
.
nodeId
)
{
loger
.
log
(
randNodeId
,
"有权限检查离开的人员是否占用channel"
);
this
.
_emit
(
MessageTypes
.
CLASS_NONENTITY_ROSTER
,
{
"nodeId"
:
nodeId
});
//如果离开的人员是老师,需要暂停当前的课堂
if
(
user
&&
user
.
role
==
ApeConsts
.
NR_HOST
)
{
this
.
pauseClass
();
//强制停止录制
this
.
stopRecord
(
true
);
}
}
else
{
let
user
=
this
.
rosters
[
nodeId
];
if
(
user
){
loger
.
log
(
nodeId
,
"->离开课堂->身份->"
,
user
.
role
);
}
delete
this
.
rosters
[
nodeId
];
this
.
emitRosterChange
();
this
.
_emit
(
MessageTypes
.
CLASS_DELETE_ROSTER
,
{
"nodeId"
:
nodeId
});
//当前人员列表中抽一个人来检查离开人员是否占用频道
for
(
let
key
in
this
.
rosters
)
{
let
randNodeId
=
parseInt
(
key
);
//如果抽到的人是自己就处理以下操作
if
(
randNodeId
==
GlobalConfig
.
nodeId
)
{
loger
.
log
(
randNodeId
,
"有权限检查离开的人员是否占用channel"
);
this
.
_emit
(
MessageTypes
.
CLASS_NONENTITY_ROSTER
,
{
"nodeId"
:
nodeId
});
//如果离开的人员是老师,需要暂停当前的课堂
if
(
user
&&
user
.
role
==
ApeConsts
.
NR_HOST
){
this
.
pauseClass
();
//强制停止录制
this
.
stopRecord
(
true
);
}
}
else
{
loger
.
warn
(
GlobalConfig
.
nodeId
,
"没有权限检查离开的人员是否占用channel"
);
}
//查找到一个就跳出操作
return
;
}
}
}
//广播当前的人数
emitRosterChange
()
{
this
.
_emit
(
MessageTypes
.
CLASS_UPDATE_ROSTER_NUM
,
Object
.
keys
(
this
.
rosters
).
length
);
}
///////数据的封包和解包/////////////////////////////////////////
packPdu
(
_param
,
_itemIdx
)
{
loger
.
log
(
"课堂===packPdu "
);
//验证坐标点集合数组是否合法
if
(
_param
==
null
||
_itemIdx
==
null
)
{
this
.
_emit
(
MessageTypes
.
MCU_ERROR
,
MessageTypes
.
ERR_APE_INTERFACE_PARAM_WRONG
);
return
null
;
}
let
classStatusInfo
=
new
pdu
[
'RCClassStatusInfoPdu'
];
classStatusInfo
.
nodeId
=
GlobalConfig
.
nodeId
;
//mcu中的唯一ID
classStatusInfo
.
userId
=
GlobalConfig
.
userId
;
classStatusInfo
.
userName
=
GlobalConfig
.
userName
;
classStatusInfo
.
siteId
=
GlobalConfig
.
siteId
;
//站点号
classStatusInfo
.
classId
=
GlobalConfig
.
classId
;
classStatusInfo
.
className
=
GlobalConfig
.
className
;
classStatusInfo
.
classType
=
GlobalConfig
.
classType
;
//课堂类型
classStatusInfo
.
classStatus
=
GlobalConfig
.
classStatus
;
//课堂的状态
classStatusInfo
.
classStartTime
=
GlobalConfig
.
classStartTime
;
//课堂点击开始时间
classStatusInfo
.
classStopTime
=
GlobalConfig
.
classStopTime
;
//最后一次停止的时间(点暂停或结束),每次发送数据都获取当前时间戳
classStatusInfo
.
classTimestamp
=
GlobalConfig
.
classTimestamp
;
//相对于点开始课堂的时间戳
classStatusInfo
.
classBeginTime
=
GlobalConfig
.
classBeginTime
;
//课堂创建的时间,这个是Sass返回的
classStatusInfo
.
classEndTime
=
GlobalConfig
.
classEndTime
;
//课堂结束的时间,这个是Sass返回的
classStatusInfo
.
recordStatus
=
GlobalConfig
.
recordStatus
;
//当前录制状态
classStatusInfo
.
recordTimestamp
=
GlobalConfig
.
recordTimestamp
;
//相对于首次开始录制的时间戳
classStatusInfo
.
recordFileName
=
GlobalConfig
.
recordFileName
;
//录制的文件名
classStatusInfo
.
recordDownloadUrl
=
GlobalConfig
.
recordDownloadUrl
;
//下载地址
classStatusInfo
.
serverTimestamp
=
GlobalConfig
.
serverTimestamp
;
//当前的系统时间戳
classStatusInfo
.
activeDocId
=
GlobalConfig
.
activeDocId
;
//当前激活的文档id
classStatusInfo
.
activeDocCurPage
=
GlobalConfig
.
activeDocCurPage
;
//当前激活的文档的当前页
classStatusInfo
.
isStopAllPublishMedia
=
_param
.
isStopAllPublishMedia
||
false
;
classStatusInfo
.
currentSceneTableId
=
GlobalConfig
.
currentSceneTableId
;
//loger.log("classStatusInfo--->", classStatusInfo);
/*
optional uint32 item_idx=1;
optional uint32 from=2;
optional uint32 owner=3;
optional uint32 action_type=4;//状态改变的类型
optional RCClassStatusInfoPdu class_status_info=5;//当前课堂状态的信息
*/
//判断type类型,根据type设置不同的参数
let
modelPdu
=
new
pdu
[
'RCClassSendDataModelPdu'
];
modelPdu
.
itemIdx
=
_itemIdx
;
modelPdu
.
from
=
GlobalConfig
.
nodeId
;
modelPdu
.
owner
=
GlobalConfig
.
nodeId
;
//modelPdu.actionType =_param.actionType;
modelPdu
.
classStatusInfo
=
classStatusInfo
;
return
modelPdu
;
}
unPackPdu
(
owner
,
itemIdx
,
itemData
)
{
loger
.
log
(
"课堂数据->unPackPdu "
);
if
(
owner
==
null
||
itemIdx
==
null
||
itemData
==
null
)
{
this
.
_emit
(
MessageTypes
.
MCU_ERROR
,
MessageTypes
.
ERR_APE_INTERFACE_PARAM_WRONG
);
return
null
;
}
try
{
let
modelPdu
=
pdu
[
'RCClassSendDataModelPdu'
].
decode
(
itemData
);
return
modelPdu
;
}
catch
(
err
)
{
loger
.
log
(
"课堂收到数据 unPackPdu Pdu解析错误,itemIdx="
+
itemIdx
+
" err:"
+
err
.
message
);
}
return
null
;
}
loger
.
warn
(
GlobalConfig
.
nodeId
,
"没有权限检查离开的人员是否占用channel"
);
}
//查找到一个就跳出操作
return
;
}
}
}
//广播当前的人数
emitRosterChange
()
{
this
.
_emit
(
MessageTypes
.
CLASS_UPDATE_ROSTER_NUM
,
Object
.
keys
(
this
.
rosters
).
length
);
}
///////数据的封包和解包/////////////////////////////////////////
packPdu
(
_param
,
_itemIdx
)
{
loger
.
log
(
"课堂===packPdu "
);
//验证坐标点集合数组是否合法
if
(
_param
==
null
||
_itemIdx
==
null
)
{
this
.
_emit
(
MessageTypes
.
MCU_ERROR
,
MessageTypes
.
ERR_APE_INTERFACE_PARAM_WRONG
);
return
null
;
}
let
classStatusInfo
=
new
pdu
[
'RCClassStatusInfoPdu'
];
classStatusInfo
.
nodeId
=
GlobalConfig
.
nodeId
;
//mcu中的唯一ID
classStatusInfo
.
userId
=
GlobalConfig
.
userId
;
classStatusInfo
.
userName
=
GlobalConfig
.
userName
;
classStatusInfo
.
siteId
=
GlobalConfig
.
siteId
;
//站点号
classStatusInfo
.
classId
=
GlobalConfig
.
classId
;
classStatusInfo
.
className
=
GlobalConfig
.
className
;
classStatusInfo
.
classType
=
GlobalConfig
.
classType
;
//课堂类型
classStatusInfo
.
classStatus
=
GlobalConfig
.
classStatus
;
//课堂的状态
classStatusInfo
.
classStartTime
=
GlobalConfig
.
classStartTime
;
//课堂点击开始时间
classStatusInfo
.
classStopTime
=
GlobalConfig
.
classStopTime
;
//最后一次停止的时间(点暂停或结束),每次发送数据都获取当前时间戳
classStatusInfo
.
classTimestamp
=
GlobalConfig
.
classTimestamp
;
//相对于点开始课堂的时间戳
classStatusInfo
.
classBeginTime
=
GlobalConfig
.
classBeginTime
;
//课堂创建的时间,这个是Sass返回的
classStatusInfo
.
classEndTime
=
GlobalConfig
.
classEndTime
;
//课堂结束的时间,这个是Sass返回的
classStatusInfo
.
recordStatus
=
GlobalConfig
.
recordStatus
;
//当前录制状态
classStatusInfo
.
recordTimestamp
=
GlobalConfig
.
recordTimestamp
;
//相对于首次开始录制的时间戳
classStatusInfo
.
recordFileName
=
GlobalConfig
.
recordFileName
;
//录制的文件名
classStatusInfo
.
recordDownloadUrl
=
GlobalConfig
.
recordDownloadUrl
;
//下载地址
classStatusInfo
.
serverTimestamp
=
GlobalConfig
.
serverTimestamp
;
//当前的系统时间戳
classStatusInfo
.
activeDocId
=
GlobalConfig
.
activeDocId
;
//当前激活的文档id
classStatusInfo
.
activeDocCurPage
=
GlobalConfig
.
activeDocCurPage
;
//当前激活的文档的当前页
classStatusInfo
.
isStopAllPublishMedia
=
_param
.
isStopAllPublishMedia
||
false
;
classStatusInfo
.
currentSceneTableId
=
GlobalConfig
.
currentSceneTableId
;
classStatusInfo
.
silence
=
GlobalConfig
.
silence
;
//loger.log("classStatusInfo--->", classStatusInfo);
/*
optional uint32 item_idx=1;
optional uint32 from=2;
optional uint32 owner=3;
optional uint32 action_type=4;//状态改变的类型
optional RCClassStatusInfoPdu class_status_info=5;//当前课堂状态的信息
*/
//判断type类型,根据type设置不同的参数
let
modelPdu
=
new
pdu
[
'RCClassSendDataModelPdu'
];
modelPdu
.
itemIdx
=
_itemIdx
;
modelPdu
.
from
=
GlobalConfig
.
nodeId
;
modelPdu
.
owner
=
GlobalConfig
.
nodeId
;
//modelPdu.actionType =_param.actionType;
modelPdu
.
classStatusInfo
=
classStatusInfo
;
return
modelPdu
;
}
unPackPdu
(
owner
,
itemIdx
,
itemData
)
{
loger
.
log
(
"课堂数据->unPackPdu "
);
if
(
owner
==
null
||
itemIdx
==
null
||
itemData
==
null
)
{
this
.
_emit
(
MessageTypes
.
MCU_ERROR
,
MessageTypes
.
ERR_APE_INTERFACE_PARAM_WRONG
);
return
null
;
}
try
{
let
modelPdu
=
pdu
[
'RCClassSendDataModelPdu'
].
decode
(
itemData
);
return
modelPdu
;
}
catch
(
err
)
{
loger
.
log
(
"课堂收到数据 unPackPdu Pdu解析错误,itemIdx="
+
itemIdx
+
" err:"
+
err
.
message
);
}
return
null
;
}
}
...
...
src/pdus/pro.js
查看文件 @
c1654e4
...
...
@@ -896,6 +896,7 @@ message RCNodeInfoRecordPdu {
optional
string
province
=
27
;
optional
string
isp
=
28
;
repeated
MsListItemPdu
msList
=
29
;
optional
string
selfSilence
=
30
;
}
message
RCVotingPollSettingsPdu
{
...
...
@@ -991,6 +992,7 @@ message RCClassStatusInfoPdu {
optional
uint32
active_doc_cur_page
=
21
;
//当前激活的文档的当前页
optional
bool
isStopAllPublishMedia
=
22
;
//是否停止推流
optional
uint32
currentSceneTableId
=
23
;
//文档区域的当前模块id
optional
bool
silence
=
24
;
//课堂禁言
}
message
RCConferenceRecordRequestPdu
{
...
...
请
注册
或
登录
后发表评论