@Override
        public void run() {
            Log.trace("Running HTTP Session Reaper");

            dispatchQueues.forEach((streamID, future) -> {
                if (!sessionMap.containsKey(streamID.getID())) {
                    if (dispatchQueues.remove(streamID) != null) {
                        Log.warn("Removed scheduled, non-executed task for stream {} for which a session does not (no longer?) exist.", streamID);
                    }
                }
            });

            // Session reaping can cause new events being dispatched. Let's run this reaper _after_ the dispatchQueues
            // have been cleaned, to reduce the chance that both operations act on #dispatchQueues concurrently.
            Instant currentTime = Instant.now();
            for (HttpSession session : sessionMap.values()) {
                try {
                    Duration lastActive = Duration.between(session.getLastActivity(), currentTime);
                    String hostAddress = session.getConnection() != null ? session.getConnection().getHostAddress() : "(not available)";
                    if( !lastActive.isNegative() && !lastActive.isZero() && HttpBindManager.LOG_HTTPBIND_ENABLED.getValue()) {
                        Log.info("Session {} was last active {} ago: {} from IP {} " +
                                " currently on rid {}",
                                session.getStreamID(),
                                lastActive,
                                session.getAddress(), // JID
                                hostAddress,
                                session.getLastAcknowledged()); // RID
                    }
                    if (lastActive.compareTo(session.getInactivityTimeout()) > 0) {
                        Log.info("Closing idle session {}: {} from IP {}",
                                session.getStreamID(),
                                session.getAddress(),
                                hostAddress);
                        session.close();
                    }
                } catch (Exception e) {
                    Log.error("Failed to determine idle state for session: {}", session, e);
                }
            }
        }
Period of time a polling session has to be idle to be closed. Default is 60 seconds. Sending stanzas to the
client is not considered as activity. We are only considering the connection active when the
client sends some data or heartbeats (i.e. whitespaces) to the server. The reason for this is
that sending data will fail if the connection is closed. And if the thread is blocked while
sending data (because the socket is closed) then the clean up thread will close the socket
anyway.
xmppserver/src/main/java/org/jivesoftware/openfire/http/HttpSessionManager.java