problem description
when writing the demo of java nio, I want to follow the React pattern so that every request that is ready is processed in a new thread. The specific code is shown below.
when a client disconnects after writing data, it will report an error:
java.nio.channels.ClosedChannelException
it is obvious that this way of writing is inappropriate or incorrect. See that the attach () method is used on the Internet
selectionKey.attach(new Acceptor(selector,selectionKey));
so:
question 1: what is the wrong writing method that caused the client to close the Times, and what is the cause of the error?
question 2: how do I use attach (), and why can this writing avoid turning off the client side to report an error?
related codes
use separate threads for select operations.
new Thread(() -> {
try {
while (selector.select() > 0) {
for (SelectionKey selectionKey : selector.selectedKeys()) {
try {
selector.selectedKeys().remove(selectionKey);
if (selectionKey.isAcceptable()) {
SocketChannel socketChannel = serverSocketChannel.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);
}
if (selectionKey.isReadable()) {
doRead(selectionKey);
}
} catch (IOException e) {
selectionKey.cancel();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}).start();
when a readable event is encountered, it is processed in a new thread.
public void doRead(SelectionKey selectionKey) {
new Thread(() -> {
try {
SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
String content = "";
int c = 0;
while ((c = socketChannel.read(byteBuffer)) > 0) {
byteBuffer.flip();
content += charset.decode(byteBuffer);
}
System.out.println(content);
selectionKey.interestOps(SelectionKey.OP_READ);
if (c == -1) {
selectionKey.cancel();
socketChannel.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}).start();
}