java通过netty实现心跳机制_Netty4服务端心跳机制

本文介绍了如何在Netty4中实现心跳机制,重点讲解了IdleStateHandler的使用,包括参数配置和心跳超时事件的处理。通过设置readerIdleTime参数,当服务器在指定时间内未接收到客户端消息时,触发读超时并关闭连接。客户端主动断开或超过总超时时间也会触发相应处理。
摘要由CSDN通过智能技术生成

Netty4与Netty3.x的心跳机制略有不同,在Netty4中已经去掉了IdleStateAwareChannelHandler这个类,但IdleStateHandler依旧保留,只是心跳超时的触发事件的写法略有不同,Netty底层实现了一套类似信号和槽的事件通信机制。

这里且看实现。

首先是在 SocketChannel.pipeline 中注册 IdleStateHandler 进行心跳时间的定制:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

// Configure the server.

EventLoopGroup bossGroup = new NioEventLoopGroup(1);

EventLoopGroup workerGroup = new NioEventLoopGroup();

try {

ServerBootstrap b = new ServerBootstrap();

b.group(bossGroup, workerGroup)

.channel(NioServerSocketChannel.class)

.option(ChannelOption.SO_BACKLOG, 100)

.handler(new LoggingHandler(LogLevel.INFO))

.childHandler(new ChannelInitializer() {

@Override

public void initChannel(SocketChannel ch)

throwsException{

ch.pipeline()

.addLast(

new LoggingHandler(LogLevel.INFO),

new IdleStateHandler(30,0,0),// 心跳控制

new ServerHandler());

}

});

// Start the server.

ChannelFuture f = b.bind(port).sync();

// Wait until the server socket is closed.

f.channel().closeFuture().sync();

} catch (InterruptedExceptione) {

e.printStackTrace();

} finally {

// Shut down all event loops to terminate all threads.

bossGroup.shutdownGracefully();

workerGroup.shutdownGracefully();

}

这里要注意IdleStateHandler()要放在ServerHandler()的前面,否则心跳管理无法触发ServerHandler中的userEventTriggered()方法。

此时已经成功在服务器中创建了心跳控制器:

IdleStateHandler(int readerIdleTimeSeconds, int writerIdleTimeSeconds, int allIdleTimeSeconds)

Property

Meaning

readerIdleTime

anIdleStateEventwhose state isIdleState.READER_IDLEwill be triggered when no read was performed for the specified period of time. Specify 0to disable.

writerIdleTime

anIdleStateEventwhose state isIdleState.WRITER_IDLEwill be triggered when no write was performed for the specified period of time. Specify 0 to disable.

allIdleTime

anIdleStateEventwhose state isIdleState.ALL_IDLEwill be triggered when neither read nor write was performed for the specified period of time. Specify 0 to disable.

这里readerIdleTime为读超时时间(即服务器一定时间内未接受到客户端消息)

writerIdleTime为写超时时间(即服务器一定时间内向客户端发送消息)

allIdleTime为全体超时时间(即同时没有读写的时间)

对于以上几种Time的使用根据用户自己的需求来决定。这里我们作为验证客户端心跳的机制,只需要设置readerIdleTime这一个参数就够了。

接下来我们需要在ServerHandler中实现其继承自ChannelInboundHandlerAdapter的userEventTriggered()方法来做心跳超时事件的触发实现,代码如下

ServerHandler.java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

public class ServerHandler extends ChannelInboundHandlerAdapter {

...

@Override

public void channelRead(ChannelHandlerContext ctx,Objectmsg)

throwsException{

...

}

...

@Override

public void userEventTriggered(ChannelHandlerContext ctx,Objectevt)

throwsException{

/*心跳处理*/

if (evt instanceof IdleStateEvent) {

IdleStateEvent event = (IdleStateEvent) evt;

if (event.state() == IdleState.READER_IDLE) {

/*读超时*/

System.out.println("READER_IDLE 读超时");

ctx.disconnect();

} else if (event.state() == IdleState.WRITER_IDLE) {

/*写超时*/

System.out.println("WRITER_IDLE 写超时");

} else if (event.state() == IdleState.ALL_IDLE) {

/*总超时*/

System.out.println("ALL_IDLE 总超时");

}

}

}

}

@Override

public void channelInactive(ChannelHandlerContext ctx) throwsException{

// 这里加入玩家的掉线处理

ctx.close();

}

...

通过对IdleStateEvent的判断即可分别实现不同超时情况的处理,这里我们针对的是READER_IDLE的超时判断,因此在其判断成功后执行ctx.disconnect(),即关闭客户端连接。

此时会触发channelInactive()方法,我们将玩家的断线处理如保存玩家信息等内容写在channelInactive()中即可。

客户端主动断开的连接同理,均会触发其Channel所属的Handler中的channelInactive()方法。

以上即实现了一套简单的服务器心跳机制,只要保证客户端在每单位时间(这里设置的是30秒)发送一次消息给服务器即可保证其不被踢下线。

本篇到此,欢迎大家提出更优化的心跳机制实现方案。

谢谢关注。

转自:BeiTown's Coder 编码之源http://coder.beitown.com/archives/1180

这里也可以参考:http://blog.csdn.net/educast/article/details/47706863

评论

暂无评论!

昵  称:

验证码:

4f96344cc48b4d7539e9f6b20c417ca2.png

内  容:

打赏

a2c3384bccd01f4b2df8fd6b27cd6c10.png

微信扫一扫,打赏一下~

关注公众号

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值