Thiết lập phát hiện thời gian chờ đọc/ghi trong máy chủ Netty

Netty là một framework mạng bất đồng bộ, hướng sự kiện, được sử dụng phổ biến để xây dựng các ứng dụng mạng có độ trễ thấp và khả năng xử lý đồng thời cao. Trong thực tế, việc phát hiện thời gian chờ (timeout) khi không có hoạt động đọc hoặc ghi là nhu cầu thiết yếu nhằm kiểm tra tính sống còn của kết nối hoặc xử lý các tình huống bất thường.

Netty cung cấp lớp IdleStateHandler để theo dõi trạng thái rỗi của kênh kết nối, hỗ trợ ba loại thời gian chờ: chỉ đọc, chỉ ghi và cả hai (read/write idle). Khi vượt quá ngưỡng thời gian cấu hình, handler này sẽ kích hoạt sự kiện IdleStateEvent, cho phép ứng dụng phản hồi phù hợp thông qua một ChannelInboundHandler tùy chỉnh.

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.timeout.IdleStateHandler;

public class TimeoutServer {
    public static void main(String[] args) throws InterruptedException {
        EventLoopGroup acceptorGroup = new NioEventLoopGroup(1);
        EventLoopGroup ioGroup = new NioEventLoopGroup();

        try {
            ServerBootstrap server = new ServerBootstrap();
            server.group(acceptorGroup, ioGroup)
                  .channel(NioServerSocketChannel.class)
                  .childHandler(new ChannelInitializer<SocketChannel>() {
                      @Override
                      protected void initChannel(SocketChannel ch) {
                          // 8s không đọc, 12s không ghi, 20s không hoạt động cả hai chiều
                          ch.pipeline().addLast(new IdleStateHandler(8, 12, 20));
                          ch.pipeline().addLast(new ConnectionTimeoutHandler());
                      }
                  });

            ChannelFuture bindFuture = server.bind(9090).sync();
            bindFuture.channel().closeFuture().sync();
        } finally {
            acceptorGroup.shutdownGracefully();
            ioGroup.shutdownGracefully();
        }
    }
}

Lớp IdleStateHandler nhận ba tham số (theo đơn vị giây): thời gian chờ đọc (readerIdleTime), thời gian chờ ghi (writerIdleTime) và thời gian chờ tổng (allIdleTime). Khi bất kỳ điều kiện nào được kích hoạt, sự kiện IdleStateEvent sẽ được gửi đến pipeline.

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

public class ConnectionTimeoutHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object event) throws Exception {
        if (event instanceof IdleStateEvent) {
            IdleState state = ((IdleStateEvent) event).state();
            if (state == IdleState.READER_IDLE) {
                System.out.println("Client không gửi dữ liệu trong thời gian dài.");
                ctx.close(); // Đóng kết nối do không đọc được dữ liệu
            } else if (state == IdleState.WRITER_IDLE) {
                System.out.println("Không có dữ liệu được gửi đi trong thời gian dài.");
                // Có thể gửi heartbeat ở đây
            } else if (state == IdleState.ALL_IDLE) {
                System.out.println("Kết nối hoàn toàn không hoạt động.");
                ctx.close();
            }
        } else {
            super.userEventTriggered(ctx, event);
        }
    }
}

Thẻ: Netty Java socket-programming

Đăng vào ngày 10 tháng 10 lúc 12:32