- track meeting status
This commit is contained in:
parent
84bfd93701
commit
47b0ada045
@ -17,6 +17,7 @@ import org.bigbluebutton.common2.messages.MessageBody.MeetingCreatedEvtBody
|
|||||||
import org.bigbluebutton.common2.messages._
|
import org.bigbluebutton.common2.messages._
|
||||||
import org.bigbluebutton.core.running.RunningMeeting
|
import org.bigbluebutton.core.running.RunningMeeting
|
||||||
import org.bigbluebutton.core2.RunningMeetings
|
import org.bigbluebutton.core2.RunningMeetings
|
||||||
|
import org.bigbluebutton.core2.message.handlers.CreateMeetingReqMsgHdlr
|
||||||
|
|
||||||
object BigBlueButtonActor extends SystemConfiguration {
|
object BigBlueButtonActor extends SystemConfiguration {
|
||||||
def props(system: ActorSystem,
|
def props(system: ActorSystem,
|
||||||
@ -27,8 +28,9 @@ object BigBlueButtonActor extends SystemConfiguration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class BigBlueButtonActor(val system: ActorSystem,
|
class BigBlueButtonActor(val system: ActorSystem,
|
||||||
eventBus: IncomingEventBus, bbbMsgBus: BbbMsgRouterEventBus,
|
val eventBus: IncomingEventBus, val bbbMsgBus: BbbMsgRouterEventBus,
|
||||||
outGW: OutMessageGateway) extends Actor with ActorLogging with SystemConfiguration {
|
val outGW: OutMessageGateway) extends Actor
|
||||||
|
with ActorLogging with SystemConfiguration {
|
||||||
|
|
||||||
implicit def executionContext = system.dispatcher
|
implicit def executionContext = system.dispatcher
|
||||||
implicit val timeout = Timeout(5 seconds)
|
implicit val timeout = Timeout(5 seconds)
|
||||||
@ -54,8 +56,10 @@ class BigBlueButtonActor(val system: ActorSystem,
|
|||||||
}
|
}
|
||||||
|
|
||||||
def receive = {
|
def receive = {
|
||||||
|
// 2x messages
|
||||||
case msg: BbbCommonEnvCoreMsg => handleBbbCommonEnvCoreMsg(msg)
|
case msg: BbbCommonEnvCoreMsg => handleBbbCommonEnvCoreMsg(msg)
|
||||||
case msg: CreateMeetingReqMsg => handleCreateMeetingReqMsg(msg)
|
|
||||||
|
// 1x messages
|
||||||
case msg: CreateMeeting => handleCreateMeeting(msg)
|
case msg: CreateMeeting => handleCreateMeeting(msg)
|
||||||
case msg: DestroyMeeting => handleDestroyMeeting(msg)
|
case msg: DestroyMeeting => handleDestroyMeeting(msg)
|
||||||
case msg: KeepAliveMessage => handleKeepAliveMessage(msg)
|
case msg: KeepAliveMessage => handleKeepAliveMessage(msg)
|
||||||
@ -88,6 +92,52 @@ class BigBlueButtonActor(val system: ActorSystem,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def handleCreateMeetingReqMsg(msg: CreateMeetingReqMsg): Unit = {
|
||||||
|
log.debug("****** RECEIVED CreateMeetingReqMsg msg {}", msg)
|
||||||
|
|
||||||
|
RunningMeetings.findWithId(meetings, msg.body.props.meetingProp.intId) match {
|
||||||
|
case None => {
|
||||||
|
log.info("Create meeting request. meetingId={}", msg.body.props.meetingProp.intId)
|
||||||
|
|
||||||
|
val m = RunningMeeting(msg.body.props, outGW, eventBus)
|
||||||
|
|
||||||
|
/** Subscribe to meeting and voice events. **/
|
||||||
|
eventBus.subscribe(m.actorRef, m.props.meetingProp.intId)
|
||||||
|
eventBus.subscribe(m.actorRef, m.props.voiceProp.voiceConf)
|
||||||
|
eventBus.subscribe(m.actorRef, m.props.screenshareProps.screenshareConf)
|
||||||
|
|
||||||
|
bbbMsgBus.subscribe(m.actorRef, m.props.meetingProp.intId)
|
||||||
|
|
||||||
|
RunningMeetings.add(meetings, m)
|
||||||
|
|
||||||
|
// Send old message format
|
||||||
|
outGW.send(new MeetingCreated(m.props.meetingProp.intId,
|
||||||
|
m.props.meetingProp.extId, m.props.breakoutProps.parentId,
|
||||||
|
m.props.recordProp.record, m.props.meetingProp.name,
|
||||||
|
m.props.voiceProp.voiceConf, m.props.durationProps.duration,
|
||||||
|
m.props.password.moderatorPass, m.props.password.viewerPass,
|
||||||
|
m.props.durationProps.createdTime, m.props.durationProps.createdDate,
|
||||||
|
m.props.meetingProp.isBreakout))
|
||||||
|
|
||||||
|
m.actorRef ! new InitializeMeeting(m.props.meetingProp.intId, m.props.recordProp.record)
|
||||||
|
|
||||||
|
// Send new 2x message
|
||||||
|
val routing = collection.immutable.HashMap("sender" -> "bbb-apps-akka")
|
||||||
|
val envelope = BbbCoreEnvelope(MeetingCreatedEvtMsg.NAME, routing)
|
||||||
|
val header = BbbCoreBaseHeader(MeetingCreatedEvtMsg.NAME)
|
||||||
|
val body = MeetingCreatedEvtBody(msg.body.props)
|
||||||
|
val event = MeetingCreatedEvtMsg(header, body)
|
||||||
|
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
|
||||||
|
outGW.send(msgEvent)
|
||||||
|
}
|
||||||
|
case Some(m) => {
|
||||||
|
log.info("Meeting already created. meetingID={}", msg.body.props.meetingProp.intId)
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private def findMeetingWithVoiceConfId(voiceConfId: String): Option[RunningMeeting] = {
|
private def findMeetingWithVoiceConfId(voiceConfId: String): Option[RunningMeeting] = {
|
||||||
RunningMeetings.findMeetingWithVoiceConfId(meetings, voiceConfId)
|
RunningMeetings.findMeetingWithVoiceConfId(meetings, voiceConfId)
|
||||||
}
|
}
|
||||||
@ -235,52 +285,6 @@ class BigBlueButtonActor(val system: ActorSystem,
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
private def handleCreateMeetingReqMsg(msg: CreateMeetingReqMsg): Unit = {
|
|
||||||
log.debug("****** RECEIVED CreateMeetingReqMsg msg {}", msg)
|
|
||||||
|
|
||||||
RunningMeetings.findWithId(meetings, msg.body.props.meetingProp.intId) match {
|
|
||||||
case None => {
|
|
||||||
log.info("Create meeting request. meetingId={}", msg.body.props.meetingProp.intId)
|
|
||||||
|
|
||||||
val m = RunningMeeting(msg.body.props, outGW, eventBus)
|
|
||||||
|
|
||||||
/** Subscribe to meeting and voice events. **/
|
|
||||||
eventBus.subscribe(m.actorRef, m.props.meetingProp.intId)
|
|
||||||
eventBus.subscribe(m.actorRef, m.props.voiceProp.voiceConf)
|
|
||||||
eventBus.subscribe(m.actorRef, m.props.screenshareProps.screenshareConf)
|
|
||||||
|
|
||||||
bbbMsgBus.subscribe(m.actorRef, m.props.meetingProp.intId)
|
|
||||||
|
|
||||||
RunningMeetings.add(meetings, m)
|
|
||||||
|
|
||||||
// Send old message format
|
|
||||||
outGW.send(new MeetingCreated(m.props.meetingProp.intId,
|
|
||||||
m.props.meetingProp.extId, m.props.breakoutProps.parentId,
|
|
||||||
m.props.recordProp.record, m.props.meetingProp.name,
|
|
||||||
m.props.voiceProp.voiceConf, m.props.durationProps.duration,
|
|
||||||
m.props.password.moderatorPass, m.props.password.viewerPass,
|
|
||||||
m.props.durationProps.createdTime, m.props.durationProps.createdDate,
|
|
||||||
m.props.meetingProp.isBreakout))
|
|
||||||
|
|
||||||
m.actorRef ! new InitializeMeeting(m.props.meetingProp.intId, m.props.recordProp.record)
|
|
||||||
|
|
||||||
// Send new 2x message
|
|
||||||
val routing = collection.immutable.HashMap("sender" -> "bbb-apps-akka")
|
|
||||||
val envelope = BbbCoreEnvelope(MeetingCreatedEvtMsg.NAME, routing)
|
|
||||||
val header = BbbCoreBaseHeader(MeetingCreatedEvtMsg.NAME)
|
|
||||||
val body = MeetingCreatedEvtBody(msg.body.props)
|
|
||||||
val event = MeetingCreatedEvtMsg(header, body)
|
|
||||||
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
|
|
||||||
outGW.send(msgEvent)
|
|
||||||
}
|
|
||||||
case Some(m) => {
|
|
||||||
log.info("Meeting already created. meetingID={}", msg.body.props.meetingProp.intId)
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private def handleCreateMeeting(msg: CreateMeeting): Unit = {
|
private def handleCreateMeeting(msg: CreateMeeting): Unit = {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,9 +18,9 @@ class MeetingModel {
|
|||||||
private var audioSettingsInited = false
|
private var audioSettingsInited = false
|
||||||
private var permissionsInited = false
|
private var permissionsInited = false
|
||||||
private var permissions = new Permissions()
|
private var permissions = new Permissions()
|
||||||
private var recording = false;
|
private var recording = false
|
||||||
private var broadcastingRTMP = false
|
private var broadcastingRTMP = false
|
||||||
private var muted = false;
|
private var muted = false
|
||||||
private var meetingEnded = false
|
private var meetingEnded = false
|
||||||
private var meetingMuted = false
|
private var meetingMuted = false
|
||||||
private var guestPolicy = GuestPolicy.ASK_MODERATOR
|
private var guestPolicy = GuestPolicy.ASK_MODERATOR
|
||||||
@ -39,8 +39,8 @@ class MeetingModel {
|
|||||||
|
|
||||||
val startedOn = timeNowInSeconds;
|
val startedOn = timeNowInSeconds;
|
||||||
|
|
||||||
var breakoutRoomsStartedOn: Long = 0;
|
var breakoutRoomsStartedOn: Long = 0
|
||||||
var breakoutRoomsdurationInMinutes: Int = 0;
|
var breakoutRoomsdurationInMinutes: Int = 0
|
||||||
|
|
||||||
def resetDesktopSharingParams() = {
|
def resetDesktopSharingParams() = {
|
||||||
broadcastingRTMP = false
|
broadcastingRTMP = false
|
||||||
@ -56,7 +56,6 @@ class MeetingModel {
|
|||||||
|
|
||||||
def setDeskShareStarted(b: Boolean) {
|
def setDeskShareStarted(b: Boolean) {
|
||||||
deskShareStarted = b
|
deskShareStarted = b
|
||||||
println("---deskshare status changed to:" + b)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def setDesktopShareVideoWidth(videoWidth: Int) {
|
def setDesktopShareVideoWidth(videoWidth: Int) {
|
||||||
@ -88,7 +87,6 @@ class MeetingModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def setRTMPBroadcastingUrl(path: String) {
|
def setRTMPBroadcastingUrl(path: String) {
|
||||||
println("---RTMP broadcastUrl changed to:" + path)
|
|
||||||
rtmpBroadcastingUrl = path
|
rtmpBroadcastingUrl = path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,8 @@ package org.bigbluebutton.core.apps
|
|||||||
import org.bigbluebutton.core.api._
|
import org.bigbluebutton.core.api._
|
||||||
import org.bigbluebutton.core.OutMessageGateway
|
import org.bigbluebutton.core.OutMessageGateway
|
||||||
import org.bigbluebutton.core.models.Users
|
import org.bigbluebutton.core.models.Users
|
||||||
import org.bigbluebutton.core.running.{ MeetingActor }
|
import org.bigbluebutton.core.running.MeetingActor
|
||||||
|
import org.bigbluebutton.core2.MeetingStatus2x
|
||||||
|
|
||||||
trait PresentationApp {
|
trait PresentationApp {
|
||||||
this: MeetingActor =>
|
this: MeetingActor =>
|
||||||
@ -73,7 +74,7 @@ trait PresentationApp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def handleGetPresentationInfo(msg: GetPresentationInfo) {
|
def handleGetPresentationInfo(msg: GetPresentationInfo) {
|
||||||
val curPresenter = liveMeeting.getCurrentPresenterInfo()
|
val curPresenter = MeetingStatus2x.getCurrentPresenterInfo(liveMeeting.status)
|
||||||
val presenter = new CurrentPresenter(curPresenter.presenterID, curPresenter.presenterName, curPresenter.assignedBy)
|
val presenter = new CurrentPresenter(curPresenter.presenterID, curPresenter.presenterName, curPresenter.assignedBy)
|
||||||
val presentations = liveMeeting.presModel.getPresentations
|
val presentations = liveMeeting.presModel.getPresentations
|
||||||
val presentationInfo = new CurrentPresentationInfo(presenter, presentations)
|
val presentationInfo = new CurrentPresentationInfo(presenter, presentations)
|
||||||
|
@ -5,6 +5,7 @@ import org.bigbluebutton.core.OutMessageGateway
|
|||||||
import org.bigbluebutton.core.api.GuestPolicy
|
import org.bigbluebutton.core.api.GuestPolicy
|
||||||
import org.bigbluebutton.core.models._
|
import org.bigbluebutton.core.models._
|
||||||
import org.bigbluebutton.core.running.MeetingActor
|
import org.bigbluebutton.core.running.MeetingActor
|
||||||
|
import org.bigbluebutton.core2.MeetingStatus2x
|
||||||
|
|
||||||
trait UsersApp {
|
trait UsersApp {
|
||||||
this: MeetingActor =>
|
this: MeetingActor =>
|
||||||
@ -16,7 +17,7 @@ trait UsersApp {
|
|||||||
|
|
||||||
val user = Users.findWithId(msg.userid, liveMeeting.users)
|
val user = Users.findWithId(msg.userid, liveMeeting.users)
|
||||||
user foreach { u =>
|
user foreach { u =>
|
||||||
if (liveMeeting.addGlobalAudioConnection(msg.userid)) {
|
if (MeetingStatus2x.addGlobalAudioConnection(liveMeeting.status, msg.userid)) {
|
||||||
for {
|
for {
|
||||||
uvo <- Users.joinedVoiceListenOnly(msg.userid, liveMeeting.users)
|
uvo <- Users.joinedVoiceListenOnly(msg.userid, liveMeeting.users)
|
||||||
} yield {
|
} yield {
|
||||||
@ -32,7 +33,7 @@ trait UsersApp {
|
|||||||
|
|
||||||
val user = Users.findWithId(msg.userid, liveMeeting.users)
|
val user = Users.findWithId(msg.userid, liveMeeting.users)
|
||||||
user foreach { u =>
|
user foreach { u =>
|
||||||
if (liveMeeting.removeGlobalAudioConnection(msg.userid)) {
|
if (MeetingStatus2x.removeGlobalAudioConnection(liveMeeting.status, msg.userid)) {
|
||||||
if (!u.joinedWeb) {
|
if (!u.joinedWeb) {
|
||||||
for {
|
for {
|
||||||
uvo <- Users.userLeft(u.id, liveMeeting.users)
|
uvo <- Users.userLeft(u.id, liveMeeting.users)
|
||||||
@ -358,7 +359,9 @@ trait UsersApp {
|
|||||||
outGW.send(new GuestAccessDenied(props.meetingProp.intId, props.recordProp.record, uvo.id))
|
outGW.send(new GuestAccessDenied(props.meetingProp.intId, props.recordProp.record, uvo.id))
|
||||||
} else {
|
} else {
|
||||||
outGW.send(new UserJoined(props.meetingProp.intId, props.recordProp.record, uvo))
|
outGW.send(new UserJoined(props.meetingProp.intId, props.recordProp.record, uvo))
|
||||||
outGW.send(new MeetingState(props.meetingProp.intId, props.recordProp.record, uvo.id, liveMeeting.meetingModel.getPermissions(), liveMeeting.meetingModel.isMeetingMuted()))
|
outGW.send(new MeetingState(props.meetingProp.intId, props.recordProp.record, uvo.id,
|
||||||
|
liveMeeting.meetingModel.getPermissions(), liveMeeting.meetingModel.isMeetingMuted()))
|
||||||
|
|
||||||
if (!waitingForAcceptance) {
|
if (!waitingForAcceptance) {
|
||||||
// Become presenter if the only moderator
|
// Become presenter if the only moderator
|
||||||
if ((Users.numModerators(liveMeeting.users) == 1) || (Users.hasNoPresenter(liveMeeting.users))) {
|
if ((Users.numModerators(liveMeeting.users) == 1) || (Users.hasNoPresenter(liveMeeting.users))) {
|
||||||
@ -455,8 +458,9 @@ trait UsersApp {
|
|||||||
|
|
||||||
def startRecordingVoiceConference() {
|
def startRecordingVoiceConference() {
|
||||||
if (Users.numUsersInVoiceConference(liveMeeting.users) == 1 &&
|
if (Users.numUsersInVoiceConference(liveMeeting.users) == 1 &&
|
||||||
props.recordProp.record && !liveMeeting.isVoiceRecording) {
|
props.recordProp.record &&
|
||||||
liveMeeting.startRecordingVoice()
|
!MeetingStatus2x.isVoiceRecording(liveMeeting.status)) {
|
||||||
|
MeetingStatus2x.startRecordingVoice(liveMeeting.status)
|
||||||
log.info("Send START RECORDING voice conf. meetingId=" + props.meetingProp.intId + " voice conf=" + props.voiceProp.voiceConf)
|
log.info("Send START RECORDING voice conf. meetingId=" + props.meetingProp.intId + " voice conf=" + props.voiceProp.voiceConf)
|
||||||
outGW.send(new StartRecordingVoiceConf(props.meetingProp.intId, props.recordProp.record, props.voiceProp.voiceConf))
|
outGW.send(new StartRecordingVoiceConf(props.meetingProp.intId, props.recordProp.record, props.voiceProp.voiceConf))
|
||||||
}
|
}
|
||||||
@ -519,8 +523,9 @@ trait UsersApp {
|
|||||||
|
|
||||||
def stopRecordingVoiceConference() {
|
def stopRecordingVoiceConference() {
|
||||||
if (Users.numUsersInVoiceConference(liveMeeting.users) == 0 &&
|
if (Users.numUsersInVoiceConference(liveMeeting.users) == 0 &&
|
||||||
props.recordProp.record && liveMeeting.isVoiceRecording) {
|
props.recordProp.record &&
|
||||||
liveMeeting.stopRecordingVoice()
|
MeetingStatus2x.isVoiceRecording(liveMeeting.status)) {
|
||||||
|
MeetingStatus2x.stopRecordingVoice(liveMeeting.status)
|
||||||
log.info("Send STOP RECORDING voice conf. meetingId=" + props.meetingProp.intId + " voice conf=" + props.voiceProp.voiceConf)
|
log.info("Send STOP RECORDING voice conf. meetingId=" + props.meetingProp.intId + " voice conf=" + props.voiceProp.voiceConf)
|
||||||
outGW.send(new StopRecordingVoiceConf(props.meetingProp.intId, props.recordProp.record,
|
outGW.send(new StopRecordingVoiceConf(props.meetingProp.intId, props.recordProp.record,
|
||||||
props.voiceProp.voiceConf, liveMeeting.meetingModel.getVoiceRecordingFilename()))
|
props.voiceProp.voiceConf, liveMeeting.meetingModel.getVoiceRecordingFilename()))
|
||||||
@ -593,7 +598,7 @@ trait UsersApp {
|
|||||||
} yield {
|
} yield {
|
||||||
removePresenterRightsToCurrentPresenter()
|
removePresenterRightsToCurrentPresenter()
|
||||||
Users.becomePresenter(newPres.id, liveMeeting.users)
|
Users.becomePresenter(newPres.id, liveMeeting.users)
|
||||||
liveMeeting.setCurrentPresenterInfo(new Presenter(newPresenterID, newPresenterName, assignedBy))
|
MeetingStatus2x.setCurrentPresenterInfo(liveMeeting.status, new Presenter(newPresenterID, newPresenterName, assignedBy))
|
||||||
outGW.send(new PresenterAssigned(props.meetingProp.intId, props.recordProp.record, new Presenter(newPresenterID, newPresenterName, assignedBy)))
|
outGW.send(new PresenterAssigned(props.meetingProp.intId, props.recordProp.record, new Presenter(newPresenterID, newPresenterName, assignedBy)))
|
||||||
outGW.send(new UserStatusChange(props.meetingProp.intId, props.recordProp.record, newPresenterID, "presenter", true: java.lang.Boolean))
|
outGW.send(new UserStatusChange(props.meetingProp.intId, props.recordProp.record, newPresenterID, "presenter", true: java.lang.Boolean))
|
||||||
}
|
}
|
||||||
|
@ -1,69 +0,0 @@
|
|||||||
package org.bigbluebutton.core.apps
|
|
||||||
|
|
||||||
import org.bigbluebutton.core.api.Presenter
|
|
||||||
|
|
||||||
class UsersModel {
|
|
||||||
// private var uservos = new Users
|
|
||||||
|
|
||||||
// private var regUsers = new RegisteredUsers
|
|
||||||
|
|
||||||
/* When reconnecting SIP global audio, users may receive the connection message
|
|
||||||
* before the disconnection message.
|
|
||||||
* This variable is a connection counter that should control this scenario.
|
|
||||||
*/
|
|
||||||
private var globalAudioConnectionCounter = new collection.immutable.HashMap[String, Integer]
|
|
||||||
|
|
||||||
private var recordingVoice = false
|
|
||||||
|
|
||||||
private var currentPresenter = new Presenter("system", "system", "system")
|
|
||||||
|
|
||||||
def setCurrentPresenterInfo(pres: Presenter) {
|
|
||||||
currentPresenter = pres
|
|
||||||
}
|
|
||||||
|
|
||||||
def getCurrentPresenterInfo(): Presenter = {
|
|
||||||
currentPresenter
|
|
||||||
}
|
|
||||||
|
|
||||||
def addGlobalAudioConnection(userID: String): Boolean = {
|
|
||||||
globalAudioConnectionCounter.get(userID) match {
|
|
||||||
case Some(vc) => {
|
|
||||||
globalAudioConnectionCounter += userID -> (vc + 1)
|
|
||||||
false
|
|
||||||
}
|
|
||||||
case None => {
|
|
||||||
globalAudioConnectionCounter += userID -> 1
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def removeGlobalAudioConnection(userID: String): Boolean = {
|
|
||||||
globalAudioConnectionCounter.get(userID) match {
|
|
||||||
case Some(vc) => {
|
|
||||||
if (vc == 1) {
|
|
||||||
globalAudioConnectionCounter -= userID
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
globalAudioConnectionCounter += userID -> (vc - 1)
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case None => {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def startRecordingVoice() {
|
|
||||||
recordingVoice = true
|
|
||||||
}
|
|
||||||
|
|
||||||
def stopRecordingVoice() {
|
|
||||||
recordingVoice = false
|
|
||||||
}
|
|
||||||
|
|
||||||
def isVoiceRecording: Boolean = {
|
|
||||||
recordingVoice
|
|
||||||
}
|
|
||||||
}
|
|
@ -7,12 +7,13 @@ import org.bigbluebutton.core.api._
|
|||||||
import org.bigbluebutton.core.apps._
|
import org.bigbluebutton.core.apps._
|
||||||
import org.bigbluebutton.core.models.{ RegisteredUsers, Users }
|
import org.bigbluebutton.core.models.{ RegisteredUsers, Users }
|
||||||
import org.bigbluebutton.core.{ MeetingModel, MeetingProperties }
|
import org.bigbluebutton.core.{ MeetingModel, MeetingProperties }
|
||||||
|
import org.bigbluebutton.core2.MeetingStatus2x
|
||||||
|
|
||||||
class LiveMeeting(val props: DefaultProps,
|
class LiveMeeting(val props: DefaultProps,
|
||||||
|
val status: MeetingStatus2x,
|
||||||
val chatModel: ChatModel,
|
val chatModel: ChatModel,
|
||||||
val layoutModel: LayoutModel,
|
val layoutModel: LayoutModel,
|
||||||
val meetingModel: MeetingModel,
|
val meetingModel: MeetingModel,
|
||||||
private val usersModel: UsersModel,
|
|
||||||
val users: Users,
|
val users: Users,
|
||||||
val registeredUsers: RegisteredUsers,
|
val registeredUsers: RegisteredUsers,
|
||||||
val pollModel: PollModel,
|
val pollModel: PollModel,
|
||||||
@ -33,34 +34,6 @@ class LiveMeeting(val props: DefaultProps,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def setCurrentPresenterInfo(pres: Presenter) {
|
|
||||||
usersModel.setCurrentPresenterInfo(pres)
|
|
||||||
}
|
|
||||||
|
|
||||||
def getCurrentPresenterInfo(): Presenter = {
|
|
||||||
usersModel.getCurrentPresenterInfo()
|
|
||||||
}
|
|
||||||
|
|
||||||
def addGlobalAudioConnection(userID: String): Boolean = {
|
|
||||||
usersModel.addGlobalAudioConnection(userID)
|
|
||||||
}
|
|
||||||
|
|
||||||
def removeGlobalAudioConnection(userID: String): Boolean = {
|
|
||||||
usersModel.removeGlobalAudioConnection(userID)
|
|
||||||
}
|
|
||||||
|
|
||||||
def startRecordingVoice() {
|
|
||||||
usersModel.startRecordingVoice()
|
|
||||||
}
|
|
||||||
|
|
||||||
def stopRecordingVoice() {
|
|
||||||
usersModel.stopRecordingVoice()
|
|
||||||
}
|
|
||||||
|
|
||||||
def isVoiceRecording: Boolean = {
|
|
||||||
usersModel.isVoiceRecording
|
|
||||||
}
|
|
||||||
|
|
||||||
def startCheckingIfWeNeedToEndVoiceConf() {
|
def startCheckingIfWeNeedToEndVoiceConf() {
|
||||||
if (Users.numWebUsers(users) == 0 && !props.meetingProp.isBreakout) {
|
if (Users.numWebUsers(users) == 0 && !props.meetingProp.isBreakout) {
|
||||||
meetingModel.lastWebUserLeft()
|
meetingModel.lastWebUserLeft()
|
||||||
|
@ -55,9 +55,14 @@ class MeetingActor(val props: DefaultProps,
|
|||||||
eventBus.subscribe(actorMonitor, props.screenshareProps.screenshareConf)
|
eventBus.subscribe(actorMonitor, props.screenshareProps.screenshareConf)
|
||||||
|
|
||||||
def receive = {
|
def receive = {
|
||||||
|
//=============================
|
||||||
|
// 2x messages
|
||||||
case msg: BbbCommonEnvCoreMsg => handleBbbCommonEnvCoreMsg(msg)
|
case msg: BbbCommonEnvCoreMsg => handleBbbCommonEnvCoreMsg(msg)
|
||||||
case msg: RegisterUserReqMsg => handleRegisterUserReqMsg(msg)
|
case msg: RegisterUserReqMsg => handleRegisterUserReqMsg(msg)
|
||||||
|
//======================================
|
||||||
|
|
||||||
|
//=======================================
|
||||||
|
// old messages
|
||||||
case msg: ActivityResponse => handleActivityResponse(msg)
|
case msg: ActivityResponse => handleActivityResponse(msg)
|
||||||
case msg: MonitorNumberOfUsers => handleMonitorNumberOfUsers(msg)
|
case msg: MonitorNumberOfUsers => handleMonitorNumberOfUsers(msg)
|
||||||
case msg: ValidateAuthToken => handleValidateAuthToken(msg)
|
case msg: ValidateAuthToken => handleValidateAuthToken(msg)
|
||||||
@ -201,10 +206,22 @@ class MeetingActor(val props: DefaultProps,
|
|||||||
"msgType" -> "direct", "meetingId" -> props.meetingProp.intId, "userId" -> msg.body.userId)
|
"msgType" -> "direct", "meetingId" -> props.meetingProp.intId, "userId" -> msg.body.userId)
|
||||||
val envelope = BbbCoreEnvelope(ValidateAuthTokenRespMsg.NAME, routing)
|
val envelope = BbbCoreEnvelope(ValidateAuthTokenRespMsg.NAME, routing)
|
||||||
val header = BbbCoreHeaderWithMeetingId(ValidateAuthTokenRespMsg.NAME, props.meetingProp.intId)
|
val header = BbbCoreHeaderWithMeetingId(ValidateAuthTokenRespMsg.NAME, props.meetingProp.intId)
|
||||||
val body = ValidateAuthTokenRespMsgBody(msg.body.userId, msg.body.authToken, true)
|
|
||||||
val event = ValidateAuthTokenRespMsg(header, body)
|
RegisteredUsers.getRegisteredUserWithToken(msg.body.authToken, msg.body.userId, liveMeeting.registeredUsers) match {
|
||||||
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
|
case Some(u) =>
|
||||||
outGW.send(msgEvent)
|
log.info("ValidateToken success. meetingId=" + props.meetingProp.intId + " userId=" + msg.body.userId)
|
||||||
|
|
||||||
|
val body = ValidateAuthTokenRespMsgBody(msg.body.userId, msg.body.authToken, true)
|
||||||
|
val event = ValidateAuthTokenRespMsg(header, body)
|
||||||
|
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
|
||||||
|
outGW.send(msgEvent)
|
||||||
|
case None =>
|
||||||
|
log.info("ValidateToken failed. meetingId=" + props.meetingProp.intId + " userId=" + msg.body.userId)
|
||||||
|
val body = ValidateAuthTokenRespMsgBody(msg.body.userId, msg.body.authToken, false)
|
||||||
|
val event = ValidateAuthTokenRespMsg(header, body)
|
||||||
|
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
|
||||||
|
outGW.send(msgEvent)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def handleDeskShareRTMPBroadcastStoppedRequest(msg: DeskShareRTMPBroadcastStoppedRequest): Unit = {
|
def handleDeskShareRTMPBroadcastStoppedRequest(msg: DeskShareRTMPBroadcastStoppedRequest): Unit = {
|
||||||
|
@ -20,7 +20,6 @@ class RunningMeeting(val props: DefaultProps, val outGW: OutMessageGateway,
|
|||||||
val chatModel = new ChatModel()
|
val chatModel = new ChatModel()
|
||||||
val layoutModel = new LayoutModel()
|
val layoutModel = new LayoutModel()
|
||||||
val meetingModel = new MeetingModel()
|
val meetingModel = new MeetingModel()
|
||||||
val usersModel = new UsersModel()
|
|
||||||
val pollModel = new PollModel()
|
val pollModel = new PollModel()
|
||||||
val wbModel = new WhiteboardModel()
|
val wbModel = new WhiteboardModel()
|
||||||
val presModel = new PresentationModel()
|
val presModel = new PresentationModel()
|
||||||
@ -29,13 +28,14 @@ class RunningMeeting(val props: DefaultProps, val outGW: OutMessageGateway,
|
|||||||
val notesModel = new SharedNotesModel()
|
val notesModel = new SharedNotesModel()
|
||||||
val users = new Users
|
val users = new Users
|
||||||
val registeredUsers = new RegisteredUsers
|
val registeredUsers = new RegisteredUsers
|
||||||
// val meetingStatux2x = new MeetingStatus2x(props, )
|
val meetingStatux2x = new MeetingStatus2x
|
||||||
|
|
||||||
// meetingModel.setGuestPolicy(props.usersProp.guestPolicy)
|
// meetingModel.setGuestPolicy(props.usersProp.guestPolicy)
|
||||||
|
|
||||||
// We extract the meeting handlers into this class so it is
|
// We extract the meeting handlers into this class so it is
|
||||||
// easy to test.
|
// easy to test.
|
||||||
val liveMeeting = new LiveMeeting(props, chatModel, layoutModel, meetingModel, usersModel, users, registeredUsers, pollModel,
|
val liveMeeting = new LiveMeeting(props, meetingStatux2x, chatModel, layoutModel,
|
||||||
|
meetingModel, users, registeredUsers, pollModel,
|
||||||
wbModel, presModel, breakoutModel, captionModel, notesModel)
|
wbModel, presModel, breakoutModel, captionModel, notesModel)
|
||||||
|
|
||||||
val actorRef = context.actorOf(MeetingActor.props(props, eventBus, outGW, liveMeeting), props.meetingProp.intId)
|
val actorRef = context.actorOf(MeetingActor.props(props, eventBus, outGW, liveMeeting), props.meetingProp.intId)
|
||||||
|
@ -1,5 +1,141 @@
|
|||||||
package org.bigbluebutton.core2
|
package org.bigbluebutton.core2
|
||||||
|
|
||||||
class MeetingStatus2x {
|
import org.bigbluebutton.core.MeetingExtensionProp
|
||||||
|
import org.bigbluebutton.core.api.{GuestPolicy, Permissions, Presenter}
|
||||||
|
|
||||||
|
object MeetingStatus2x {
|
||||||
|
def setCurrentPresenterInfo(status: MeetingStatus2x, pres: Presenter) {
|
||||||
|
status.currentPresenter = pres
|
||||||
|
}
|
||||||
|
|
||||||
|
def getCurrentPresenterInfo(status: MeetingStatus2x): Presenter = {
|
||||||
|
status.currentPresenter
|
||||||
|
}
|
||||||
|
|
||||||
|
def addGlobalAudioConnection(status: MeetingStatus2x, userID: String): Boolean = {
|
||||||
|
status.globalAudioConnectionCounter.get(userID) match {
|
||||||
|
case Some(vc) => {
|
||||||
|
status.globalAudioConnectionCounter += userID -> (vc + 1)
|
||||||
|
false
|
||||||
|
}
|
||||||
|
case None => {
|
||||||
|
status.globalAudioConnectionCounter += userID -> 1
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def removeGlobalAudioConnection(status: MeetingStatus2x, userID: String): Boolean = {
|
||||||
|
status.globalAudioConnectionCounter.get(userID) match {
|
||||||
|
case Some(vc) => {
|
||||||
|
if (vc == 1) {
|
||||||
|
status.globalAudioConnectionCounter -= userID
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
status.globalAudioConnectionCounter += userID -> (vc - 1)
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case None => {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def startRecordingVoice(status: MeetingStatus2x): Boolean = {
|
||||||
|
status.recordingVoice = true
|
||||||
|
status.recordingVoice
|
||||||
|
}
|
||||||
|
|
||||||
|
def stopRecordingVoice(status: MeetingStatus2x): Boolean = {
|
||||||
|
status.recordingVoice = false
|
||||||
|
status.recordingVoice
|
||||||
|
}
|
||||||
|
|
||||||
|
def isVoiceRecording(status: MeetingStatus2x): Boolean = {
|
||||||
|
status.recordingVoice
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MeetingStatus2x {
|
||||||
|
private var globalAudioConnectionCounter = new collection.immutable.HashMap[String, Integer]
|
||||||
|
|
||||||
|
private var recordingVoice = false
|
||||||
|
|
||||||
|
private var currentPresenter = new Presenter("system", "system", "system")
|
||||||
|
private var audioSettingsInited = false
|
||||||
|
private var permissionsInited = false
|
||||||
|
private var permissions = new Permissions()
|
||||||
|
private var recording = false
|
||||||
|
private var broadcastingRTMP = false
|
||||||
|
private var muted = false
|
||||||
|
private var meetingEnded = false
|
||||||
|
private var meetingMuted = false
|
||||||
|
private var guestPolicy = GuestPolicy.ASK_MODERATOR
|
||||||
|
private var guestPolicySetBy: String = null
|
||||||
|
|
||||||
|
private var hasLastWebUserLeft = false
|
||||||
|
private var lastWebUserLeftOnTimestamp: Long = 0
|
||||||
|
|
||||||
|
private var voiceRecordingFilename: String = ""
|
||||||
|
private var rtmpBroadcastingUrl: String = ""
|
||||||
|
private var deskShareStarted = false
|
||||||
|
private var desktopShareVideoWidth = 0
|
||||||
|
private var desktopShareVideoHeight = 0
|
||||||
|
|
||||||
|
private var extension = new MeetingExtensionProp
|
||||||
|
|
||||||
|
val startedOn = timeNowInSeconds;
|
||||||
|
var breakoutRoomsStartedOn: Long = 0
|
||||||
|
var breakoutRoomsdurationInMinutes: Int = 0
|
||||||
|
|
||||||
|
private def setCurrentPresenterInfo(pres: Presenter) {
|
||||||
|
currentPresenter = pres
|
||||||
|
}
|
||||||
|
|
||||||
|
private def getCurrentPresenterInfo(): Presenter = {
|
||||||
|
currentPresenter
|
||||||
|
}
|
||||||
|
|
||||||
|
private def addGlobalAudioConnection(userID: String): Boolean = {
|
||||||
|
globalAudioConnectionCounter.get(userID) match {
|
||||||
|
case Some(vc) => {
|
||||||
|
globalAudioConnectionCounter += userID -> (vc + 1)
|
||||||
|
false
|
||||||
|
}
|
||||||
|
case None => {
|
||||||
|
globalAudioConnectionCounter += userID -> 1
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private def removeGlobalAudioConnection(userID: String): Boolean = {
|
||||||
|
globalAudioConnectionCounter.get(userID) match {
|
||||||
|
case Some(vc) => {
|
||||||
|
if (vc == 1) {
|
||||||
|
globalAudioConnectionCounter -= userID
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
globalAudioConnectionCounter += userID -> (vc - 1)
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case None => {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private def startRecordingVoice() {
|
||||||
|
recordingVoice = true
|
||||||
|
}
|
||||||
|
|
||||||
|
private def stopRecordingVoice() {
|
||||||
|
recordingVoice = false
|
||||||
|
}
|
||||||
|
|
||||||
|
private def isVoiceRecording: Boolean = {
|
||||||
|
recordingVoice
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
package org.bigbluebutton.core2.message.handlers
|
package org.bigbluebutton.core2.message.handlers
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by ralam on 2017-05-29.
|
|
||||||
*/
|
|
||||||
trait CreateMeetingReqMsgHdlr {
|
trait CreateMeetingReqMsgHdlr {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,7 @@ package org.bigbluebutton.main.model.users
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function onMessageFromServer2x(messageName:String, msg:String):void {
|
public function onMessageFromServer2x(messageName:String, msg:String):void {
|
||||||
trace("onMessageFromServer - " + msg);
|
trace("onMessageFromServer2x - " + msg);
|
||||||
var map:Object = JSON.parse(msg);
|
var map:Object = JSON.parse(msg);
|
||||||
var header: Object = map.header as Object;
|
var header: Object = map.header as Object;
|
||||||
var body: Object = map.body as Object;
|
var body: Object = map.body as Object;
|
||||||
@ -122,8 +122,6 @@ package org.bigbluebutton.main.model.users
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function onMessageFromServer(messageName:String, msg:Object):void {
|
public function onMessageFromServer(messageName:String, msg:Object):void {
|
||||||
trace("onMessageFromServer2 - " + msg);
|
|
||||||
|
|
||||||
if (!authenticated && (messageName == "validateAuthTokenReply")) {
|
if (!authenticated && (messageName == "validateAuthTokenReply")) {
|
||||||
handleValidateAuthTokenReply(msg)
|
handleValidateAuthTokenReply(msg)
|
||||||
} else if (messageName == "validateAuthTokenTimedOut") {
|
} else if (messageName == "validateAuthTokenTimedOut") {
|
||||||
|
Loading…
Reference in New Issue
Block a user