Netty保持心跳

来源:互联网 发布:selpiecity软件下载 编辑:程序博客网 时间:2024/05/14 14:49
Netty保持心跳
在我们使用Netty进行长连接的时候,需要考虑如何去保持心跳。保持心跳有两种方式:一种是每到一定时间服务端发送一条保持心跳的报文给客户端维持长连接,一种是客户端发送一条保持心跳的报文给服务端维持长连接。两者区别就是如果由服务端发送可能会在大规模并发的时候增加服务端的压力,导致服务端异常。在这里我们选择使用客户端发送消息保持长连接。


在Netty中为我提供了一个IdleStateHandler类,使用这个类我们可以指定在一定时间内如果处于空闲状态,就给服务端发送一条消息保持心跳。IdleStateHandler类的构造函数为:

public IdleStateHandler(long readerIdleTime, long writerIdleTime, long allIdleTime,                         TimeUnit unit)


readerIdleTime是指在这个参数指定的时间内若没有发生read事件,则发送一条信息维持心跳。0表示禁用该功能。


writerIdleTime是指在这个参数指定的时间内若没有发生write事件,则发送一条信息维持心跳。0表示禁用该功能。


allIdleTime是指在这个参数指定的时间内若没有发生write或者read事件,则发送一条信息维持心跳。0表示禁用该功能。


TimeUnit是指前面三个变量的时间单位。


使用IdleStateHandler保持心跳,只需要像我们自定义的channelhandler一样,设定好发送心跳消息的时长,加入到channelpipeline就可以了。


public IdleStateHandler(long readerIdleTime, long writerIdleTime, long allIdleTime,                         TimeUnit unit)


完整代码如下:


客户端:

public class TimeClient {public void connect(String host, int port) {EventLoopGroup group = new NioEventLoopGroup();Bootstrap b = new Bootstrap();b.group(group)    .channel(NioSocketChannel.class)    .option(ChannelOption.TCP_NODELAY, true).handler(new ChannelInitializer<SocketChannel>(){@Overrideprotected void initChannel(SocketChannel ch)throws Exception {ChannelPipeline pipeline = ch.pipeline();pipeline.addLast(new IdleStateHandler(0, 0, 10,TimeUnit.SECONDS));pipeline.addLast(new HeartbeatHandler());}});try {ChannelFuture f;f = b.connect(host, port).sync();f.channel().closeFuture().sync();} catch (InterruptedException e) {group.shutdownGracefully();}}    public static void main(String[] args) {   new TimeClient().connect("127.0.0.1", 28080);    }}


自定义channelhandler:


public class TimeClientHandle extends ChannelInboundHandlerAdapter {private byte[] bytes;public TimeClientHandle() {bytes = ("client msg" + System.getProperty("line.separator")).getBytes();}@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {ByteBuf buf = null;buf = Unpooled.buffer(bytes.length);buf.writeBytes(bytes);ctx.writeAndFlush(buf);}@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg)throws Exception {String body = (String) msg;System.out.println("The server reback msg is:" + body);}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)throws Exception {ctx.close();}}


服务端:


public class TimeServer {public void bind(int port) {EventLoopGroup bossGroup = new NioEventLoopGroup();EventLoopGroup workGroup = new NioEventLoopGroup();ServerBootstrap b = new ServerBootstrap();b.group(bossGroup, workGroup)    .channel(NioServerSocketChannel.class)    .option(ChannelOption.SO_BACKLOG, 1024).childHandler(new ChannelInitializer<SocketChannel>(){@Overrideprotected void initChannel(SocketChannel ch)throws Exception {ch.pipeline().addLast(new TimeServerHandle());}});try {ChannelFuture f = b.bind(port).sync();f.channel().closeFuture().sync();} catch (InterruptedException e) {e.printStackTrace();bossGroup.shutdownGracefully();workGroup.shutdownGracefully();}}public static void main(String[] args) {int port = 28080;//String host = "172.16.9.249";new TimeServer().bind(port);}}


自定义channelhandler:


public class TimeServerHandle extends ChannelInboundHandlerAdapter {private int count;@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg)throws Exception {ByteBuf body = (ByteBuf) msg;byte[] bytes = new byte[body.readableBytes()];body.readBytes(bytes);String str = new String(bytes,"Utf-8");System.out.println( "The heartbeat message is:" + str + ",The times is: " + count++ );}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)throws Exception {ctx.close();}}


心跳信息如下:


The heartbeat message is:ping,The times is: 1The heartbeat message is:ping,The times is: 2The heartbeat message is:ping,The times is: 3The heartbeat message is:ping,The times is: 4The heartbeat message is:ping,The times is: 5

 
0 1
原创粉丝点击