diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonActor.scala index 5a6d5cc6c79647cf85fbe67c40c5c2872a596bee..44ecc08fdce31b2d8a4b169758d94327c833d63e 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonActor.scala @@ -121,7 +121,7 @@ class BigBlueButtonActor( val m = RunningMeeting(msg.body.props, outGW, eventBus) - /** Subscribe to meeting and voice events. **/ + // 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) @@ -161,7 +161,7 @@ class BigBlueButtonActor( m <- RunningMeetings.findWithId(meetings, msg.meetingId) m2 <- RunningMeetings.remove(meetings, msg.meetingId) } yield { - /** Unsubscribe to meeting and voice events. **/ + // Unsubscribe to meeting and voice events. eventBus.unsubscribe(m.actorRef, m.props.meetingProp.intId) eventBus.unsubscribe(m.actorRef, m.props.voiceProp.voiceConf) eventBus.unsubscribe(m.actorRef, m.props.screenshareProps.screenshareConf) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/BreakoutHdlrHelpers.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/BreakoutHdlrHelpers.scala index a51591fa59cf375c31e615e08a55456379fbeaa6..0d8361a8abbb2b5341020cf24bedea262167dc42 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/BreakoutHdlrHelpers.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/BreakoutHdlrHelpers.scala @@ -8,12 +8,15 @@ import org.bigbluebutton.core.domain.{ BreakoutUser, BreakoutVoiceUser } import org.bigbluebutton.core.models.{ Users2x, VoiceUsers } import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter } -trait BreakoutHdlrHelpers extends SystemConfiguration { - val liveMeeting: LiveMeeting - val outGW: OutMsgRouter - val eventBus: InternalEventBus - - def sendJoinURL(userId: String, externalMeetingId: String, roomSequence: String, breakoutId: String) { +object BreakoutHdlrHelpers extends SystemConfiguration { + def sendJoinURL( + liveMeeting: LiveMeeting, + outGW: OutMsgRouter, + userId: String, + externalMeetingId: String, + roomSequence: String, + breakoutId: String + ) { for { user <- Users2x.findWithIntId(liveMeeting.users2x, userId) apiCall = "join" @@ -28,13 +31,27 @@ trait BreakoutHdlrHelpers extends SystemConfiguration { redirectToHtml5JoinURL = BreakoutRoomsUtil.createJoinURL(bbbWebAPI, apiCall, redirectToHtml5BaseString, BreakoutRoomsUtil.calculateChecksum(apiCall, redirectToHtml5BaseString, bbbWebSharedSecret)) } yield { - sendJoinURLMsg(liveMeeting.props.meetingProp.intId, breakoutId, externalMeetingId, - userId, redirectJoinURL, redirectToHtml5JoinURL) + sendJoinURLMsg( + outGW, + liveMeeting.props.meetingProp.intId, + breakoutId, + externalMeetingId, + userId, + redirectJoinURL, + redirectToHtml5JoinURL + ) } } - def sendJoinURLMsg(meetingId: String, breakoutId: String, externalId: String, - userId: String, redirectJoinURL: String, redirectToHtml5JoinURL: String): Unit = { + def sendJoinURLMsg( + outGW: OutMsgRouter, + meetingId: String, + breakoutId: String, + externalId: String, + userId: String, + redirectJoinURL: String, + redirectToHtml5JoinURL: String + ): Unit = { def build(meetingId: String, breakoutId: String, userId: String, redirectJoinURL: String, redirectToHtml5JoinURL: String): BbbCommonEnvCoreMsg = { val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, meetingId, userId) @@ -52,7 +69,10 @@ trait BreakoutHdlrHelpers extends SystemConfiguration { } - def updateParentMeetingWithUsers(): Unit = { + def updateParentMeetingWithUsers( + liveMeeting: LiveMeeting, + eventBus: InternalEventBus + ): Unit = { val users = Users2x.findAll(liveMeeting.users2x) val breakoutUsers = users map { u => new BreakoutUser(u.extId, u.name) } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/BreakoutRoomCreatedMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/BreakoutRoomCreatedMsgHdlr.scala index cccb9fa0f69c261f4775f039f317113ab4dcb893..bce40f1cf045025ee7be18d103bc9e26c462dfff 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/BreakoutRoomCreatedMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/BreakoutRoomCreatedMsgHdlr.scala @@ -4,10 +4,10 @@ import org.bigbluebutton.common2.msgs._ import org.bigbluebutton.core.api.BreakoutRoomCreatedInternalMsg import org.bigbluebutton.core.apps.BreakoutModel import org.bigbluebutton.core.domain.{ BreakoutRoom2x, MeetingState2x } -import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting, OutMsgRouter } +import org.bigbluebutton.core.running.{ LiveMeeting, MeetingActor, OutMsgRouter } -trait BreakoutRoomCreatedMsgHdlr extends BreakoutHdlrHelpers { - this: BaseMeetingActor => +trait BreakoutRoomCreatedMsgHdlr { + this: MeetingActor => val liveMeeting: LiveMeeting val outGW: OutMsgRouter @@ -41,7 +41,14 @@ trait BreakoutRoomCreatedMsgHdlr extends BreakoutHdlrHelpers { breakoutModel.rooms.values.foreach { room => log.debug("Sending invitations for room {} with num users {}", room.name, room.assignedUsers.toVector.length) room.assignedUsers.foreach { user => - sendJoinURL(user, room.externalId, room.sequence.toString(), room.id) + BreakoutHdlrHelpers.sendJoinURL( + liveMeeting, + outGW, + user, + room.externalId, + room.sequence.toString(), + room.id + ) } } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/RequestBreakoutJoinURLReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/RequestBreakoutJoinURLReqMsgHdlr.scala index 71e2d21a9e2bb2476ce3cdc56fee01a54f816ab2..2089416bc892c1bcbf3fdef0bd2c909dc509b4e0 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/RequestBreakoutJoinURLReqMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/RequestBreakoutJoinURLReqMsgHdlr.scala @@ -5,7 +5,7 @@ import org.bigbluebutton.core.domain.MeetingState2x import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter } import org.bigbluebutton.core.apps.{ PermissionCheck, RightsManagementTrait } -trait RequestBreakoutJoinURLReqMsgHdlr extends BreakoutHdlrHelpers with RightsManagementTrait { +trait RequestBreakoutJoinURLReqMsgHdlr extends RightsManagementTrait { this: MeetingActor => val outGW: OutMsgRouter @@ -20,7 +20,14 @@ trait RequestBreakoutJoinURLReqMsgHdlr extends BreakoutHdlrHelpers with RightsMa model <- state.breakout room <- model.find(msg.body.breakoutId) } yield { - sendJoinURL(msg.body.userId, room.externalId, room.sequence.toString(), room.id) + BreakoutHdlrHelpers.sendJoinURL( + liveMeeting, + outGW, + msg.body.userId, + room.externalId, + room.sequence.toString(), + room.id + ) } } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/SendBreakoutUsersUpdateMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/SendBreakoutUsersUpdateMsgHdlr.scala index f97bf0d93be85158225e12ddd1764790d5e0af80..d12843d45ae5c704cbc89bc1f7d078b8e37c8e7c 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/SendBreakoutUsersUpdateMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/SendBreakoutUsersUpdateMsgHdlr.scala @@ -10,6 +10,9 @@ trait SendBreakoutUsersUpdateMsgHdlr { def handleSendBreakoutUsersUpdateInternalMsg(msg: SendBreakoutUsersAuditInternalMsg): Unit = { - updateParentMeetingWithUsers() + BreakoutHdlrHelpers.updateParentMeetingWithUsers( + liveMeeting, + eventBus + ) } } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserJoinMeetingAfterReconnectReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserJoinMeetingAfterReconnectReqMsgHdlr.scala index 9f2ae24579d7ef1a67b2ce2822f56e03bd35d946..88a06ea09e13495b0cb9ec1845137dc6c69c659a 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserJoinMeetingAfterReconnectReqMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserJoinMeetingAfterReconnectReqMsgHdlr.scala @@ -5,10 +5,10 @@ import org.bigbluebutton.core.apps.breakout.BreakoutHdlrHelpers import org.bigbluebutton.core.apps.voice.UserJoinedVoiceConfEvtMsgHdlr import org.bigbluebutton.core.domain.MeetingState2x import org.bigbluebutton.core.models.Users2x -import org.bigbluebutton.core.running.{ BaseMeetingActor, HandlerHelpers, LiveMeeting, OutMsgRouter } +import org.bigbluebutton.core.running.{ HandlerHelpers, LiveMeeting, MeetingActor, OutMsgRouter } -trait UserJoinMeetingAfterReconnectReqMsgHdlr extends HandlerHelpers with BreakoutHdlrHelpers with UserJoinedVoiceConfEvtMsgHdlr { - this: BaseMeetingActor => +trait UserJoinMeetingAfterReconnectReqMsgHdlr extends HandlerHelpers with UserJoinedVoiceConfEvtMsgHdlr { + this: MeetingActor => val liveMeeting: LiveMeeting val outGW: OutMsgRouter @@ -27,7 +27,7 @@ trait UserJoinMeetingAfterReconnectReqMsgHdlr extends HandlerHelpers with Breako case None => val newState = userJoinMeeting(outGW, msg.body.authToken, msg.body.clientType, liveMeeting, state) if (liveMeeting.props.meetingProp.isBreakout) { - updateParentMeetingWithUsers() + BreakoutHdlrHelpers.updateParentMeetingWithUsers(liveMeeting, eventBus) } newState } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserJoinMeetingReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserJoinMeetingReqMsgHdlr.scala index 9aee3e87c41d96680709d9a4721f5bb567e78ecd..cd8011ff15b45366cc33fc75c14fdaab39332061 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserJoinMeetingReqMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserJoinMeetingReqMsgHdlr.scala @@ -4,10 +4,10 @@ import org.bigbluebutton.common2.msgs.UserJoinMeetingReqMsg import org.bigbluebutton.core.apps.breakout.BreakoutHdlrHelpers import org.bigbluebutton.core.models.{ Users2x, VoiceUsers } import org.bigbluebutton.core.domain.MeetingState2x -import org.bigbluebutton.core.running.{ BaseMeetingActor, HandlerHelpers, LiveMeeting, OutMsgRouter } +import org.bigbluebutton.core.running.{ HandlerHelpers, LiveMeeting, MeetingActor, OutMsgRouter } -trait UserJoinMeetingReqMsgHdlr extends HandlerHelpers with BreakoutHdlrHelpers { - this: BaseMeetingActor => +trait UserJoinMeetingReqMsgHdlr extends HandlerHelpers { + this: MeetingActor => val liveMeeting: LiveMeeting val outGW: OutMsgRouter @@ -27,7 +27,7 @@ trait UserJoinMeetingReqMsgHdlr extends HandlerHelpers with BreakoutHdlrHelpers val newState = userJoinMeeting(outGW, msg.body.authToken, msg.body.clientType, liveMeeting, state) if (liveMeeting.props.meetingProp.isBreakout) { - updateParentMeetingWithUsers() + BreakoutHdlrHelpers.updateParentMeetingWithUsers(liveMeeting, eventBus) } // fresh user joined (not due to reconnection). Clear (pop) the cached voice user diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/UserJoinedVoiceConfEvtMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/UserJoinedVoiceConfEvtMsgHdlr.scala index 4e73d2b693b8b59e6a2506115b09fa1626e8b1c5..ac38722dd642859065d440c58d6be7547b225262 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/UserJoinedVoiceConfEvtMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/UserJoinedVoiceConfEvtMsgHdlr.scala @@ -2,14 +2,10 @@ package org.bigbluebutton.core.apps.voice import org.bigbluebutton.SystemConfiguration import org.bigbluebutton.common2.msgs._ -import org.bigbluebutton.core.apps.breakout.BreakoutHdlrHelpers -import org.bigbluebutton.core.models.{ VoiceUserState, VoiceUsers } -import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting, OutMsgRouter } -import org.bigbluebutton.core2.MeetingStatus2x -import org.bigbluebutton.core2.message.senders.MsgBuilder +import org.bigbluebutton.core.running.{ LiveMeeting, MeetingActor, OutMsgRouter } -trait UserJoinedVoiceConfEvtMsgHdlr extends BreakoutHdlrHelpers with SystemConfiguration { - this: BaseMeetingActor => +trait UserJoinedVoiceConfEvtMsgHdlr extends SystemConfiguration { + this: MeetingActor => val liveMeeting: LiveMeeting val outGW: OutMsgRouter @@ -17,7 +13,10 @@ trait UserJoinedVoiceConfEvtMsgHdlr extends BreakoutHdlrHelpers with SystemConfi def handleUserJoinedVoiceConfEvtMsg(msg: UserJoinedVoiceConfEvtMsg): Unit = { log.info("Received user joined voice conference " + msg) - handleUserJoinedVoiceConfEvtMsg( + VoiceApp.handleUserJoinedVoiceConfEvtMsg( + liveMeeting, + outGW, + eventBus, msg.body.voiceConf, msg.body.intId, msg.body.voiceUserId, @@ -29,91 +28,4 @@ trait UserJoinedVoiceConfEvtMsgHdlr extends BreakoutHdlrHelpers with SystemConfi "freeswitch" ) } - - def handleUserJoinedVoiceConfEvtMsg( - voiceConf: String, - intId: String, - voiceUserId: String, - callingWith: String, - callerIdName: String, - callerIdNum: String, - muted: Boolean, - talking: Boolean, - callingInto: String - ): Unit = { - - def broadcastEvent(voiceUserState: VoiceUserState): Unit = { - val routing = Routing.addMsgToClientRouting( - MessageTypes.BROADCAST_TO_MEETING, - liveMeeting.props.meetingProp.intId, - voiceUserState.intId - ) - val envelope = BbbCoreEnvelope( - UserJoinedVoiceConfToClientEvtMsg.NAME, - routing - ) - val header = BbbClientMsgHeader( - UserJoinedVoiceConfToClientEvtMsg.NAME, - liveMeeting.props.meetingProp.intId, - voiceUserState.intId - ) - - val body = UserJoinedVoiceConfToClientEvtMsgBody( - voiceConf, - voiceUserState.intId, - voiceUserState.voiceUserId, - voiceUserState.callerName, - voiceUserState.callerNum, - voiceUserState.muted, - voiceUserState.talking, - voiceUserState.callingWith, - voiceUserState.listenOnly - ) - - val event = UserJoinedVoiceConfToClientEvtMsg( - header, - body - ) - val msgEvent = BbbCommonEnvCoreMsg( - envelope, - event - ) - outGW.send(msgEvent) - } - - val isListenOnly = if (callerIdName.startsWith("LISTENONLY")) true else false - - val voiceUserState = VoiceUserState( - intId, - voiceUserId, - callingWith, - callerIdName, - callerIdNum, - muted, - talking, - listenOnly = isListenOnly, - callingInto, - System.currentTimeMillis() - ) - VoiceUsers.add(liveMeeting.voiceUsers, voiceUserState) - - broadcastEvent(voiceUserState) - - if (liveMeeting.props.meetingProp.isBreakout) { - updateParentMeetingWithUsers() - } - - // if the meeting is muted tell freeswitch to mute the new person - if (!isListenOnly - && MeetingStatus2x.isMeetingMuted(liveMeeting.status)) { - val event = MsgBuilder.buildMuteUserInVoiceConfSysMsg( - liveMeeting.props.meetingProp.intId, - voiceConf, - voiceUserId, - true - ) - outGW.send(event) - } - } - } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/UserLeftVoiceConfEvtMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/UserLeftVoiceConfEvtMsgHdlr.scala index 209b01acd5c326ab06975ba16e49a4eb1832a3e2..c9eec16579c01f9ff94def46e455f93befdc039c 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/UserLeftVoiceConfEvtMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/UserLeftVoiceConfEvtMsgHdlr.scala @@ -3,10 +3,10 @@ package org.bigbluebutton.core.apps.voice import org.bigbluebutton.common2.msgs._ import org.bigbluebutton.core.apps.breakout.BreakoutHdlrHelpers import org.bigbluebutton.core.models.{ VoiceUserState, VoiceUsers } -import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting, OutMsgRouter } +import org.bigbluebutton.core.running.{ LiveMeeting, MeetingActor, OutMsgRouter } -trait UserLeftVoiceConfEvtMsgHdlr extends BreakoutHdlrHelpers { - this: BaseMeetingActor => +trait UserLeftVoiceConfEvtMsgHdlr { + this: MeetingActor => val liveMeeting: LiveMeeting val outGW: OutMsgRouter @@ -34,7 +34,7 @@ trait UserLeftVoiceConfEvtMsgHdlr extends BreakoutHdlrHelpers { } if (liveMeeting.props.meetingProp.isBreakout) { - updateParentMeetingWithUsers() + BreakoutHdlrHelpers.updateParentMeetingWithUsers(liveMeeting, eventBus) } } } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/UserStatusVoiceConfEvtMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/UserStatusVoiceConfEvtMsgHdlr.scala index a49e8ba66145f4477f662a8ed03e964bd7f73cd3..ccd3ca137f862f8c81c592a91cae4805cb607e8d 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/UserStatusVoiceConfEvtMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/UserStatusVoiceConfEvtMsgHdlr.scala @@ -1,22 +1,22 @@ package org.bigbluebutton.core.apps.voice import org.bigbluebutton.common2.msgs.UserStatusVoiceConfEvtMsg -import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting, OutMsgRouter } +import org.bigbluebutton.core.running.{ LiveMeeting, MeetingActor, OutMsgRouter } trait UserStatusVoiceConfEvtMsgHdlr { - this: BaseMeetingActor => + this: MeetingActor => val liveMeeting: LiveMeeting val outGW: OutMsgRouter def handleUserStatusVoiceConfEvtMsg(msg: UserStatusVoiceConfEvtMsg): Unit = { - println("************* RECEIVED UserStatusVoiceConfEvtMsg *************") - msg.body.confUsers foreach { cm => - println("user " + cm.callerIdName) - } - msg.body.confRecordings foreach { cr => - println("rec = " + cr.recordPath) - } + VoiceApp.processUserStatusVoiceConfEvtMsg( + liveMeeting, + outGW, + eventBus, + msg.body.confUsers + ) + } } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/VoiceApp.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/VoiceApp.scala index b26bc6765b57e6a50f09153f016468ab58d37a8b..b5b1dc9e360f698a14ecabddaf987434dc814397 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/VoiceApp.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/VoiceApp.scala @@ -1,5 +1,9 @@ package org.bigbluebutton.core.apps.voice +import org.bigbluebutton.common2.msgs.{ BbbClientMsgHeader, BbbCommonEnvCoreMsg, BbbCoreEnvelope, ConfVoiceUser, MessageTypes, Routing, UserJoinedVoiceConfToClientEvtMsg, UserJoinedVoiceConfToClientEvtMsgBody, UserLeftVoiceConfToClientEvtMsg, UserLeftVoiceConfToClientEvtMsgBody, UserMutedVoiceEvtMsg, UserMutedVoiceEvtMsgBody } +import org.bigbluebutton.core.apps.breakout.BreakoutHdlrHelpers +import org.bigbluebutton.core.bus.InternalEventBus +import org.bigbluebutton.core.models.{ VoiceUserState, VoiceUsers } import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter } import org.bigbluebutton.core2.MeetingStatus2x import org.bigbluebutton.core2.message.senders.MsgBuilder @@ -35,6 +39,246 @@ object VoiceApp { ) outGW.send(event) } + } + + def broadcastUserMutedVoiceEvtMsg( + meetingId: String, + vu: VoiceUserState, + voiceConf: String, + outGW: OutMsgRouter + ): Unit = { + val routing = Routing.addMsgToClientRouting( + MessageTypes.BROADCAST_TO_MEETING, + meetingId, + vu.intId + ) + val envelope = BbbCoreEnvelope(UserMutedVoiceEvtMsg.NAME, routing) + val header = BbbClientMsgHeader( + UserMutedVoiceEvtMsg.NAME, + meetingId, + vu.intId + ) + + val body = UserMutedVoiceEvtMsgBody( + voiceConf = voiceConf, + intId = vu.intId, + voiceUserId = vu.intId, + vu.muted + ) + + val event = UserMutedVoiceEvtMsg(header, body) + val msgEvent = BbbCommonEnvCoreMsg(envelope, event) + outGW.send(msgEvent) + } + + def handleUserMutedInVoiceConfEvtMsg( + liveMeeting: LiveMeeting, + outGW: OutMsgRouter, + voiceUserId: String, + muted: Boolean + ): Unit = { + for { + mutedUser <- VoiceUsers.userMuted(liveMeeting.voiceUsers, voiceUserId, muted) + } yield { + broadcastUserMutedVoiceEvtMsg( + liveMeeting.props.meetingProp.intId, + mutedUser, + liveMeeting.props.voiceProp.voiceConf, + outGW + ) + } + } + + def processUserStatusVoiceConfEvtMsg( + liveMeeting: LiveMeeting, + outGW: OutMsgRouter, + eventBus: InternalEventBus, + users: Vector[ConfVoiceUser] + ): Unit = { + users foreach { u => + VoiceUsers.findWithVoiceUserId( + liveMeeting.voiceUsers, + u.voiceUserId + ) match { + case Some(vu) => + if (vu.muted != u.muted) { + handleUserMutedInVoiceConfEvtMsg( + liveMeeting, + outGW, + u.voiceUserId, + u.muted + ) + } + // Update the user status to indicate they are stll in the voice conference. + VoiceUsers.setLastStatusUpdate(liveMeeting.voiceUsers, vu) + case None => + handleUserJoinedVoiceConfEvtMsg( + liveMeeting, + outGW, + eventBus, + liveMeeting.props.voiceProp.voiceConf, + u.intId, + u.voiceUserId, + u.callingWith, + u.callerIdName, + u.callerIdNum, + u.muted, + u.talking, + u.calledInto + ) + + // Update this new users status time. + for { + vu <- VoiceUsers.findWithVoiceUserId(liveMeeting.voiceUsers, u.voiceUserId) + } yield { + VoiceUsers.setLastStatusUpdate(liveMeeting.voiceUsers, vu) + } + } + } + + // Remove users that hasn't been updated for the last two minutes as + // these users might have already left. + val twoMinutes = 2 * 60 * 1000 + val now = System.currentTimeMillis() + VoiceUsers.findAllFreeswitchCallers(liveMeeting.voiceUsers) foreach { fsu => + if (now - fsu.lastStatusUpdateOn > twoMinutes) { + handleUserLeftVoiceConfEvtMsg( + liveMeeting, + outGW, + eventBus, + liveMeeting.props.voiceProp.voiceConf, + fsu.voiceUserId + ) + } + } + } + + def handleUserJoinedVoiceConfEvtMsg( + liveMeeting: LiveMeeting, + outGW: OutMsgRouter, + eventBus: InternalEventBus, + voiceConf: String, + intId: String, + voiceUserId: String, + callingWith: String, + callerIdName: String, + callerIdNum: String, + muted: Boolean, + talking: Boolean, + callingInto: String + ): Unit = { + + def broadcastEvent(voiceUserState: VoiceUserState): Unit = { + val routing = Routing.addMsgToClientRouting( + MessageTypes.BROADCAST_TO_MEETING, + liveMeeting.props.meetingProp.intId, + voiceUserState.intId + ) + val envelope = BbbCoreEnvelope( + UserJoinedVoiceConfToClientEvtMsg.NAME, + routing + ) + val header = BbbClientMsgHeader( + UserJoinedVoiceConfToClientEvtMsg.NAME, + liveMeeting.props.meetingProp.intId, + voiceUserState.intId + ) + + val body = UserJoinedVoiceConfToClientEvtMsgBody( + voiceConf, + voiceUserState.intId, + voiceUserState.voiceUserId, + voiceUserState.callerName, + voiceUserState.callerNum, + voiceUserState.muted, + voiceUserState.talking, + voiceUserState.callingWith, + voiceUserState.listenOnly + ) + + val event = UserJoinedVoiceConfToClientEvtMsg( + header, + body + ) + val msgEvent = BbbCommonEnvCoreMsg( + envelope, + event + ) + outGW.send(msgEvent) + } + + val isListenOnly = if (callerIdName.startsWith("LISTENONLY")) true else false + + val voiceUserState = VoiceUserState( + intId, + voiceUserId, + callingWith, + callerIdName, + callerIdNum, + muted, + talking, + listenOnly = isListenOnly, + callingInto, + System.currentTimeMillis() + ) + VoiceUsers.add(liveMeeting.voiceUsers, voiceUserState) + + broadcastEvent(voiceUserState) + + if (liveMeeting.props.meetingProp.isBreakout) { + BreakoutHdlrHelpers.updateParentMeetingWithUsers( + liveMeeting, + eventBus + ) + } + + // if the meeting is muted tell freeswitch to mute the new person + if (!isListenOnly + && MeetingStatus2x.isMeetingMuted(liveMeeting.status)) { + val event = MsgBuilder.buildMuteUserInVoiceConfSysMsg( + liveMeeting.props.meetingProp.intId, + voiceConf, + voiceUserId, + true + ) + outGW.send(event) + } + } + + def handleUserLeftVoiceConfEvtMsg( + liveMeeting: LiveMeeting, + outGW: OutMsgRouter, + eventBus: InternalEventBus, + voiceConf: String, + voiceUserId: String + ): Unit = { + + def broadcastEvent(vu: VoiceUserState): Unit = { + val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, liveMeeting.props.meetingProp.intId, + vu.intId) + val envelope = BbbCoreEnvelope(UserLeftVoiceConfToClientEvtMsg.NAME, routing) + val header = BbbClientMsgHeader(UserLeftVoiceConfToClientEvtMsg.NAME, liveMeeting.props.meetingProp.intId, vu.intId) + + val body = UserLeftVoiceConfToClientEvtMsgBody(voiceConf = voiceConf, intId = vu.intId, voiceUserId = vu.intId) + + val event = UserLeftVoiceConfToClientEvtMsg(header, body) + val msgEvent = BbbCommonEnvCoreMsg(envelope, event) + outGW.send(msgEvent) + } + + for { + user <- VoiceUsers.findWithVoiceUserId(liveMeeting.voiceUsers, voiceUserId) + } yield { + VoiceUsers.removeWithIntId(liveMeeting.voiceUsers, user.intId) + broadcastEvent(user) + } + + if (liveMeeting.props.meetingProp.isBreakout) { + BreakoutHdlrHelpers.updateParentMeetingWithUsers( + liveMeeting, + eventBus + ) + } } } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/RegisteredUsers.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/RegisteredUsers.scala index df9efbbdf6db0a769d6e8c9ecaeb993208dea832..c009167680c03bc19a158c44e716d8fa730ff579 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/RegisteredUsers.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/RegisteredUsers.scala @@ -1,6 +1,5 @@ package org.bigbluebutton.core.models -import org.bigbluebutton.common2.domain.UserVO import com.softwaremill.quicklens._ object RegisteredUsers { diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/VoiceUsers.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/VoiceUsers.scala index f4041b0ac706eba9342309dc7b8238282bf6f47a..2055586d05b06d88c4901032e383853724172b56 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/VoiceUsers.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/VoiceUsers.scala @@ -14,6 +14,8 @@ object VoiceUsers { def findAll(users: VoiceUsers): Vector[VoiceUserState] = users.toVector def findAllNonListenOnlyVoiceUsers(users: VoiceUsers): Vector[VoiceUserState] = users.toVector.filter(u => u.listenOnly == false) + def findAllFreeswitchCallers(users: VoiceUsers): Vector[VoiceUserState] = users.toVector.filter(u => u.calledInto == "freeswitch") + def findAllKurentoCallers(users: VoiceUsers): Vector[VoiceUserState] = users.toVector.filter(u => u.calledInto == "kms") def add(users: VoiceUsers, user: VoiceUserState): Unit = { users.save(user) @@ -74,6 +76,12 @@ object VoiceUsers { vu } } + + def setLastStatusUpdate(users: VoiceUsers, user: VoiceUserState): VoiceUserState = { + val vu = user.copy(lastStatusUpdateOn = System.currentTimeMillis()) + users.save(vu) + vu + } } class VoiceUsers { diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala index 37314f21fe887fb544920bc2b0093687d375cf82..7ab5efb756aefdfebf709eb9131a11a11560fa6c 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala @@ -670,7 +670,7 @@ class MeetingActor( stopRecordingIfAutoStart2x(outGW, liveMeeting, state) if (liveMeeting.props.meetingProp.isBreakout) { - updateParentMeetingWithUsers() + BreakoutHdlrHelpers.updateParentMeetingWithUsers(liveMeeting, eventBus) } if (state.expiryTracker.userHasJoined && diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/AkkaAppsRedisSubscriberActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/AkkaAppsRedisSubscriberActor.scala index 8a8c296bac5ba2153bbf38b2e26b01b49c6beee3..9b3eb27333ad29ba032ebdadb20940a6fec3ee0d 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/AkkaAppsRedisSubscriberActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/AkkaAppsRedisSubscriberActor.scala @@ -1,7 +1,7 @@ package org.bigbluebutton.endpoint.redis import org.bigbluebutton.common2.bus.IncomingJsonMessageBus -import org.bigbluebutton.common2.redis.{ RedisConfig, RedisSubscriber, RedisSubscriberProvider } +import org.bigbluebutton.common2.redis.{ RedisConfig, RedisSubscriberProvider } import akka.actor.ActorSystem import akka.actor.Props diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/RedisRecorderActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/RedisRecorderActor.scala index 936499d4759b49d6edfde4f55fd235d1d35bd8e0..3aee1d95028a9d06a5b26b1a70d17fa0da6a3e8d 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/RedisRecorderActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/RedisRecorderActor.scala @@ -2,7 +2,6 @@ package org.bigbluebutton.endpoint.redis import scala.collection.immutable.StringOps import scala.collection.JavaConverters._ -import org.bigbluebutton.SystemConfiguration import org.bigbluebutton.common2.msgs._ import org.bigbluebutton.common2.redis.{ RedisConfig, RedisStorageProvider } import org.bigbluebutton.core.apps.groupchats.GroupChatApp