private void sendPing()
        {
            // Ping the connection to see if it is alive.
            final JID entity = wsConnection.getStanzaHandler().getAddress();
            final IQ pingRequest = new IQ(IQ.Type.get);
            pingRequest.setChildElement("ping", IQPingHandler.NAMESPACE);
            pingRequest.setFrom(XMPPServer.getInstance().getServerInfo().getXMPPDomain());
            pingRequest.setTo(entity);

            Log.debug("Pinging websocket connection (XMPP address: '{}') that has been idle: {}", entity, wsConnection);

            // OF-1497: Ensure that data sent to the client is processed through LocalClientSession, to avoid
            // synchronisation issues with stanza counts related to Stream Management (XEP-0198)!
            final LocalClientSession ofSession = (LocalClientSession) SessionManager.getInstance().getSession(entity);
            if (ofSession == null) {
                Log.warn( "Trying to ping a websocket connection (XMPP address: '{}') that's idle, but has no corresponding Openfire session. Websocket connection: {}", entity, wsConnection );
            } else {
                try {
                    ofSession.deliver( pingRequest );
                    pendingPingSentAt = Instant.now();
                } catch (UnauthorizedException e) {
                    Log.warn("An unexpected exception occurred while trying to ping a websocket connection (XMPP address: '{}') that's idle. Websocket connection: {}", entity, wsConnection, e);
                }
            }
        }
Task that, on prolonged inactivity, sends an XMPP ping, to ensure that the remote entity is still responsive.
xmppserver/src/main/java/org/jivesoftware/openfire/websocket/WebSocketClientConnectionHandler.java