From 722fb707cc4d8f9ec9ad2c9811a7f2d2f9b5c1fe Mon Sep 17 00:00:00 2001 From: Richard Alam <ritzalam@gmail.com> Date: Fri, 23 Apr 2021 21:25:06 +0000 Subject: [PATCH] - fix issue https://github.com/bigbluebutton/bigbluebutton/issues/11358 by having the parent meeting tell the breakout rooms the remaining time. Currently, each room has its own countdown timer which could introduce drifting resulting in breakout rooms ending at different times. --- .../bigbluebutton/core/api/InMessages.scala | 7 ++++++ ...BreakoutTimeRemainingInternalMsgHdlr.scala | 15 ++++++++++++ .../core/running/MeetingActor.scala | 12 ++++++++-- .../SendBreakoutTimeRemainingMsgHdlr.scala | 23 ++++++++++++------- .../SendTimeRemainingUpdateHdlr.scala | 20 ++++------------ .../core2/message/senders/MsgBuilder.scala | 10 ++++++++ 6 files changed, 61 insertions(+), 26 deletions(-) create mode 100755 akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/SendBreakoutTimeRemainingInternalMsgHdlr.scala diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala index 19ef329125..c08cb4ad4a 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala @@ -26,6 +26,13 @@ case class MonitorNumberOfUsersInternalMsg(meetingID: String) extends InMessage */ case class SendTimeRemainingAuditInternalMsg(meetingId: String) extends InMessage +/** + * Parent message sent to breakout rooms to trigger updating clients of meeting time remaining. + * @param meetingId + * @param timeLeftInSec + */ +case class SendBreakoutTimeRemainingInternalMsg(meetingId: String, timeLeftInSec: Long) extends InMessage + case class SendRecordingTimerInternalMsg(meetingId: String) extends InMessage case class ExtendMeetingDuration(meetingId: String, userId: String) extends InMessage diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/SendBreakoutTimeRemainingInternalMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/SendBreakoutTimeRemainingInternalMsgHdlr.scala new file mode 100755 index 0000000000..c3decbbf73 --- /dev/null +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/SendBreakoutTimeRemainingInternalMsgHdlr.scala @@ -0,0 +1,15 @@ +package org.bigbluebutton.core.apps.breakout + +import org.bigbluebutton.core.api.SendBreakoutTimeRemainingInternalMsg +import org.bigbluebutton.core.running.{LiveMeeting, OutMsgRouter} +import org.bigbluebutton.core2.message.senders.MsgBuilder + +trait SendBreakoutTimeRemainingInternalMsgHdlr { + val liveMeeting: LiveMeeting + val outGW: OutMsgRouter + + def handleSendBreakoutTimeRemainingInternalMsg(msg: SendBreakoutTimeRemainingInternalMsg): Unit = { + val event = MsgBuilder.buildMeetingTimeRemainingUpdateEvtMsg(liveMeeting.props.meetingProp.intId, msg.timeLeftInSec.toInt) + outGW.send(event) + } +} 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 adcea570d7..a26f62c541 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 @@ -86,6 +86,7 @@ class MeetingActor( with DestroyMeetingSysCmdMsgHdlr with SendTimeRemainingUpdateHdlr with SendBreakoutTimeRemainingMsgHdlr + with SendBreakoutTimeRemainingInternalMsgHdlr with ChangeLockSettingsInMeetingCmdMsgHdlr with SyncGetMeetingInfoRespMsgHdlr with ClientToServerLatencyTracerMsgHdlr @@ -238,16 +239,23 @@ class MeetingActor( case msg: ExtendMeetingDuration => handleExtendMeetingDuration(msg) case msg: SendTimeRemainingAuditInternalMsg => - state = handleSendTimeRemainingUpdate(msg, state) + if (!liveMeeting.props.meetingProp.isBreakout) { + // Update users of meeting remaining time. + state = handleSendTimeRemainingUpdate(msg, state) + } + + // Update breakout rooms of remaining time state = handleSendBreakoutTimeRemainingMsg(msg, state) case msg: BreakoutRoomCreatedInternalMsg => state = handleBreakoutRoomCreatedInternalMsg(msg, state) case msg: SendBreakoutUsersAuditInternalMsg => handleSendBreakoutUsersUpdateInternalMsg(msg) case msg: BreakoutRoomUsersUpdateInternalMsg => state = handleBreakoutRoomUsersUpdateInternalMsg(msg, state) case msg: EndBreakoutRoomInternalMsg => handleEndBreakoutRoomInternalMsg(msg) case msg: BreakoutRoomEndedInternalMsg => state = handleBreakoutRoomEndedInternalMsg(msg, state) + case msg: SendBreakoutTimeRemainingInternalMsg => + handleSendBreakoutTimeRemainingInternalMsg(msg) // Screenshare - case msg: DeskShareGetDeskShareInfoRequest => handleDeskShareGetDeskShareInfoRequest(msg) + case msg: DeskShareGetDeskShareInfoRequest => handleDeskShareGetDeskShareInfoRequest(msg) case msg: SendRecordingTimerInternalMsg => state = usersApp.handleSendRecordingTimerInternalMsg(msg, state) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/SendBreakoutTimeRemainingMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/SendBreakoutTimeRemainingMsgHdlr.scala index 7a428f0589..55116e2183 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/SendBreakoutTimeRemainingMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/SendBreakoutTimeRemainingMsgHdlr.scala @@ -1,30 +1,37 @@ package org.bigbluebutton.core2.message.handlers import org.bigbluebutton.common2.msgs._ -import org.bigbluebutton.core.api.SendTimeRemainingAuditInternalMsg +import org.bigbluebutton.core.api.{ EndBreakoutRoomInternalMsg, SendBreakoutTimeRemainingInternalMsg, SendTimeRemainingAuditInternalMsg } +import org.bigbluebutton.core.bus.BigBlueButtonEvent import org.bigbluebutton.core.domain.MeetingState2x -import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter } +import org.bigbluebutton.core.running.{ LiveMeeting, MeetingActor, OutMsgRouter } import org.bigbluebutton.core.util.TimeUtil trait SendBreakoutTimeRemainingMsgHdlr { + this: MeetingActor => + val liveMeeting: LiveMeeting val outGW: OutMsgRouter def handleSendBreakoutTimeRemainingMsg(msg: SendTimeRemainingAuditInternalMsg, state: MeetingState2x): MeetingState2x = { - for { model <- state.breakout startedOn <- model.startedOn } yield { - if (!liveMeeting.props.meetingProp.isBreakout) { - - val endMeetingTime = TimeUtil.millisToSeconds(startedOn) + TimeUtil.minutesToSeconds(model.durationInMinutes) - val timeRemaining = endMeetingTime - TimeUtil.millisToSeconds(System.currentTimeMillis()) + val endMeetingTime = TimeUtil.millisToSeconds(startedOn) + TimeUtil.minutesToSeconds(model.durationInMinutes) + val timeRemaining = endMeetingTime - TimeUtil.millisToSeconds(System.currentTimeMillis()) + if (!liveMeeting.props.meetingProp.isBreakout) { + // Notify parent meeting users of breakout rooms time remaining val event = buildBreakoutRoomsTimeRemainingUpdateEvtMsg(liveMeeting.props.meetingProp.intId, timeRemaining.toInt) - outGW.send(event) } + + // Tell all breakout rooms of time remaining so they can notify their users. + // This syncs all rooms about time remaining. + model.rooms.values.foreach { room => + eventBus.publish(BigBlueButtonEvent(room.id, SendBreakoutTimeRemainingInternalMsg(props.breakoutProps.parentId, timeRemaining.toInt))) + } } state diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/SendTimeRemainingUpdateHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/SendTimeRemainingUpdateHdlr.scala index b79f000b77..e17880b90c 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/SendTimeRemainingUpdateHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/SendTimeRemainingUpdateHdlr.scala @@ -1,10 +1,10 @@ package org.bigbluebutton.core2.message.handlers -import org.bigbluebutton.common2.msgs._ import org.bigbluebutton.core.api.SendTimeRemainingAuditInternalMsg -import org.bigbluebutton.core.domain.{ MeetingState2x } -import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting, OutMsgRouter } +import org.bigbluebutton.core.domain.MeetingState2x +import org.bigbluebutton.core.running.{BaseMeetingActor, LiveMeeting, OutMsgRouter} import org.bigbluebutton.core.util.TimeUtil +import org.bigbluebutton.core2.message.senders.MsgBuilder trait SendTimeRemainingUpdateHdlr { this: BaseMeetingActor => @@ -13,26 +13,14 @@ trait SendTimeRemainingUpdateHdlr { val outGW: OutMsgRouter def handleSendTimeRemainingUpdate(msg: SendTimeRemainingAuditInternalMsg, state: MeetingState2x): MeetingState2x = { - if (state.expiryTracker.durationInMs > 0) { val endMeetingTime = state.expiryTracker.endMeetingTime() val timeRemaining = TimeUtil.millisToSeconds(endMeetingTime - TimeUtil.timeNowInMs()) - def buildMeetingTimeRemainingUpdateEvtMsg(meetingId: String, timeLeftInSec: Long): BbbCommonEnvCoreMsg = { - val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, "not-used") - val envelope = BbbCoreEnvelope(MeetingTimeRemainingUpdateEvtMsg.NAME, routing) - val body = MeetingTimeRemainingUpdateEvtMsgBody(timeLeftInSec) - val header = BbbClientMsgHeader(MeetingTimeRemainingUpdateEvtMsg.NAME, meetingId, "not-used") - val event = MeetingTimeRemainingUpdateEvtMsg(header, body) - - BbbCommonEnvCoreMsg(envelope, event) - } - if (timeRemaining > 0) { - val event = buildMeetingTimeRemainingUpdateEvtMsg(liveMeeting.props.meetingProp.intId, timeRemaining.toInt) + val event = MsgBuilder.buildMeetingTimeRemainingUpdateEvtMsg(liveMeeting.props.meetingProp.intId, timeRemaining.toInt) outGW.send(event) } - } state diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/MsgBuilder.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/MsgBuilder.scala index 1104852f6d..93c7a550ca 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/MsgBuilder.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/MsgBuilder.scala @@ -494,4 +494,14 @@ object MsgBuilder { BbbCommonEnvCoreMsg(envelope, event) } + + def buildMeetingTimeRemainingUpdateEvtMsg(meetingId: String, timeLeftInSec: Long): BbbCommonEnvCoreMsg = { + val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, "not-used") + val envelope = BbbCoreEnvelope(MeetingTimeRemainingUpdateEvtMsg.NAME, routing) + val body = MeetingTimeRemainingUpdateEvtMsgBody(timeLeftInSec) + val header = BbbClientMsgHeader(MeetingTimeRemainingUpdateEvtMsg.NAME, meetingId, "not-used") + val event = MeetingTimeRemainingUpdateEvtMsg(header, body) + + BbbCommonEnvCoreMsg(envelope, event) + } } -- GitLab