[英]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.