java - 使用netty库,服务器无法处理客户端重连场景

标签 java netty

最初能够建立连接。只需关闭连接客户端并尝试再次连接或重新启动客户端即可。连接未建立。它仅创建一次连接。 有人可以帮助我改进它吗?因此,它可以同时处理n个客户端。

bossGroup = new NioEventLoopGroup(1);
    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<SocketChannel>() {
                @Override
                public void initChannel(SocketChannel ch) throws Exception {
                    ChannelPipeline p = ch.pipeline();
                    p.addLast(new DelimiterBasedFrameDecoder(20000, Delimiters.lineDelimiter()));
                    // p.addLast(new StringDecoder());
                    // p.addLast(new StringEncoder());

                    p.addLast(serverHandler);
                }
            });

    // Start the server.
    LOGGER.key("Simulator is opening listen port").low().end();
    ChannelFuture f = b.bind(config.getPort()).sync();
    LOGGER.key("Simulator started listening at port: " + config.getPort()).low().end();


    // Wait until the server socket is closed.
    f.channel().closeFuture().sync();

} finally {
    // Shut down all event loops to terminate all threads.
    LOGGER.key("Shtting down all the thread if anyone is still open.").low().end();
    bossGroup.shutdownGracefully();
    workerGroup.shutdownGracefully();
}

服务器处理程序代码如下:

    public class SimulatorServerHandler extends SimpleChannelInboundHandler<String> {

    private AtomicReference<ChannelHandlerContext> ctxRef = new AtomicReference<ChannelHandlerContext>();
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
    private AtomicInteger seqNum = new AtomicInteger(1);
    private final Configuration configure;

    private ScheduledFuture<?> hbTimerWorker;


    private final int stx = 0x02;
    private final int etx = 0x03;
    private final ILogger LOGGER;
    public int enablePublishFunction = 0;

    public SimulatorServerHandler(Configuration config) {
        this.configure = config;
        //LOGGER = LogFactory.INSTANCE.createLogger();
        LOGGER = new LogFactory().createLogger("SIM SERVER");

    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        ctxRef.set(ctx);
        enablePublishFunction =1;
//      System.out.println("Connected!");
        LOGGER.low().key("Gateway connected to the Simulator ").end();
        startHBTimer();

    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        ctx.fireChannelInactive();
        hbTimerWorker.cancel(false);
        enablePublishFunction =0;
        LOGGER.low().key("Gateway disconnected from the Simulator ").end();
    }

    @Override
    public void channelRead0(ChannelHandlerContext ctx, String request) {
        // Generate and write a response.
        String response;
        boolean close = false;
 /*       if (request.isEmpty()) {
            response = "Please type something.\r\n";
        } else if ("bye".equals(request.toLowerCase())) {
            response = "Have a good day!\r\n";
            close = true;
        } else {
            response = "Did you say '" + request + "'?\r\n";
        }

        // We do not need to write a ChannelBuffer here.
        // We know the encoder inserted at TelnetPipelineFactory will do the conversion.
        ChannelFuture future = ctx.write(response);

        // Close the connection after sending 'Have a good day!'
        // if the client has sent 'bye'.
        if (close) {
            future.addListener(ChannelFutureListener.CLOSE);
        }
        */
        System.out.println(request);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        LOGGER.key("Unknown exception while network communication :"+ cause.getStackTrace()).high().end();
        cause.printStackTrace();
        ctx.close();
    }

最佳答案

也许是因为您在管道中始终对所有连接使用完全相同的服务器处理程序(不使用 new ServerHandler())?实现中的副作用可能会阻止您的处理程序可重用。

关于java - 使用netty库,服务器无法处理客户端重连场景,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31613006/

相关文章:

java - 包含 ListView 的选项卡 fragment 在第二次被选中时为空白

java - 如何解决java.lang.NoClassDefFoundError : javax/annotation/Generated?

java - 为什么这个 boolean 比较不能正常工作?

java - Netty SimpleChannelInboundHandler 关闭 channel

java - ChannelInboundMessageHandlerAdapter 找不到符号

java - 如何编写HttpChunkedInput/ChunkedStream?

java - 如何在不刷新整个 Pane 的情况下附加到 JEditorPane?

java - 我可以将二进制文件添加到基于字符串的服务器消息队列吗?

java - 使用 Netty 提供文件 - 响应被截断一个字节

java - Hadoop 可写 readFields EOFException