Server oparty o ServerSocketChannels

Odpowiedz Nowy wątek
2018-12-18 20:56
0
    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ąć SocketChannele, 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?)


Pozostało 580 znaków

2018-12-18 22:45
0

@Burdzi0: niestety za dużo z NIO 2 nie miałem do czynienia i nie mam za bardzo dużo czasu ogarnąc temat teraz, ale wydaje mi się że powinieneś użyć AsynchronousServerSocketChannel.open() zamiast metody z ServerSocketChannel :)


Nie pomagam przez PM. Pytania zadaje się na forum.

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0