服务端

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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package com.jhj.netty.heartbeat;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.timeout.IdleStateHandler;

import java.util.concurrent.TimeUnit;

public class MyServer {

public static void main(String[] args) throws Exception{

EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();

try{

ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup,workerGroup)
.channel(NioServerSocketChannel.class)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer<SocketChannel>() {


@Override
protected void initChannel(SocketChannel ch) throws Exception {

ChannelPipeline pipeline = ch.pipeline();
/*
说明 IdleStateHandler
是netty提供的 空闲状态处理器
参数一 表示多长时间没有读 就会发送一个心跳检测包
参数二 表示多长时间没有写 就会发送一个心跳检测包
参数三 表示多长时间没有读写 就会发送一个心跳检测包

当IdleStateEvent 触发后,就会传递给管道的下一个handler去处理
通过调用下一个handler的userEventTiggered方法 在该方法中处理

*/
pipeline.addLast(new IdleStateHandler(3,5,7, TimeUnit.SECONDS));

//加入一个对空闲检测进一步处理的handler(自定义)
pipeline.addLast(new MyServerHandler());

}
});

//启动服务器
ChannelFuture channelFuture = serverBootstrap.bind(7000).sync();
channelFuture.channel().closeFuture().sync();



}finally {

bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}

服务端handler

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
42
43
44
45
46
47
48
49
package com.jhj.netty.heartbeat;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleStateEvent;

public class MyServerHandler extends ChannelInboundHandlerAdapter {



/**
*
* @param ctx 上下文
* @param evt 事件
* @throws Exception
*/
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {

if (evt instanceof IdleStateEvent){


//将evt向下转型

IdleStateEvent event=(IdleStateEvent) evt;
String eventType=null;

switch (event.state()){

case READER_IDLE:
eventType="读空闲";
break;
case WRITER_IDLE:
eventType="写空闲";
break;
case ALL_IDLE:
eventType="读写空闲";
break;
}

System.out.println(ctx.channel().remoteAddress()+"---超时时间---"+eventType);
System.out.println("服务器做相应处理");

//如果发生空闲 我们关闭通道
ctx.channel().close();
}

}
}

客户端连接上即可

作者声明

1
如有问题,欢迎指正!