java - 如何阻止 netty bootstrap 监听和接受新连接

标签 java netty

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.epoll.EpollChannelOption;
import io.netty.channel.epoll.EpollEventLoopGroup;
import io.netty.channel.epoll.EpollServerSocketChannel;
import io.netty.channel.socket.SocketChannel;
import sun.misc.Signal;
import sun.misc.SignalHandler;

import java.net.InetSocketAddress;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

public class ReusePortServer {
  private final int port;
  private List<Channel> bindingChannels = new LinkedList<>();

  public ReusePortServer(int port) {
    this.port = port;
  }

  private void initSignals() {
    Signal.handle(new Signal("BUS"), new SignalHandler() {
      @Override public void handle(Signal signal) {
        System.out.println("signal arrived");
        closeChannels();
      }
    });
  }

  synchronized private void closeChannels() {
    for (Channel channel : bindingChannels) {
      channel.close();
    }

    bindingChannels.clear();
  }

  synchronized private void registerChannel(Channel channel) {
    bindingChannels.add(channel);
  }

  public void start() throws Exception {
    initSignals();

    EventLoopGroup group = new EpollEventLoopGroup();
    try {
      ServerBootstrap b = new ServerBootstrap();
      b.group(group)
              .channel(EpollServerSocketChannel.class)
              .option(EpollChannelOption.SO_REUSEPORT, true)
              .localAddress(new InetSocketAddress(port))
              .childHandler(new ChannelInitializer<SocketChannel>(){
                @Override
                public void initChannel(SocketChannel ch) throws Exception {
                  ch.pipeline().addLast(new ReusePortHandler());
                  registerChannel(ch);
                }
              });

      for (StackTraceElement e : Thread.currentThread().getStackTrace()) {
        System.out.println(e.toString());
      }
      ChannelFuture f = b.bind().sync();
      log(String.format("%s started and listen on %s", ReusePortServer.class.getName(), f.channel().localAddress()));
      // registerChannel(ch);  // ---------------I also tried to register this channel, but after my signaling, it closes my client's connection, rather than keeping it.
      f.channel().closeFuture().sync();
    } finally {
      group.shutdownGracefully().sync();
    }
  }

  private final static SimpleDateFormat datefmt = new SimpleDateFormat("HH:mm:ss ");

  public static void log(final String msg) {
    System.out.print(datefmt.format(new Date()));
    System.out.println(msg);
    System.out.flush();
  }

  public static void main(final String[] args) throws Exception {
    int port = 12355;
    new ReusePortServer(port).start();
  }
}

你好,我正在寻找一种方法来阻止 netty 在服务器套接字上监听和接受,但要完成当前连接上任何正在进行的工作。

我遇到了以下问题: How to stop netty from listening and accepting on server socket

根据它,我写了上面的代码,它接收信号(kill -7)来完成关闭。

但结果不是预期的,它关闭了tcp连接,netty仍然可以接受新的连接。

阻止netty监听和接受的正确方式是否正确?

这是怎么回事?

最佳答案

您应该像这样关闭 ServerChannel:

ChannelFuture f = b.bind().sync();
// Call this once you want to stop accepting new connections.
f.channel().close().sync();

关于java - 如何阻止 netty bootstrap 监听和接受新连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37675009/

相关文章:

java - 将 ResultSet.getString 值与文本字段中的输入进行比较

java - 四分区矩阵搜索

java - Ant TaskDef 在 ClassLoader 中失败

java - Java 游戏中链表的迭代器

java - 在 Netty 4 中迁移 sendUpstream

java - Netty SSL 中的字段长度溢出

java - Netty TCP 套接字输入流

java - 我可以在 onPostexecute 中使用 setImageResource 吗?

java - Netty:在 ctx.flush() 之后保持服务器套接字打开

java - 直接在客户端处理接收到的消息(通过 netty 框架使用 nio)