Heartbeat detection scenarios: between nodes within a cluster and each node senses whether the survival of each other.
- Why heartbeat? netty not provide a callback method to disconnect it?
In the scenario of the app, open the phone if the flight mode or forced shutdown, the server is not aware tcp long connection is closed, this time you need server sends a heartbeat packet to the client to detect whether the connection has been disconnected.
netty addition to providing a variety of codecs, Handler also provides a variety of processors, such as the idle stateIdleStateHandler
Service-side implementation
/** * Created by fubin on 2019/7/13. */ public class BeartBeatServer { public static void main(String[] args) { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try{ ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(bossGroup,workerGroup) .channel(NioServerSocketChannel.class) //增加日志handler .handler(new LoggingHandler(LogLevel.INFO)) .childHandler(new HeartBeatInitializer()); ChannelFuture channelFuture = serverBootstrap.bind(8899).sync(); channelFuture.channel().closeFuture().sync(); } catch (InterruptedException e) { e.printStackTrace (); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } } class HeartBeatInitializer extends ChannelInitializer<SocketChannel> { protected void initChannel(SocketChannel socketChannel) throws Exception { The ChannelPipeline the ChannelPipeline = socketChannel.pipeline (); // Netty also provides a variety of processors, such as the idle detection Handler channelPipeline.addLast ( new new IdleStateHandler (5,7,10 , TimeUnit.SECONDS)); channelPipeline.addLast(new HeartBeatHandler()); } } class HeartBeatHandler extends ChannelInboundHandlerAdapter { @Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { IdleStateEvent event = (IdleStateEvent)evt; String eventType = null; switch (event.state()){ case READER_IDLE: eventType = "读空闲"; break; case WRITER_IDLE: eventType = "write idle" ; BREAK ; Case ALL_IDLE: the eventType = "Idle reader" ; BREAK ; } System.out.println(ctx.channel().remoteAddress() + "超时事件:" + eventType); ctx.channel().close(); } }
Client implementation
client client code can be a netty socket services on the use of chat programs
Netty heartbeat core Handler IdleStateHandler
API for explanation
When a Channel is not performing a read, write or both did not execute, it will trigger a IdleStateEvent event.
Supported idle idle
state
Attributes | meaning |
---|---|
readerIdleTime | A IdleStateEvent status of IdleState.READER_IDLE events will trigger a read operation is not performed within a specified period, specify 0 to disable |
writerIdleTime | A IdleStateEvent status of IdleState.WRITE_IDLE events will trigger a write operation is disabled is not performed within a specified period, specify 0 |
allIdleTime | A IdleStateEvent status of IdleState.ALL_IDLE event will trigger the implementation of read and write operations are not disabled when the specified period, specify 0 |
// example of transmitting the ping message at 30 seconds without flow out of the stack // When 60 seconds was not pushed off the flow connection class MyChannelInitializer the extends ChannelInitializer <Channel> { @Override protected void initChannel(Channel ch) { ch.pipeline().addLast("idleStateHandler",new IdleStateHandler(60,30,0)); ch.pipeline().addLast("myHandler",null); } } class MyHandler extends ChannelDuplexHandler{ @Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { if(evt instanceof IdleStateEvent){ IdleStateEvent e = (IdleStateEvent)evt; if(e.state() == IdleState.READER_IDLE){ ctx.close(); }else if(e.state() == IdleState.WRITER_IDLE){ ctx.writeAndFlush ( "write idle!" ); } } } } //server main ServerBootstrap bootstrap = ...; bootstrap.childHandler(new MyChannelInitializer());