为 NIO 使用两个选择器

Using two Selectors for NIO

我需要一种方法来为 OP_READ 和 OP_ACCEPT 使用不同的选择器。我 运行 遇到一个问题,其他实体之间的端口抓取器连接将延迟握手并导致在 OP_READ 上注册的任何人延迟。我的解决方案是在不同的线程上处理 OP_READ & OP_ACCEPT,但我一直遇到问题。我首先在此处将我的接受器(选择器)注册到我的服务器套接字通道...

ssc.register(acceptor, SelectionKey.OP_ACCEPT);

在我接受客户端后,我将其套接字通道注册到一个不同于被接受的选择器:

        SocketChannel sc = ((ServerSocketChannel) key.channel()).accept();
        sc.configureBlocking(false);

        SSLEngine e = context.createSSLEngine();
        e.setUseClientMode(false);
        e.beginHandshake();
        ClientHandler c = new ClientHandler(e);
        if (doHandshake(sc, e)) {
            c.setSocketChannel(sc);
            sc.register(selector, SelectionKey.OP_READ, c);
            System.out.println("Registered socket channel to selector");
        } else {
            sc.close();
            System.out.println("Connection closed: handshake failure.");
        }

出于某种原因,OP_READ 的选择器永远不会 return 任何东西,即使它应该(当客户端发送消息时)也是如此。当我对 OP_READ 使用与 OP_ACCEPT 相同的选择器时,我对收到的消息没有任何问题。具体来说,我坚持 selector.select();

我想通了!我希望这对这里的任何人都有帮助。解决方案是执行以下操作:

  1. 取消密钥。
  2. 握手后用新的选择器注册密钥。
  3. 在刚刚注册的选择器上调用 wakeup()。