From ffb6d6e5936a2d123dbf67686a5d5cf84d9d11c9 Mon Sep 17 00:00:00 2001 From: Ghazi Triki <ghazi.triki@riadvice.tn> Date: Fri, 27 Jul 2018 19:00:15 +0100 Subject: [PATCH] Update last user activity depending on his actions. --- .../core/running/MeetingActor.scala | 186 ++++++++++-------- .../main/views/MainApplicationShell.mxml | 2 +- .../modules/users/services/MessageReceiver.as | 2 +- 3 files changed, 110 insertions(+), 80 deletions(-) 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 a3b7c67ed9..aa54cde62d 100644 --- 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 @@ -221,15 +221,19 @@ class MeetingActor( state.update(tracker) } - private def updateUserLastUserActivity(userId: String) { + private def updateVoiceUserLastActivity(userId: String) { for { vu <- VoiceUsers.findWithVoiceUserId(liveMeeting.voiceUsers, userId) } yield { - for { - user <- Users2x.findWithIntId(liveMeeting.users2x, vu.intId) - } yield { - Users2x.updateLastUserActivity(liveMeeting.users2x, user) - } + updateUserLastActivity(vu.intId) + } + } + + private def updateUserLastActivity(userId: String) { + for { + user <- Users2x.findWithIntId(liveMeeting.users2x, userId) + } yield { + Users2x.updateLastUserActivity(liveMeeting.users2x, user) } } @@ -252,115 +256,145 @@ class MeetingActor( case m: LogoutAndEndMeetingCmdMsg => usersApp.handleLogoutAndEndMeetingCmdMsg(m, state) case m: SetRecordingStatusCmdMsg => state = usersApp.handleSetRecordingStatusCmdMsg(m, state) + updateVoiceUserLastActivity(m.body.setBy) case m: RecordAndClearPreviousMarkersCmdMsg => state = usersApp.handleRecordAndClearPreviousMarkersCmdMsg(m, state) + updateUserLastActivity(m.body.setBy) case m: GetWebcamsOnlyForModeratorReqMsg => usersApp.handleGetWebcamsOnlyForModeratorReqMsg(m) case m: UpdateWebcamsOnlyForModeratorCmdMsg => usersApp.handleUpdateWebcamsOnlyForModeratorCmdMsg(m) case m: GetRecordingStatusReqMsg => usersApp.handleGetRecordingStatusReqMsg(m) case m: ChangeUserEmojiCmdMsg => handleChangeUserEmojiCmdMsg(m) + // Client requested to eject user - case m: EjectUserFromMeetingCmdMsg => usersApp.handleEjectUserFromMeetingCmdMsg(m) + case m: EjectUserFromMeetingCmdMsg => + usersApp.handleEjectUserFromMeetingCmdMsg(m) + updateUserLastActivity(m.body.ejectedBy) + // Another part of system (e.g. bbb-apps) requested to eject user. - case m: EjectUserFromMeetingSysMsg => usersApp.handleEjectUserFromMeetingSysMsg(m) - case m: GetUsersMeetingReqMsg => usersApp.handleGetUsersMeetingReqMsg(m) - case m: ChangeUserRoleCmdMsg => usersApp.handleChangeUserRoleCmdMsg(m) + case m: EjectUserFromMeetingSysMsg => usersApp.handleEjectUserFromMeetingSysMsg(m) + case m: GetUsersMeetingReqMsg => usersApp.handleGetUsersMeetingReqMsg(m) + case m: ChangeUserRoleCmdMsg => + usersApp.handleChangeUserRoleCmdMsg(m) + updateUserLastActivity(m.body.changedBy) // Whiteboard - case m: SendCursorPositionPubMsg => wbApp.handle(m, liveMeeting, msgBus) - case m: ClearWhiteboardPubMsg => wbApp.handle(m, liveMeeting, msgBus) - case m: UndoWhiteboardPubMsg => wbApp.handle(m, liveMeeting, msgBus) - case m: ModifyWhiteboardAccessPubMsg => wbApp.handle(m, liveMeeting, msgBus) - case m: SendWhiteboardAnnotationPubMsg => wbApp.handle(m, liveMeeting, msgBus) - case m: GetWhiteboardAnnotationsReqMsg => wbApp.handle(m, liveMeeting, msgBus) + case m: SendCursorPositionPubMsg => wbApp.handle(m, liveMeeting, msgBus) + case m: ClearWhiteboardPubMsg => wbApp.handle(m, liveMeeting, msgBus) + case m: UndoWhiteboardPubMsg => wbApp.handle(m, liveMeeting, msgBus) + case m: ModifyWhiteboardAccessPubMsg => wbApp.handle(m, liveMeeting, msgBus) + case m: SendWhiteboardAnnotationPubMsg => wbApp.handle(m, liveMeeting, msgBus) + case m: GetWhiteboardAnnotationsReqMsg => wbApp.handle(m, liveMeeting, msgBus) - case m: ClientToServerLatencyTracerMsg => handleClientToServerLatencyTracerMsg(m) + case m: ClientToServerLatencyTracerMsg => handleClientToServerLatencyTracerMsg(m) // Poll - case m: StartPollReqMsg => pollApp.handle(m, state, liveMeeting, msgBus) // passing state but not modifying it - case m: StartCustomPollReqMsg => pollApp.handle(m, state, liveMeeting, msgBus) // passing state but not modifying it - case m: StopPollReqMsg => pollApp.handle(m, state, liveMeeting, msgBus) // passing state but not modifying it - case m: ShowPollResultReqMsg => pollApp.handle(m, state, liveMeeting, msgBus) // passing state but not modifying it - case m: GetCurrentPollReqMsg => pollApp.handle(m, state, liveMeeting, msgBus) // passing state but not modifying it - case m: RespondToPollReqMsg => pollApp.handle(m, liveMeeting, msgBus) + case m: StartPollReqMsg => + pollApp.handle(m, state, liveMeeting, msgBus) // passing state but not modifying it + updateUserLastActivity(m.body.requesterId) + case m: StartCustomPollReqMsg => + pollApp.handle(m, state, liveMeeting, msgBus) // passing state but not modifying it + updateUserLastActivity(m.body.requesterId) + case m: StopPollReqMsg => + pollApp.handle(m, state, liveMeeting, msgBus) // passing state but not modifying it + updateUserLastActivity(m.body.requesterId) + case m: ShowPollResultReqMsg => + pollApp.handle(m, state, liveMeeting, msgBus) // passing state but not modifying it + updateUserLastActivity(m.body.requesterId) + case m: GetCurrentPollReqMsg => pollApp.handle(m, state, liveMeeting, msgBus) // passing state but not modifying it + case m: RespondToPollReqMsg => + pollApp.handle(m, liveMeeting, msgBus) + updateUserLastActivity(m.body.requesterId) // Breakout - case m: BreakoutRoomsListMsg => state = handleBreakoutRoomsListMsg(m, state) - case m: CreateBreakoutRoomsCmdMsg => state = handleCreateBreakoutRoomsCmdMsg(m, state) - case m: EndAllBreakoutRoomsMsg => state = handleEndAllBreakoutRoomsMsg(m, state) - case m: RequestBreakoutJoinURLReqMsg => state = handleRequestBreakoutJoinURLReqMsg(m, state) - case m: TransferUserToMeetingRequestMsg => state = handleTransferUserToMeetingRequestMsg(m, state) + case m: BreakoutRoomsListMsg => state = handleBreakoutRoomsListMsg(m, state) + case m: CreateBreakoutRoomsCmdMsg => state = handleCreateBreakoutRoomsCmdMsg(m, state) + case m: EndAllBreakoutRoomsMsg => state = handleEndAllBreakoutRoomsMsg(m, state) + case m: RequestBreakoutJoinURLReqMsg => state = handleRequestBreakoutJoinURLReqMsg(m, state) + case m: TransferUserToMeetingRequestMsg => state = handleTransferUserToMeetingRequestMsg(m, state) // Voice - case m: UserLeftVoiceConfEvtMsg => handleUserLeftVoiceConfEvtMsg(m) - case m: UserMutedInVoiceConfEvtMsg => handleUserMutedInVoiceConfEvtMsg(m) + case m: UserLeftVoiceConfEvtMsg => handleUserLeftVoiceConfEvtMsg(m) + case m: UserMutedInVoiceConfEvtMsg => handleUserMutedInVoiceConfEvtMsg(m) case m: UserTalkingInVoiceConfEvtMsg => state = updateInactivityTracker(state) - updateUserLastUserActivity(m.body.voiceUserId) + updateVoiceUserLastActivity(m.body.voiceUserId) handleUserTalkingInVoiceConfEvtMsg(m) case m: RecordingStartedVoiceConfEvtMsg => handleRecordingStartedVoiceConfEvtMsg(m) - case m: MuteUserCmdMsg => usersApp.handleMuteUserCmdMsg(m) - case m: MuteAllExceptPresentersCmdMsg => handleMuteAllExceptPresentersCmdMsg(m) + case m: MuteUserCmdMsg => + usersApp.handleMuteUserCmdMsg(m) + updateUserLastActivity(m.body.mutedBy) + case m: MuteAllExceptPresentersCmdMsg => + handleMuteAllExceptPresentersCmdMsg(m) + updateUserLastActivity(m.body.mutedBy) case m: EjectUserFromVoiceCmdMsg => handleEjectUserFromVoiceCmdMsg(m) - case m: IsMeetingMutedReqMsg => handleIsMeetingMutedReqMsg(m) - case m: MuteMeetingCmdMsg => handleMuteMeetingCmdMsg(m) - case m: UserConnectedToGlobalAudioMsg => handleUserConnectedToGlobalAudioMsg(m) + case m: IsMeetingMutedReqMsg => handleIsMeetingMutedReqMsg(m) + case m: MuteMeetingCmdMsg => + handleMuteMeetingCmdMsg(m) + updateUserLastActivity(m.body.mutedBy) + case m: UserConnectedToGlobalAudioMsg => handleUserConnectedToGlobalAudioMsg(m) case m: UserDisconnectedFromGlobalAudioMsg => handleUserDisconnectedFromGlobalAudioMsg(m) - case m: VoiceConfRunningEvtMsg => handleVoiceConfRunningEvtMsg(m) + case m: VoiceConfRunningEvtMsg => handleVoiceConfRunningEvtMsg(m) // Layout - case m: GetCurrentLayoutReqMsg => handleGetCurrentLayoutReqMsg(m) - case m: BroadcastLayoutMsg => handleBroadcastLayoutMsg(m) + case m: GetCurrentLayoutReqMsg => handleGetCurrentLayoutReqMsg(m) + case m: BroadcastLayoutMsg => handleBroadcastLayoutMsg(m) // Lock Settings - case m: ChangeLockSettingsInMeetingCmdMsg => handleSetLockSettings(m) - case m: LockUserInMeetingCmdMsg => handleLockUserInMeetingCmdMsg(m) - case m: LockUsersInMeetingCmdMsg => handleLockUsersInMeetingCmdMsg(m) - case m: GetLockSettingsReqMsg => handleGetLockSettingsReqMsg(m) + case m: ChangeLockSettingsInMeetingCmdMsg => + handleSetLockSettings(m) + updateUserLastActivity(m.body.setBy) + case m: LockUserInMeetingCmdMsg => handleLockUserInMeetingCmdMsg(m) + case m: LockUsersInMeetingCmdMsg => handleLockUsersInMeetingCmdMsg(m) + case m: GetLockSettingsReqMsg => handleGetLockSettingsReqMsg(m) // Presentation - case m: PreuploadedPresentationsSysPubMsg => presentationApp2x.handle(m, liveMeeting, msgBus) - case m: AssignPresenterReqMsg => state = handlePresenterChange(m, state) + case m: PreuploadedPresentationsSysPubMsg => presentationApp2x.handle(m, liveMeeting, msgBus) + case m: AssignPresenterReqMsg => state = handlePresenterChange(m, state) // Presentation Pods - case m: CreateNewPresentationPodPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) - case m: RemovePresentationPodPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) - case m: GetAllPresentationPodsReqMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) - case m: SetCurrentPresentationPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) + case m: CreateNewPresentationPodPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) + case m: RemovePresentationPodPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) + case m: GetAllPresentationPodsReqMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) + case m: SetCurrentPresentationPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) case m: PresentationConversionCompletedSysPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) - case m: SetCurrentPagePubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) - case m: SetPresenterInPodReqMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) - case m: RemovePresentationPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) - case m: SetPresentationDownloadablePubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) - case m: PresentationConversionUpdateSysPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) - case m: PresentationPageGeneratedSysPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) - case m: PresentationPageCountErrorSysPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) - case m: PresentationUploadTokenReqMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) - case m: ResizeAndMovePagePubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) + case m: SetCurrentPagePubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) + case m: SetPresenterInPodReqMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) + case m: RemovePresentationPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) + case m: SetPresentationDownloadablePubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) + case m: PresentationConversionUpdateSysPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) + case m: PresentationPageGeneratedSysPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) + case m: PresentationPageCountErrorSysPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) + case m: PresentationUploadTokenReqMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) + case m: ResizeAndMovePagePubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) // Caption - case m: EditCaptionHistoryPubMsg => captionApp2x.handle(m, liveMeeting, msgBus) - case m: UpdateCaptionOwnerPubMsg => captionApp2x.handle(m, liveMeeting, msgBus) - case m: SendCaptionHistoryReqMsg => captionApp2x.handle(m, liveMeeting, msgBus) + case m: EditCaptionHistoryPubMsg => captionApp2x.handle(m, liveMeeting, msgBus) + case m: UpdateCaptionOwnerPubMsg => captionApp2x.handle(m, liveMeeting, msgBus) + case m: SendCaptionHistoryReqMsg => captionApp2x.handle(m, liveMeeting, msgBus) // SharedNotes - case m: GetSharedNotesPubMsg => sharedNotesApp2x.handle(m, liveMeeting, msgBus) - case m: SyncSharedNotePubMsg => sharedNotesApp2x.handle(m, liveMeeting, msgBus) - case m: ClearSharedNotePubMsg => sharedNotesApp2x.handle(m, liveMeeting, msgBus) - case m: UpdateSharedNoteReqMsg => sharedNotesApp2x.handle(m, liveMeeting, msgBus) - case m: CreateSharedNoteReqMsg => sharedNotesApp2x.handle(m, liveMeeting, msgBus) - case m: DestroySharedNoteReqMsg => sharedNotesApp2x.handle(m, liveMeeting, msgBus) + case m: GetSharedNotesPubMsg => sharedNotesApp2x.handle(m, liveMeeting, msgBus) + case m: SyncSharedNotePubMsg => sharedNotesApp2x.handle(m, liveMeeting, msgBus) + case m: ClearSharedNotePubMsg => sharedNotesApp2x.handle(m, liveMeeting, msgBus) + case m: UpdateSharedNoteReqMsg => sharedNotesApp2x.handle(m, liveMeeting, msgBus) + case m: CreateSharedNoteReqMsg => sharedNotesApp2x.handle(m, liveMeeting, msgBus) + case m: DestroySharedNoteReqMsg => sharedNotesApp2x.handle(m, liveMeeting, msgBus) // Guests - case m: GetGuestsWaitingApprovalReqMsg => handleGetGuestsWaitingApprovalReqMsg(m) - case m: SetGuestPolicyCmdMsg => handleSetGuestPolicyMsg(m) - case m: GuestsWaitingApprovedMsg => handleGuestsWaitingApprovedMsg(m) - case m: GetGuestPolicyReqMsg => handleGetGuestPolicyReqMsg(m) + case m: GetGuestsWaitingApprovalReqMsg => handleGetGuestsWaitingApprovalReqMsg(m) + case m: SetGuestPolicyCmdMsg => handleSetGuestPolicyMsg(m) + case m: GuestsWaitingApprovedMsg => handleGuestsWaitingApprovedMsg(m) + case m: GetGuestPolicyReqMsg => handleGetGuestPolicyReqMsg(m) // Chat - case m: GetChatHistoryReqMsg => chatApp2x.handle(m, liveMeeting, msgBus) - case m: SendPublicMessagePubMsg => chatApp2x.handle(m, liveMeeting, msgBus) - case m: SendPrivateMessagePubMsg => chatApp2x.handle(m, liveMeeting, msgBus) + case m: GetChatHistoryReqMsg => chatApp2x.handle(m, liveMeeting, msgBus) + case m: SendPublicMessagePubMsg => + chatApp2x.handle(m, liveMeeting, msgBus) + updateUserLastActivity(m.body.message.fromUserId) + case m: SendPrivateMessagePubMsg => + chatApp2x.handle(m, liveMeeting, msgBus) + updateUserLastActivity(m.body.message.fromUserId) case m: ClearPublicChatHistoryPubMsg => state = chatApp2x.handle(m, state, liveMeeting, msgBus) // Screenshare @@ -579,24 +613,20 @@ class MeetingActor( } def warnPotentiallyInactiveUsers(): Unit = { - log.debug("### WARNING USERS") val users = Users2x.findAll(liveMeeting.users2x) users foreach { u => val active = (lastUserInactivityInspectSentOn - expiryTracker.userInactivityThresholdInMs) < u.lastActivityTime if (!active) { - log.debug("$$$ WARNING USER {}", u.intId) Sender.sendUserInactivityInspectMsg(liveMeeting.props.meetingProp.intId, u.intId, TimeUtil.minutesToSeconds(props.durationProps.userActivitySignResponseDelayInMinutes), outGW) } } } def disconnectInactiveUsers(): Unit = { - log.debug("### DISCONNECTING USERS") val users = Users2x.findAll(liveMeeting.users2x) users foreach { u => val respondedOntIme = (lastUserInactivityInspectSentOn - expiryTracker.userInactivityThresholdInMs) < u.lastActivityTime && (lastUserInactivityInspectSentOn + expiryTracker.userActivitySignResponseDelayInMs) > u.lastActivityTime if (!respondedOntIme) { - log.debug("$$$ INACTIVE USER {}", u.intId) UsersApp.ejectUserFromMeeting(outGW, liveMeeting, u.intId, SystemUser.ID, "User inactive for too long.", EjectReasonCode.USER_INACTIVITY) Sender.sendDisconnectClientSysMsg(liveMeeting.props.meetingProp.intId, u.intId, SystemUser.ID, EjectReasonCode.USER_INACTIVITY, outGW) } diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/MainApplicationShell.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/MainApplicationShell.mxml index 7f144cd843..723348358c 100644 --- a/bigbluebutton-client/src/org/bigbluebutton/main/views/MainApplicationShell.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/MainApplicationShell.mxml @@ -503,7 +503,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. private function handleUserInactivityInspectEvent(e:BBBEvent):void { var inactivityWarning:UserInactivityWindow = PopUpUtil.createModalPopUp(FlexGlobals.topLevelApplication as DisplayObject, UserInactivityWindow, true) as UserInactivityWindow; - inactivityWarning.duration = e.payload.duration; + inactivityWarning.duration = e.payload.responseDelay; } private function handleInactivityWarningEvent(e:BBBEvent):void { diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageReceiver.as b/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageReceiver.as index a88505cdb4..c069bac3c7 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageReceiver.as +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageReceiver.as @@ -235,7 +235,7 @@ package org.bigbluebutton.modules.users.services var body: Object = msg.body as Object; var bbbEvent:BBBEvent = new BBBEvent(BBBEvent.USER_INACTIVITY_INSPECT_EVENT); - bbbEvent.payload.duration = body.responseDuration as Number; + bbbEvent.payload.responseDelay = body.responseDelay as Number; globalDispatcher.dispatchEvent(bbbEvent); } -- GitLab