简体   繁体   English

如何使该非阻塞服务器成为多线程?

[英]How do I make this non-blocking server multi-threaded?

I'm trying to allow multiple connections to a little Java server type app. 我试图允许到一个小型Java服务器类型应用程序的多个连接。 It works fine as is, but if one connection opens and then hangs, all subsequent connections will hang. 它按原样工作正常,但是如果一个连接打开然后挂起,则所有后续连接都将挂起。 I'm not sure how to go about handling each connection, up to about 20 concurrent ones in their own thread while keeping track of which thread belongs to which client etc. The code I have so far is: 我不确定如何处理每个连接,在自己的线程中最多可处理约20个并发连接,同时跟踪哪个线程属于哪个客户端等。到目前为止,我的代码是:

private void init() {
    try {
        // Create the server socket channel
        ServerSocketChannel server = ServerSocketChannel.open();
        // nonblocking I/O
        server.configureBlocking(false);
        // host-port 
        server.socket().bind(new InetSocketAddress(host, port));
        System.out.println("Server connected on " + host + ":" + port);
        // Create the selector
        Selector selector = Selector.open();
        // Recording server to selector (type OP_ACCEPT)
        server.register(selector, SelectionKey.OP_ACCEPT);
        // Infinite server loop
        for (;;) {
            // Waiting for events
            selector.select();
            // Get keys
            Set keys = selector.selectedKeys();
            Iterator i = keys.iterator();
            // For each keys...
            while (i.hasNext()) {
                SelectionKey key = (SelectionKey) i.next();
                // Remove the current key
                i.remove();
                // if isAccetable = true
                // then a client required a connection
                if (key.isAcceptable()) {
                    // get client socket channel
                    SocketChannel client = server.accept();
                    // Non Blocking I/O
                    client.configureBlocking(false);
                    // recording to the selector (reading)
                    client.register(selector, SelectionKey.OP_READ);
                    continue;
                }
                // then the server is ready to read
                if (key.isReadable()) {
                    SocketChannel client = (SocketChannel) key.channel();
                    // Read byte coming from the client
                    int BUFFER_SIZE = 32;
                    ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
                    try {
                        client.read(buffer);
                    } catch (Exception e) {
                        // client is no longer active
                        e.printStackTrace();
                        continue;
                    }
                    buffer.flip();
                    Charset charset = Charset.forName("ISO-8859-1");
                    CharsetDecoder decoder = charset.newDecoder();
                    CharBuffer charBuffer = decoder.decode(buffer);
                    Handler dataHandler = new Handler();
                    client.write(ByteBuffer.wrap(dataHandler.processInput(charBuffer.toString()).getBytes()));
                    client.socket().close();
                    continue;
                }
            }
        }
    } catch (IOException ex) {
        Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
    }
}

Whenever I need to write a socket server I avoid using low-level JVM classes because of the need to handle all the nitty-gritty details. 每当我需要编写套接字服务器时,由于需要处理所有细节问题,我避免使用低级JVM类。

Instead I use Apache Mina . 相反,我使用Apache Mina This ia a Java library for writing high-performance non-blocking multi-threaded socket servers. 这是一个Java库,用于编写高性能的非阻塞多线程套接字服务器。

An added benefit of using Mina is that it enforces clean architecture (IoFilters, protocol decoders) which makes your code more modular and makes it more maintainable. 使用Mina的另一个好处是,它强制执行了干净的体系结构 (IoFilter,协议解码器),这使您的代码更加模块化,并且更具可维护性。

Unless you really want to write an NIO server as a learning exercise I would recommend using Netty . 除非您真的想编写一个NIO服务器作为学习练习,否则我建议使用Netty Like Mina that Peter mentioned it is also a library for writing high performance servers. 就像彼得提到的Mina一样,它也是用于编写高性能服务器的库。

I recently moved from using my own NIO code to this library and it has made my code so much cleaner. 最近,我从使用自己的NIO代码移到了该库,它使我的代码更加简洁。

My solution i Netty and Executor which creates ThreadPool. 我的解决方案是创建线程池的Netty和Executor。 You simply add handler do Netty's pipeline, which call executor witch ChannelBuffer as a parameter. 您只需添加处理程序来执行Netty的管道,即可将执行程序女巫ChannelBuffer作为参数调用。 Than every client request will be processed by separate thread. 超过每个客户端请求将由单独的线程处理。

Look at the examples 例子

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

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