Netty closeFuture().sync().channel();块休息 api

Netty closeFuture().sync().channel(); blocks rest api

我正在学习 Netty,并开始使用 spring 启动一些教程。我的目标是创建一个应用程序,它设置一个 tcp 端口来接收消息并在休息时呈现它们 api。

大多数教程都说我应该添加这样的内容

serverChannel = serverBootstrap.bind(tcpPort).sync().channel().closeFuture().sync().channel();

启动 netty。 当我这样做时,我实施的其余服务无法正常工作。 现在,当我使用以下代码片段启动应用程序时:

serverChannel = serverBootstrap.bind(tcpPort).sync().channel();

似乎一切正常。 谁能解释一下是什么导致了这个问题?

谢谢

第一部分启动服务器, 1) 将其绑定在 TCP 端口上, 2)等待服务器准备好(套接字正在监听) 3) 和 return 关联的频道。

serverBootstrap.bind(tcpPort).sync().channel();
                 (1)           (2)       (3)

第二部分是等待主通道(侦听套接字)关闭(closeFuture().sync()),其中 closeFuture 为您提供 "future" on "close" 操作(意味着关闭服务器套接字),并且 sync 等待这个未来完成。 channel() 返回与第一次相同的频道,只是现在已关闭。

所以你可能会在各种示例中找到这段代码,因为通常你在主线程左右启动服务器(绑定),然后如果你不等待什么,主线程就会结束,给你JVM整理,因此你的服务器启动后立即停止。

所以总的来说,我们做的是:

  • 启动服务器
  • 在管道中添加必要的处理程序来处理您的业务逻辑(当然还有网络协议)
  • 然后通过等待 closeFuture 来完成您的主线程,这样,一旦您在业务逻辑中收到关闭命令,您就关闭了主通道,因此您的主线程也将关闭。

见实例

旧的,但我的 RestController 没有启动时遇到了同样的问题。其他答案帮助我解决了这个问题,但这里是 Spring 组件的完整代码。

import com.myserver.netty.handler.ClientInboundHandler;
import com.myserver.netty.handler.PacketDecoder;
import com.myserver.netty.handler.PacketEncoder;

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 lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

@Component
@Log4j2
public class NettyServer {

   private EventLoopGroup masters = new NioEventLoopGroup();
   private EventLoopGroup workers = new NioEventLoopGroup();

   private Channel mainChannel;

   @PostConstruct
   public void start() {
       try {
           ServerBootstrap bootstrap = init();
           mainChannel = bootstrap.bind(8484).sync().channel(); // save the main channel so we can cleanly close it when app is shutdown
           log.info("Netty Server started......");
       } catch (Exception e) {
           e.printStackTrace();
       }
   }

   @PreDestroy
   public void stop() throws InterruptedException {
       log.info("Shutting down netty server");
       workers.shutdownGracefully().sync();
       masters.shutdownGracefully().sync();
       mainChannel.closeFuture().sync();
       log.info("Shutdown complete");
   }

   private ServerBootstrap init() {
       return new ServerBootstrap()
               .group(masters, workers)
               .channel(NioServerSocketChannel.class)
               .option(ChannelOption.SO_BACKLOG, 5000)
               .option(ChannelOption.TCP_NODELAY, true)
               .option(ChannelOption.SO_KEEPALIVE, true)
               .childHandler(new ChannelInitializer<SocketChannel>() {
                   @Override
                   protected void initChannel(SocketChannel channel) throws Exception {
                       channel.pipeline()
                               .addLast(new PacketDecoder())
                               .addLast(new ClientInboundHandler())
                               .addLast(new PacketEncoder());
                   }
               });
   }

}