Skip to main content

Heartbeat Settings and Hooks

Introduction

Heartbeat keeps communication active over long connections.

After client and server establish a long connection, if client sends no message for a long time, server usually closes the connection. Client can periodically send heartbeat packets to keep the connection active and avoid disconnection.

Heartbeat packet is an empty packet. Sending it periodically simulates normal data transfer and keeps connectivity. One responsibility of external server is maintaining long user connections, so heartbeat is configured at external-server side.

Example Source Code

see https://github.com/iohao/ionet-examples

path : ionet-cookbook-code

  • MyIdleHook
  • MyExternalServer

Enabling Heartbeat Mechanism

Only external server needs heartbeat enabled. During external-server building, add heartbeat settings to setting. The following example demonstrates overall heartbeat timing in idle.

  • code 4: create IdleProcessSettingBuilder for heartbeat settings.
  • code 5: overall heartbeat times, including readerIdleTime, writerIdleTime, allIdleTime.
  • code 7: add IdleProcessSettingBuilder to external-server builder.
public ExternalServerBuilder builder(int port, ExternalJoinEnum joinEnum) {
var builder = ExternalMapper.builder(port, joinEnum);

var idleProcessSettingBuilder = new IdleProcessSettingBuilder()
.setIdleTime(10);

builder.setIdleProcessSettingBuilder(idleProcessSettingBuilder);

return builder;
}
warning

If heartbeat mechanism is enabled, client must send heartbeat to server within a time interval, otherwise connection will be closed.

Heartbeat Hooks

IdleHook heartbeat interface provides methods:

  • callback: callback method triggered by Netty heartbeat event mechanism.
  • pongBefore: callback hook before heartbeat message is returned to client.

Framework provides default implementation DefaultSocketIdleHook for IdleHook:

public ExternalServerBuilder builder(int port, ExternalJoinEnum joinEnum) {
var idleProcessSettingBuilder = ...;
idleProcessSettingBuilder.setIdleHook(new DefaultSocketIdleHook())
...
}

Custom Heartbeat Hooks

MyIdleHook is our custom heartbeat hook.

  • code 12: pass current timestamp to heartbeat receiver so client and server time can be synchronized.
  • code 17: use default callback; returning true means framework should close current user connection.
  • code 22: update current time once per second.
public class MyIdleHook implements SocketIdleHook {
final DefaultSocketIdleHook defaultSocketIdleHook = new DefaultSocketIdleHook();
/** currentTimeMillis */
volatile byte[] timeBytes;

@Override
public void pongBefore(CommunicationMessage idleMessage) {
/*
* Set the time of the current server so that the time of the client and the server can be synchronized.
* cn: 设置当前服务器的时间,以便客户端与服务器的时间同步。
*/
idleMessage.setData(timeBytes);
}

@Override
public boolean callback(UserSession userSession, IdleStateEvent event) {
return defaultSocketIdleHook.callback(userSession, event);
}

public MyIdleHook() {
updateTime();
TaskKit.runInterval(this::updateTime, 1, TimeUnit.SECONDS);
}

private void updateTime() {
var data = LongValue.of(TimeKit.currentTimeMillis());
timeBytes = DataCodecManager.encode(data);
}
}