private void checkForTimedOutUsers()
    {
        for (final OccupantManager.Occupant occupant : occupantManager.getLocalOccupants())
        {
            try
            {
                if (userIdleKick != null && occupant.getLastActive().isBefore(Instant.now().minus(userIdleKick)))
                {
                    // Kick users if 'user_idle' feature is enabled and the user has been idle for too long.
                    tryRemoveOccupantFromRoom(occupant, JiveGlobals.getProperty("admin.mucRoom.timeoutKickReason", "User was inactive for longer than the allowed maximum duration of " + userIdleKick.toString().substring(2).replaceAll("(\\d[HMS])(?!$)", "$1 ").toLowerCase()) + "." );
                }
                else if (userIdlePing != null)
                {
                    // Check if the occupant has been inactive for to long.
                    final Instant lastActive = occupant.getLastActive();
                    final boolean isInactive = lastActive.isBefore(Instant.now().minus(userIdlePing));

                    // Ensure that we didn't quite recently send a ping already.
                    final Instant lastPing = occupant.getLastPingRequest();
                    final boolean isRecentlyPinged = lastPing != null && lastPing.isAfter(Instant.now().minus(userIdlePing));

                    if (isInactive && !isRecentlyPinged) {
                        // Ping the user if it hasn't been kicked already, the feature is enabled, and the user has been idle for too long.
                        pingOccupant(occupant);
                    }
                }
            }
            catch (final Throwable e) {
                Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
            }
        }
    }
Iterates over the local occupants of MUC rooms (users connected to the local cluster node), to determine if an
action needs to be taken based on their (lack of) activity. Depending on the configuration of Openfire, inactive
users (users that are connected, but have not typed anything) are kicked from the room, and/or are explicitly
asked for a proof of life (connectivity), removing them if this proof is not given.
xmppserver/src/main/java/org/jivesoftware/openfire/muc/spi/MultiUserChatServiceImpl.java