心跳设置与钩子

心跳设置与钩子

介绍​

心跳的作用是在长连接中保持通信的活跃状态。

当客户端和服务端建立了长连接后,如果客户端长时间没有向服务器发送消息,服务端通常会断开该长连接。

客户端可以通过定期向服务器发送心跳包来保持连接的活跃状态,以防止被服务器断开。

心跳包是一种空的数据包,通过定期发送心跳包来模拟一次正常的数据传输,从而保证连接的连通性。

游戏对外服的职责之一是保持与用户的长连接,所以心跳相关的会在游戏对外服做设置。

开启心跳机制​

只有游戏对外服需要开启心跳,我们可以在建构游戏对外服时,

将心跳相关的设置添加到 setting 中就可以了,下面这个示例在 idle 方法中演示了心跳整体时间的设置。

code 2,创建 IdleProcessSetting,用于心跳相关的设置。

code 3,心跳整体时间设置,包括 readerIdleTime、writerIdleTime、allIdleTime。

code 5,添加心跳相关设置。

void idle(DefaultExternalCoreSetting setting) { IdleProcessSetting idleProcessSetting = new IdleProcessSetting() .setIdleTime(10); setting.setIdleProcessSetting(idleProcessSetting);}ExternalServer createExternalServer(int externalCorePort) { DefaultExternalServerBuilder builder = ... DefaultExternalCoreSetting setting = builder.setting(); idle(setting); ... return builder.build();}

注意如果开启了心跳机制,需要客户端在一定的时间间隔向服务器发送心跳消息,否则会被断开。

心跳钩子​

IdleHook 心跳钩子接口提供了如下方法

callback 方法,触发了 netty 心跳事件机制的回调方法。

pongBefore 方法,将心跳消息响应给客户端前的回调钩子方法。

框架为 IdleHook 接口提供了一个默认实现类 DefaultSocketIdleHook,使用如下

...void idle(DefaultExternalCoreSetting setting) { IdleProcessSetting idleProcessSetting = new IdleProcessSetting() .setIdleHook(new DefaultSocketIdleHook()); setting.setIdleProcessSetting(idleProcessSetting);}

自定义心跳钩子​

DemoIdleHook 是我们自定义心跳钩子。

code 7,把当前时间戳给到心跳接收端,让客户端时间与服务器同步。

code 12 ~ 14,创建错误消息,并通知客户端触发了心跳事件。

code 16,返回 true 时,表示通知框架将当前用户的连接关闭。

code 21,每秒更新当前时间。

@Slf4jpublic class DemoIdleHook implements SocketIdleHook { volatile byte[] timeBytes; @Override public void pongBefore(BarMessage idleMessage) { idleMessage.setData(timeBytes); } @Override public boolean callback(UserSession userSession, IdleStateEvent event) { BarMessage message = ExternalCodecKit.createErrorIdleMessage(ActionErrorEnum.idleErrorCode); message.setValidatorMsg(ActionErrorEnum.idleErrorCode.getMsg() + " : " + state.name()); userSession.writeAndFlush(message); return true; } public DemoIdleHook() { updateTime(); TaskKit.runInterval(this::updateTime, 1, TimeUnit.SECONDS); } private void updateTime() { LongValue data = LongValue.of(CacheTimeKit.currentTimeMillis()); timeBytes = DataCodecKit.encode(data); }}

Example Source Code​

see https://github.com/iohao/ioGameExamples

path : SimpleExample/example/example-hook

汽车之家 说说看机械师曙光16pro和联想y9000p哪个好?比较区别感觉大吗?
top