Протокол Heartbeat, написанный на Java, работающий через UDP.
Протокол Heartbeat построен на непрерывном уведомлении о датаграмме UDP с задержкой в 1000 миллисекунд. Поле полезных данных содержит идентификатор идентификатора от клиента, который может состоять из строки, например MAC-адреса сетевых карт, используемых в данный момент источником проверки связи, или идентификатора, например имени пользователя. Сервер будет прослушивать различные пинги, сортируя их по идентификатору и управляя различными состояниями, которые они определят сами. Всякий раз, когда сервер заметит, что после задержки в 3000 миллисекунд не получен ни один пинг от клиента, он уведомит через событие пользователя этого протокола о вероятной потере соединения, посоветовав ограничить или остановить обмен данными через любое другое соединение- зависимый протокол, такой как TCP. Если в течение 5000 миллисекунд вы получите этот идентификатор, клиент снова подключится, а это значит, что канал передачи данных можно восстановить. В противном случае клиент будет считаться полностью оффлайн. Обо всем этом будет сообщено, как указано выше, через систему управления событиями, как показано ниже:
@ Override
public void onHeartbeat ( HeartbeatEvent event ) {
LOGGER . log ( Level . INFO , () -> "Received heartbeat from " + event . getSource () + " in " + event . getTimeFromPreviousBeat () + " at " + event . getBeatTimeStamp ());
}
@ Override
public void onDeath ( HeartbeatEvent event ) {
LOGGER . log ( Level . INFO , () -> event . getSource () + " died after " + event . getTimeFromPreviousBeat () + " at " + event . getBeatTimeStamp ());
}
@ Override
public void onLossCommunication ( HeartbeatEvent event ) {
LOGGER . log ( Level . INFO , () -> "Communication lost of " + event . getSource () + " in " + event . getTimeFromPreviousBeat () + " at " + event . getBeatTimeStamp ());
}
@ Override
public void onReacquiredCommunication ( HeartbeatEvent event ) {
LOGGER . log ( Level . INFO , () -> "Communication reacquired of " + event . getSource () + " in " + event . getTimeFromPreviousBeat () + " at " + event . getBeatTimeStamp ());
}
@ Override
public void onAcquiredCommunication ( HeartbeatEvent event ) {
LOGGER . log ( Level . INFO , () -> event . getSource () + " connected at " + event . getBeatTimeStamp ());
}
В приведенном выше примере кода показан захват различных событий в состояниях клиента. Тогда задача тех, кто реализует прослушиватель, будет принимать решение о том, что делать при захвате событий определенного типа, как показано ниже:
public class ServerStart implements HeartbeatListener {
private static final ServerStart thisInstance = new ServerStart ();
public static void main ( String [] args ) {
HeartbeatProtocolManager heartbeatProtocolManager = new HeartbeatProtocolManager ( thisInstance );
heartbeatProtocolManager . addHost ( "Test" , 43210 ); //identifier, port
heartbeatProtocolManager . addHost ( "Test1" , 43211 );
}
@ Override
public void onHeartbeat ( HeartbeatEvent event ) {
LOGGER . log ( Level . INFO , () -> "Received heartbeat from " + event . getSource () + " in " + event . getTimeFromPreviousBeat () + " at " + event . getBeatTimeStamp ());
}
@ Override
public void onDeath ( HeartbeatEvent event ) {
LOGGER . log ( Level . INFO , () -> event . getSource () + " died after " + event . getTimeFromPreviousBeat () + " at " + event . getBeatTimeStamp ());
}
@ Override
public void onLossCommunication ( HeartbeatEvent event ) {
LOGGER . log ( Level . INFO , () -> "Communication lost of " + event . getSource () + " in " + event . getTimeFromPreviousBeat () + " at " + event . getBeatTimeStamp ());
}
@ Override
public void onReacquiredCommunication ( HeartbeatEvent event ) {
LOGGER . log ( Level . INFO , () -> "Communication reacquired of " + event . getSource () + " in " + event . getTimeFromPreviousBeat () + " at " + event . getBeatTimeStamp ());
}
@ Override
public void onAcquiredCommunication ( HeartbeatEvent event ) {
LOGGER . log ( Level . INFO , () -> event . getSource () + " connected at " + event . getBeatTimeStamp ());
}
}
Сгенерированное событие помимо содержания полезной нагрузки также будет содержать задержку, переданную по отношению к предыдущему, со своим собственным идентификатором полезной нагрузки и меткой времени текущего приема пинга.
Использование этого протокола позволит лучше управлять состоянием соединений между клиентом и сервером и лучше контролировать возможные ошибки.