@Override
        public void run() {
            if (!isWebSocketOpen()) {
                TaskEngine.getInstance().cancelScheduledTask(websocketFramePingTask);
                TaskEngine.getInstance().cancelScheduledTask(xmppSessionIdleTask);
            } else if (KEEP_ALIVE_FRAME_PING_ENABLED_PROPERTY.getValue()) {
                // Send a ping when the line has been inactive for more than 90% of the maximum allowable duration.
                final Duration inactive = Duration.between(lastReceived, Instant.now());
                final Duration sinceLastPing = Duration.between(lastWebsocketPing, Instant.now());
                final Duration shortest = inactive.compareTo(sinceLastPing) > 0 ? sinceLastPing : inactive;
                final Duration maxIdleTime = KEEP_ALIVE_FRAME_PING_INTERVAL_PROPERTY.getValue().dividedBy(10).multipliedBy(9);
                if (shortest.compareTo(maxIdleTime) > 0) {
                    try {
                        Log.trace("Remote peer was inactive for {}. Sending websocket ping to: {}", shortest, wsConnection);
                        // see https://tools.ietf.org/html/rfc6455#section-5.5.2
                        wsSession.getRemote().sendPing(null);
                        lastWebsocketPing = Instant.now();
                    } catch (IOException ioe) {
                        // Log the issue, but no need to act: IdleTask will eventually clean up this websocket.
                        Log.warn("Unable to send websocket ping to remote peer: {}", wsConnection, ioe);
                    }
                }
            }
        }
Task that periodically sends websocket pings, to prevent the websocket transport from being closed.
xmppserver/src/main/java/org/jivesoftware/openfire/websocket/WebSocketClientConnectionHandler.java