public void serve(InetSocketAddress address) throws IOException {
var serverSocketChannel = ServerSocketChannel.open();
log.info("Opened server socket channel");
serverSocketChannel.configureBlocking(false);
log.info("Configured channel to nonblocking mode");
serverSocketChannel.bind(address);
log.info("Bind to port: " + address.getPort());
Selector selector = Selector.open();
log.info("Created selector");
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
log.info("Registered server socket channel");
Set<SelectionKey> selectedKeys;
int selected;
Iterator<SelectionKey> iter;
log.info("Listening...");
while (true) {
log.info("- Select -");
selected = selector.select();
log.info("Selected: " + selected + " channels");
selectedKeys = selector.selectedKeys();
iter = selectedKeys.iterator();
while (iter.hasNext()) {
SelectionKey key = iter.next();
log.info("Processing key " + key.toString());
if (key.isAcceptable()) {
log.info("Key is acceptable");
var serverChannel = (ServerSocketChannel) key.channel();
log.info("Obtained server channel");
var channel = serverChannel.accept();
log.info("Obtained channel");
channel.configureBlocking(false);
log.info("Configured channel to nonblocking mode");
channel.register(selector, SelectionKey.OP_READ);
log.info("Registered channel as readable");
iter.remove();
log.info("Processing complete - removed channel");
}
if (key.isReadable()) {
log.info("Key is readable");
var channel = (SocketChannel) key.channel();
log.info("Obtained channel");
var buffer = ByteBuffer.allocate(1024);
channel.read(buffer);
log.info("Read from channel");
buffer.flip();
CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer);
System.out.printf("Message: %s%n", charBuffer.toString());
channel.configureBlocking(false);
log.info("Configured channel to nonblocking mode");
channel.register(selector, SelectionKey.OP_WRITE);
log.info("Registered channel as writable");
// iter.remove();
buffer.clear();
charBuffer.clear();
log.info("Processing complete - removed channel");
}
if (key.isWritable()) {
log.info("Key is writable");
var channel = (SocketChannel) key.channel();
log.info("Obtained channel");
var charBuffer = CharBuffer.allocate(1024);
charBuffer.put("RESPONSE " + getCurrentDate()).flip();
log.info("Created response");
int writtenBytes = channel.write(StandardCharsets.UTF_8.encode(charBuffer));
log.info("Written " + writtenBytes + " bytes");
// iter.remove();
// channel.close();
log.info("Processing complete - removed channel without registering");
}
}
}
}
Dokumentacja kompletnie mi nie pomaga, potrzebuję ogarnąć SocketChannel
e, czy jest ktoś w stanie pomóc mi z tym kodem? Urywa połączenie po drugiej wiadomości (docelowo ma to być kopia IRCa).
Jak poprawnie obsługiwać SelectionKey
? Jak utrzymywać połączenia w aplikacji (tak, aby można było zrobić broadcast?)