package org.f1x.v1; import org.f1x.api.session.SessionStatus; import org.gflogger.GFLog; import org.gflogger.GFLogFactory; import java.util.TimerTask; /** Timer responsible for sending HEARTBEATs from our side, and TEST request of we do not receive HEARTBEATs from other side */ final class SessionMonitoringTask extends TimerTask { private static final GFLog LOGGER = GFLogFactory.getLog(SessionMonitoringTask.class); private final FixCommunicator communicator; private final int heartbeatInterval; public SessionMonitoringTask(FixCommunicator communicator) { this.communicator = communicator; heartbeatInterval = communicator.getSettings().getHeartBeatIntervalSec() * 1000; } @Override public void run() { final long currentTime = communicator.timeSource.currentTimeMillis(); if (communicator.getSessionStatus() == SessionStatus.ApplicationConnected) checkInbound(currentTime); if (communicator.getSessionStatus() == SessionStatus.ApplicationConnected) checkOutbound(currentTime); } /** Check when we received last message from other side (send TEST if that happen long time ago) */ private void checkInbound(long currentTime) { long lastReceivedMessageTimestamp = communicator.getSessionState().getLastReceivedMessageTimestamp(); if (lastReceivedMessageTimestamp < currentTime - heartbeatInterval) { LOGGER.debug().append("Haven't heard from the other side for a while. Sending TEST(1) message to validate connection.").commit(); try { //TODO: Other than sending Test request we need to add a logic that will force socket disconnect if we don't hear back communicator.sendTestRequest("Are you there?"); } catch (Throwable e) { LOGGER.warn().append("Error sending TEST(1):").append(e).commit(); } } } /** Check when we sent last message to other side (send HEARTBEAT if that happened long time ago) */ private void checkOutbound(long currentTime) { long lastSentMessageTimestamp = communicator.getSessionState().getLastSentMessageTimestamp(); if (lastSentMessageTimestamp < currentTime - heartbeatInterval) { LOGGER.debug().append("Connection is idle. Sending HEARTBEAT(0) to confirm connection.").commit(); try { communicator.sendHeartbeat(null); } catch (Throwable e) { LOGGER.warn().append("Error sending HEARTBEAT(0):").append(e).commit(); } } } }