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 new file mode 100644 index 0000000000000000000000000000000000000000..43015c26f5f85aa94aa2652f2adca50806717d3a --- /dev/null +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserJoinMeetingAfterReconnectReqMsgHdlr.scala @@ -0,0 +1,34 @@ +package org.bigbluebutton.core.apps.users + +import org.bigbluebutton.common2.msgs.UserJoinMeetingAfterReconnectReqMsg +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.VoiceUsers +import org.bigbluebutton.core.running.{ BaseMeetingActor, HandlerHelpers, LiveMeeting, OutMsgRouter } + +trait UserJoinMeetingAfterReconnectReqMsgHdlr extends HandlerHelpers with BreakoutHdlrHelpers with UserJoinedVoiceConfEvtMsgHdlr { + this: BaseMeetingActor => + + val liveMeeting: LiveMeeting + val outGW: OutMsgRouter + + def handleUserJoinMeetingAfterReconnectReqMsg(msg: UserJoinMeetingAfterReconnectReqMsg, state: MeetingState2x): MeetingState2x = { + val newState = userJoinMeeting(outGW, msg.body.authToken, liveMeeting, state) + + if (liveMeeting.props.meetingProp.isBreakout) { + updateParentMeetingWithUsers() + } + + // recover voice user + for { + vu <- VoiceUsers.recoverVoiceUser(liveMeeting.voiceUsers, msg.body.userId) + } yield { + handleUserJoinedVoiceConfEvtMsg(liveMeeting.props.voiceProp.voiceConf, vu.intId, vu.voiceUserId, vu.callingWith, vu.callerName, vu.callerNum, vu.muted, vu.talking) + } + + 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 28854e5a74e96dc53e3dea5d54a85d57d999eca5..f2b451b3dc3471871554d6d0598ce24bcfdf1ca1 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 @@ -2,6 +2,7 @@ package org.bigbluebutton.core.apps.users import org.bigbluebutton.common2.msgs.UserJoinMeetingReqMsg import org.bigbluebutton.core.apps.breakout.BreakoutHdlrHelpers +import org.bigbluebutton.core.models.VoiceUsers import org.bigbluebutton.core.domain.MeetingState2x import org.bigbluebutton.core.running.{ BaseMeetingActor, HandlerHelpers, LiveMeeting, OutMsgRouter } @@ -18,6 +19,9 @@ trait UserJoinMeetingReqMsgHdlr extends HandlerHelpers with BreakoutHdlrHelpers updateParentMeetingWithUsers() } + // fresh user joined (not due to reconnection). Clear (pop) the cached voice user + VoiceUsers.recoverVoiceUser(liveMeeting.voiceUsers, msg.body.userId) + newState } 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 53b3988cf139d9a50637fcc2bbf9236d2d2dd31a..282999b16d1040aeb33beadff7fc2b2f6faf829a 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 @@ -25,6 +25,10 @@ object VoiceUsers { users.toVector.find(u => u.intId == intId) } + def recoverVoiceUser(users: VoiceUsers, intId: String): Option[VoiceUserState] = { + users.removeFromCache(intId) + } + def userMuted(users: VoiceUsers, voiceUserId: String, muted: Boolean): Option[VoiceUserState] = { for { u <- findWithVoiceUserId(users, voiceUserId) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala index b7c76f69835e10e3a97b018c03458fd3de5fdae7..e986aa1f57b3d77624018c66229099234d02ef03 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala @@ -62,6 +62,8 @@ class ReceivedJsonMsgHandlerActor( route[RegisterUserReqMsg](meetingManagerChannel, envelope, jsonNode) case UserJoinMeetingReqMsg.NAME => routeGenericMsg[UserJoinMeetingReqMsg](envelope, jsonNode) + case UserJoinMeetingAfterReconnectReqMsg.NAME => + routeGenericMsg[UserJoinMeetingAfterReconnectReqMsg](envelope, jsonNode) case GetAllMeetingsReqMsg.NAME => route[GetAllMeetingsReqMsg](meetingManagerChannel, envelope, jsonNode) case DestroyMeetingSysCmdMsg.NAME => 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 bff889698bc5e07f8c5b2742df513036e2865b9b..21714a66cbf3ee781f2686a0f87e4de1964179d1 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 @@ -63,6 +63,7 @@ class MeetingActor( with PermisssionCheck with UserBroadcastCamStartMsgHdlr with UserJoinMeetingReqMsgHdlr + with UserJoinMeetingAfterReconnectReqMsgHdlr with UserBroadcastCamStopMsgHdlr with UserConnectedToGlobalAudioMsgHdlr with UserDisconnectedFromGlobalAudioMsgHdlr @@ -180,6 +181,8 @@ class MeetingActor( state = usersApp.handleValidateAuthTokenReqMsg(m, state) case m: UserJoinMeetingReqMsg => state = handleUserJoinMeetingReqMsg(m, state) + case m: UserJoinMeetingAfterReconnectReqMsg => + state = handleUserJoinMeetingAfterReconnectReqMsg(m, state) case m: UserLeaveReqMsg => state = handleUserLeaveReqMsg(m, state) case m: UserBroadcastCamStartMsg => handleUserBroadcastCamStartMsg(m) diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/UsersMgs.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/UsersMgs.scala index 7734cd1e7f47309e483483c7ddd1b99553c08807..6dbddaa6301225990f86ab5ce6480a6c29a13d00 100755 --- a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/UsersMgs.scala +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/UsersMgs.scala @@ -238,6 +238,14 @@ object UserJoinMeetingReqMsg { val NAME = "UserJoinMeetingReqMsg" } case class UserJoinMeetingReqMsg(header: BbbClientMsgHeader, body: UserJoinMeetingReqMsgBody) extends StandardMsg case class UserJoinMeetingReqMsgBody(userId: String, authToken: String) +/** + * Sent from Flash client to rejoin meeting after reconnection + */ +object UserJoinMeetingAfterReconnectReqMsg { val NAME = "UserJoinMeetingAfterReconnectReqMsg" } +case class UserJoinMeetingAfterReconnectReqMsg(header: BbbClientMsgHeader, body: UserJoinMeetingAfterReconnectReqMsgBody) extends StandardMsg +case class UserJoinMeetingAfterReconnectReqMsgBody(userId: String, authToken: String) + + object UserLeaveReqMsg { val NAME = "UserLeaveReqMsg" } case class UserLeaveReqMsg(header: BbbClientMsgHeader, body: UserLeaveReqMsgBody) extends StandardMsg case class UserLeaveReqMsgBody(userId: String, sessionId: String) diff --git a/bigbluebutton-client/src/org/bigbluebutton/core/events/TokenValidReconnectEvent.as b/bigbluebutton-client/src/org/bigbluebutton/core/events/TokenValidReconnectEvent.as new file mode 100644 index 0000000000000000000000000000000000000000..3ff05da640dc68766fd18c288521cc5d49cb2381 --- /dev/null +++ b/bigbluebutton-client/src/org/bigbluebutton/core/events/TokenValidReconnectEvent.as @@ -0,0 +1,16 @@ +package org.bigbluebutton.core.events +{ +import flash.events.Event; + +public class TokenValidReconnectEvent extends Event +{ + public static const TOKEN_VALID_RECONNECT_EVENT:String = "auth token valid reconnect event"; + + public function TokenValidReconnectEvent() + { + super(TOKEN_VALID_RECONNECT_EVENT, true, false); + } + +} + +} diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/NetConnectionDelegate.as b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/NetConnectionDelegate.as index a25939d158262660efe9e81d95055ca1930a93d2..f28129db21ec5e01eaf4df0855e01eee7f5e30f5 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/NetConnectionDelegate.as +++ b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/NetConnectionDelegate.as @@ -38,6 +38,7 @@ package org.bigbluebutton.main.model.users import org.bigbluebutton.core.connection.messages.ValidateAuthTokenReqMsg; import org.bigbluebutton.core.connection.messages.ValidateAuthTokenReqMsgBody; import org.bigbluebutton.core.events.TokenValidEvent; + import org.bigbluebutton.core.events.TokenValidReconnectEvent; import org.bigbluebutton.core.managers.ReconnectionManager; import org.bigbluebutton.core.model.LiveMeeting; import org.bigbluebutton.core.services.BandwidthMonitor; @@ -137,15 +138,19 @@ package org.bigbluebutton.main.model.users LOGGER.info(JSON.stringify(logData)); if (tokenValid) { - LiveMeeting.inst().me.authTokenValid = true; - if (waitForApproval) { - var waitCommand:BBBEvent = new BBBEvent(BBBEvent.WAITING_FOR_MODERATOR_ACCEPTANCE); - dispatcher.dispatchEvent(waitCommand); + LiveMeeting.inst().me.authTokenValid = true; + if (waitForApproval) { + var waitCommand:BBBEvent = new BBBEvent(BBBEvent.WAITING_FOR_MODERATOR_ACCEPTANCE); + dispatcher.dispatchEvent(waitCommand); + } else { + LiveMeeting.inst().me.waitingForApproval = false; + if (reconnecting) { + dispatcher.dispatchEvent(new TokenValidReconnectEvent()); } else { - LiveMeeting.inst().me.waitingForApproval = false; dispatcher.dispatchEvent(new TokenValidEvent()); - sendConnectionSuccessEvent(userId); } + sendConnectionSuccessEvent(userId); + } } else { dispatcher.dispatchEvent(new InvalidAuthTokenEvent()); } diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/UserService.as b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/UserService.as index d4662156bb81be7c8ebb315665215bac979f87e1..040da18c3cc35c5213fed69721a2472cc7621f9c 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/UserService.as +++ b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/UserService.as @@ -29,6 +29,7 @@ package org.bigbluebutton.main.model.users import org.bigbluebutton.core.UsersUtil; import org.bigbluebutton.core.events.LockControlEvent; import org.bigbluebutton.core.events.TokenValidEvent; + import org.bigbluebutton.core.events.TokenValidReconnectEvent; import org.bigbluebutton.core.events.VoiceConfEvent; import org.bigbluebutton.core.managers.ConnectionManager; import org.bigbluebutton.core.model.LiveMeeting; @@ -148,7 +149,11 @@ package org.bigbluebutton.main.model.users public function tokenValidEventHandler(event: TokenValidEvent): void { sender.joinMeeting(); } - + + public function tokenValidReconnectEventHandler(event: TokenValidReconnectEvent): void { + sender.joinMeetingAfterReconnect(); + } + public function logoutEndMeeting():void{ if (this.isModerator()) { var myUserId: String = UsersUtil.getMyUserID(); @@ -187,6 +192,7 @@ package org.bigbluebutton.main.model.users reconnecting = false; } else { onAllowedToJoin(); + } } diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/users/maps/UsersMainEventMap.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/users/maps/UsersMainEventMap.mxml index 2a67382431576c3e78d11a26678054975b9037b5..610e50e8a3619e71b97bcd2cd730faa981dc10f2 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/users/maps/UsersMainEventMap.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/users/maps/UsersMainEventMap.mxml @@ -27,6 +27,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. import org.bigbluebutton.core.events.LockControlEvent; import org.bigbluebutton.core.events.TokenValidEvent; + import org.bigbluebutton.core.events.TokenValidReconnectEvent; import org.bigbluebutton.core.events.VoiceConfEvent; import org.bigbluebutton.main.events.BBBEvent; import org.bigbluebutton.main.events.BreakoutRoomEvent; @@ -115,7 +116,11 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. <EventHandlers type="{TokenValidEvent.TOKEN_VALID_EVENT}" > <MethodInvoker generator="{UserService}" method="tokenValidEventHandler" arguments="{event}" /> </EventHandlers> - + + <EventHandlers type="{TokenValidReconnectEvent.TOKEN_VALID_RECONNECT_EVENT}" > + <MethodInvoker generator="{UserService}" method="tokenValidReconnectEventHandler" arguments="{event}" /> + </EventHandlers> + <EventHandlers type="{ChangeRoleEvent.CHANGE_ROLE_EVENT}" > <MethodInvoker generator="{UserService}" method="changeRole" arguments="{event}" /> </EventHandlers> diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageSender.as b/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageSender.as index ef7299cfff612f9b2894bbfa1770fe2fe66af356..3c4cc56458addb93ea6fbace0ad1f6c76c281a27 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageSender.as +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageSender.as @@ -73,11 +73,29 @@ package org.bigbluebutton.modules.users.services }, function(status:String):void { // status - On error occurred var logData:Object = UsersUtil.initLogData(); logData.tags = ["apps"]; - logData.message = "Error occurred assigning a presenter."; + logData.message = "Error occurred when user joining."; LOGGER.info(JSON.stringify(logData)); }, JSON.stringify(message)); } - + + public function joinMeetingAfterReconnect(): void { + LOGGER.info("Sending JOIN MEETING AFTER RECONNECT message"); + + var message:Object = { + header: {name: "UserJoinMeetingAfterReconnectReqMsg", meetingId: UsersUtil.getInternalMeetingID(), userId: UsersUtil.getMyUserID()}, + body: {userId: UsersUtil.getMyUserID(), authToken: LiveMeeting.inst().me.authToken} + }; + + var _nc:ConnectionManager = BBB.initConnectionManager(); + _nc.sendMessage2x(function(result:String):void { // On successful result + }, function(status:String):void { // status - On error occurred + var logData:Object = UsersUtil.initLogData(); + logData.tags = ["apps"]; + logData.message = "Error occurred when user joining after reconnect."; + LOGGER.info(JSON.stringify(logData)); + }, JSON.stringify(message)); + } + public function assignPresenter(newPresenterUserId:String, newPresenterName:String, assignedBy:String):void { var message:Object = { header: {name: "AssignPresenterReqMsg", meetingId: UsersUtil.getInternalMeetingID(), userId: UsersUtil.getMyUserID()},