[英]How do I make this non-blocking server multi-threaded?
我试图允许到一个小型Java服务器类型应用程序的多个连接。 它按原样工作正常,但是如果一个连接打开然后挂起,则所有后续连接都将挂起。 我不确定如何处理每个连接,在自己的线程中最多可处理约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);
}
}
每当我需要编写套接字服务器时,由于需要处理所有细节问题,我避免使用低级JVM类。
相反,我使用Apache Mina 。 这是一个Java库,用于编写高性能的非阻塞多线程套接字服务器。
使用Mina的另一个好处是,它强制执行了干净的体系结构 (IoFilter,协议解码器),这使您的代码更加模块化,并且更具可维护性。
除非您真的想编写一个NIO服务器作为学习练习,否则我建议使用Netty 。 就像彼得提到的Mina一样,它也是用于编写高性能服务器的库。
最近,我从使用自己的NIO代码移到了该库,它使我的代码更加简洁。
我的解决方案是创建线程池的Netty和Executor。 您只需添加处理程序来执行Netty的管道,即可将执行程序女巫ChannelBuffer作为参数调用。 超过每个客户端请求将由单独的线程处理。
看例子
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.