Merge pull request #12342 from gustavotrott/user-inactivity-fix
Fix: Eject user from meeting after inactivity warning timeout
This commit is contained in:
commit
b29d5884e4
@ -68,7 +68,13 @@ object Users2x {
|
||||
}
|
||||
|
||||
def updateLastUserActivity(users: Users2x, u: UserState): UserState = {
|
||||
val newUserState = modify(u)(_.lastActivityTime).setTo(TimeUtil.timeNowInMs())
|
||||
val newUserState = modify(u)(_.lastActivityTime).setTo(System.currentTimeMillis())
|
||||
users.save(newUserState)
|
||||
newUserState
|
||||
}
|
||||
|
||||
def updateLastInactivityInspect(users: Users2x, u: UserState): UserState = {
|
||||
val newUserState = modify(u)(_.lastInactivityInspect).setTo(System.currentTimeMillis())
|
||||
users.save(newUserState)
|
||||
newUserState
|
||||
}
|
||||
@ -257,21 +263,22 @@ case class OldPresenter(userId: String, changedPresenterOn: Long)
|
||||
case class UserLeftFlag(left: Boolean, leftOn: Long)
|
||||
|
||||
case class UserState(
|
||||
intId: String,
|
||||
extId: String,
|
||||
name: String,
|
||||
role: String,
|
||||
guest: Boolean,
|
||||
authed: Boolean,
|
||||
guestStatus: String,
|
||||
emoji: String,
|
||||
locked: Boolean,
|
||||
presenter: Boolean,
|
||||
avatar: String,
|
||||
roleChangedOn: Long = System.currentTimeMillis(),
|
||||
lastActivityTime: Long = TimeUtil.timeNowInMs(),
|
||||
clientType: String,
|
||||
userLeftFlag: UserLeftFlag
|
||||
intId: String,
|
||||
extId: String,
|
||||
name: String,
|
||||
role: String,
|
||||
guest: Boolean,
|
||||
authed: Boolean,
|
||||
guestStatus: String,
|
||||
emoji: String,
|
||||
locked: Boolean,
|
||||
presenter: Boolean,
|
||||
avatar: String,
|
||||
roleChangedOn: Long = System.currentTimeMillis(),
|
||||
lastActivityTime: Long = System.currentTimeMillis(),
|
||||
lastInactivityInspect: Long = 0,
|
||||
clientType: String,
|
||||
userLeftFlag: UserLeftFlag
|
||||
)
|
||||
|
||||
case class UserIdAndName(id: String, name: String)
|
||||
|
@ -1,7 +1,6 @@
|
||||
package org.bigbluebutton.core.running
|
||||
|
||||
import java.io.{ PrintWriter, StringWriter }
|
||||
|
||||
import akka.actor._
|
||||
import akka.actor.SupervisorStrategy.Resume
|
||||
import org.bigbluebutton.SystemConfiguration
|
||||
@ -40,6 +39,7 @@ import org.bigbluebutton.core.apps.meeting.{ SyncGetMeetingInfoRespMsgHdlr, Vali
|
||||
import org.bigbluebutton.core.apps.users.ChangeLockSettingsInMeetingCmdMsgHdlr
|
||||
import org.bigbluebutton.core2.message.senders.{ MsgBuilder, Sender }
|
||||
|
||||
import java.util.concurrent.TimeUnit
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
|
||||
object MeetingActor {
|
||||
@ -298,6 +298,14 @@ class MeetingActor(
|
||||
}
|
||||
}
|
||||
|
||||
private def updateUserLastInactivityInspect(userId: String) {
|
||||
for {
|
||||
user <- Users2x.findWithIntId(liveMeeting.users2x, userId)
|
||||
} yield {
|
||||
Users2x.updateLastInactivityInspect(liveMeeting.users2x, user)
|
||||
}
|
||||
}
|
||||
|
||||
private def handleBbbCommonEnvCoreMsg(msg: BbbCommonEnvCoreMsg): Unit = {
|
||||
msg.core match {
|
||||
case m: ClientToServerLatencyTracerMsg => handleClientToServerLatencyTracerMsg(m)
|
||||
@ -610,7 +618,7 @@ class MeetingActor(
|
||||
var lastRecBreakSentOn = expiryTracker.startedOnInMs
|
||||
|
||||
def setRecordingChapterBreak(): Unit = {
|
||||
val now = TimeUtil.timeNowInMs()
|
||||
val now = System.currentTimeMillis()
|
||||
val elapsedInMs = now - lastRecBreakSentOn
|
||||
val elapsedInMin = TimeUtil.millisToMinutes(elapsedInMs)
|
||||
|
||||
@ -723,34 +731,37 @@ class MeetingActor(
|
||||
}
|
||||
}
|
||||
|
||||
var lastUserInactivityInspectSentOn = TimeUtil.timeNowInMs()
|
||||
var checkInactiveUsers = false
|
||||
var lastUsersInactivityInspection = System.currentTimeMillis()
|
||||
|
||||
def processUserInactivityAudit(): Unit = {
|
||||
val now = TimeUtil.timeNowInMs()
|
||||
|
||||
val now = System.currentTimeMillis()
|
||||
|
||||
// Check if user is inactive. We only do the check is user inactivity
|
||||
// is not disabled (0).
|
||||
if ((expiryTracker.userInactivityInspectTimerInMs > 0) &&
|
||||
(now > lastUserInactivityInspectSentOn + expiryTracker.userInactivityInspectTimerInMs)) {
|
||||
lastUserInactivityInspectSentOn = now
|
||||
checkInactiveUsers = true
|
||||
warnPotentiallyInactiveUsers()
|
||||
}
|
||||
(now > lastUsersInactivityInspection + expiryTracker.userInactivityInspectTimerInMs)) {
|
||||
lastUsersInactivityInspection = now
|
||||
|
||||
if (checkInactiveUsers && now > lastUserInactivityInspectSentOn + expiryTracker.userActivitySignResponseDelayInMs) {
|
||||
checkInactiveUsers = false
|
||||
warnPotentiallyInactiveUsers()
|
||||
disconnectInactiveUsers()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
def warnPotentiallyInactiveUsers(): Unit = {
|
||||
log.info("Checking for inactive users.")
|
||||
val users = Users2x.findAll(liveMeeting.users2x)
|
||||
users foreach { u =>
|
||||
val active = (lastUserInactivityInspectSentOn - expiryTracker.userInactivityThresholdInMs) < u.lastActivityTime
|
||||
if (!active) {
|
||||
Sender.sendUserInactivityInspectMsg(liveMeeting.props.meetingProp.intId, u.intId, TimeUtil.minutesToSeconds(props.durationProps.userActivitySignResponseDelayInMinutes), outGW)
|
||||
val hasActivityAfterWarning = u.lastInactivityInspect < u.lastActivityTime
|
||||
val hasActivityRecently = (lastUsersInactivityInspection - expiryTracker.userInactivityThresholdInMs) < u.lastActivityTime
|
||||
|
||||
if (hasActivityAfterWarning && !hasActivityRecently) {
|
||||
log.info("User has been inactive for " + TimeUnit.MILLISECONDS.toMinutes(expiryTracker.userInactivityThresholdInMs) + " minutes. Sending inactivity warning. meetingId=" + props.meetingProp.intId + " userId=" + u.intId + " user=" + u)
|
||||
|
||||
val secsToDisconnect = TimeUnit.MILLISECONDS.toSeconds(expiryTracker.userActivitySignResponseDelayInMs);
|
||||
Sender.sendUserInactivityInspectMsg(liveMeeting.props.meetingProp.intId, u.intId, secsToDisconnect, outGW)
|
||||
updateUserLastInactivityInspect(u.intId)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -759,8 +770,13 @@ class MeetingActor(
|
||||
log.info("Check for users who haven't responded to user inactivity warning.")
|
||||
val users = Users2x.findAll(liveMeeting.users2x)
|
||||
users foreach { u =>
|
||||
val respondedOnTime = (lastUserInactivityInspectSentOn - expiryTracker.userInactivityThresholdInMs) < u.lastActivityTime && (lastUserInactivityInspectSentOn + expiryTracker.userActivitySignResponseDelayInMs) > u.lastActivityTime
|
||||
if (!respondedOnTime) {
|
||||
val hasInactivityWarningSent = u.lastInactivityInspect != 0
|
||||
val hasActivityAfterWarning = u.lastInactivityInspect < u.lastActivityTime
|
||||
val respondedOnTime = (lastUsersInactivityInspection - expiryTracker.userActivitySignResponseDelayInMs) < u.lastInactivityInspect
|
||||
|
||||
if (hasInactivityWarningSent && !hasActivityAfterWarning && !respondedOnTime) {
|
||||
log.info("User didn't response the inactivity warning within " + TimeUnit.MILLISECONDS.toSeconds(expiryTracker.userActivitySignResponseDelayInMs) + " seconds. Ejecting from meeting. meetingId=" + props.meetingProp.intId + " userId=" + u.intId + " user=" + u)
|
||||
|
||||
UsersApp.ejectUserFromMeeting(
|
||||
outGW,
|
||||
liveMeeting,
|
||||
|
@ -64,6 +64,8 @@ class ActivityCheck extends Component {
|
||||
const { responseDelay } = this.state;
|
||||
|
||||
return setInterval(() => {
|
||||
if(responseDelay == 0) return;
|
||||
|
||||
const remainingTime = responseDelay - 1;
|
||||
|
||||
this.setState({
|
||||
|
Loading…
Reference in New Issue
Block a user