简体   繁体   English

为 NIO 使用两个选择器

[英]Using two Selectors for NIO

I need a way to use different Selectors for OP_READ & OP_ACCEPT.我需要一种为 OP_READ 和 OP_ACCEPT 使用不同选择器的方法。 I am running into an issue where port scrapers among other entities connecting will delay the handshake and cause latency for anyone registered on OP_READ.我遇到了一个问题,即其他连接实体之间的端口抓取器会延迟握手并导致在 OP_READ 上注册的任何人延迟。 My solution was to handle OP_READ & OP_ACCEPT on separate threads but I have been having issues.我的解决方案是在单独的线程上处理 OP_READ 和 OP_ACCEPT,但我一直遇到问题。 I first register my acceptor (a selector) to my sever socket channel here...我首先在这里将我的接受器(选择器)注册到我的服务器套接字通道......

ssc.register(acceptor, SelectionKey.OP_ACCEPT);

after I accept a client, I register its socket channel to a different selector than it was accepted on:接受客户端后,我将其套接字通道注册到与接受的选择器不同的选择器:

        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.");
        }

For some reason, the selector for OP_READ will never return anything even when it should (when a client sends a message).出于某种原因,OP_READ 的选择器永远不会返回任何东西,即使它应该返回任何东西(当客户端发送消息时)。 When I use the same selector for OP_READ as OP_ACCEPT, I have no issues regarding the messages being received.当我对 OP_READ 使用与 OP_ACCEPT 相同的选择器时,我对收到的消息没有任何问题。 Specifically, I am stuck on selector.select();具体来说,我被困在selector.select();

I figured it out.我想到了。 I hope this helps anyone here: The solution is to do the following:我希望这对这里的任何人都有帮助:解决方案是执行以下操作:

  1. Cancel the key.取消密钥。
  2. Register the key with the new selector after the handshake.握手后用新的选择器注册密钥。
  3. Call wakeup() on the selector it was just registered to.在刚刚注册到的选择器上调用 wakeup()。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM