[JAVA] Ich habe versucht, einen Server mit Netty zu implementieren

zunaechst

Beim letzten Mal habe ich versucht, mithilfe von Bibliotheken wie webSocket und SocketChannel einen TCP / IP + NIO / BIO-Übertragungspfad zu erstellen, aber ich habe festgestellt, dass der Code ziemlich kompliziert wurde. Dieses Mal werde ich versuchen, einen Server mit Netty erneut zu realisieren.

Was ist Netty?

Einfach ausgedrückt ist Netty ein Framework für die Entwicklung von Anwendungen, die asynchron kommunizieren. Im Vergleich zur von SocketChannel realisierten NIO-Verarbeitung ist es nicht mehr erforderlich, Low-Layer-APIs (select (), read () usw.) direkt zu betreiben, und sie ist auf der Netty-Seite verborgen.

Implementierung

NIO-Implementierung auf ServerSocket Channel

Zuerst werde ich die vorherige [NIO-Implementierung auf ServerSocket Channel] erneut veröffentlichen (https://qiita.com/haoyu_ma/items/bec7a50def5c18a0e1d2).

➀ Erstellen Sie einen ServerSocketChannel und warten Sie auf den clientseitigen Zugriff


public class ChannelServer {

    public static void main(String[] args) throws IOException {
        // I/Bereiten Sie einen Thread-Pool vor, um O-Anforderungen zu verarbeiten
        ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 10, 1000, TimeUnit.MILLISECONDS, 
                new ArrayBlockingQueue<Runnable>(100));

        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.bind(new InetSocketAddress(1234));

        while (true) {
            SocketChannel socketChannel = serverSocketChannel.accept();

            if (socketChannel != null) {
                //Übertragen Sie die Anforderung in den Thread-Pool
                executor.submit(new ChannelServerThread(socketChannel));
            }
        }
    }
}

② Thread zur Bearbeitung der Anfrage


public class ChannelServerThread implements Runnable {

    private SocketChannel socketChannel;
    private String remoteName;

    public ChannelServerThread(SocketChannel socketChannel) throws IOException {
        this.socketChannel = socketChannel;
        this.remoteName = socketChannel.getRemoteAddress().toString();
        System.out.println("client:" + remoteName + " access successfully!");
    }

    // I/O-Anfrage bearbeiten
    @Override
    public void run() {
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        ByteBuffer sizeBuffer = ByteBuffer.allocate(4);
        StringBuilder sb = new StringBuilder();
        byte b[];
        //Lesen Sie Daten und Länge von socketChannel und geben Sie sie in die Standardausgabe aus
        while(true) {
            try {
                sizeBuffer.clear();
                int read = socketChannel.read(sizeBuffer);
                if (read != -1) {
                    sb.setLength(0);
                    sizeBuffer.flip();
                    int size = sizeBuffer.getInt();
                    int readCount = 0;
                    b = new byte[1024];
                    while (readCount < size) {
                        buffer.clear();
                        read = socketChannel.read(buffer);
                        if (read != -1) {
                            readCount += read;
                            buffer.flip();
                            int index = 0 ;
                            while(buffer.hasRemaining()) {
                                b[index++] = buffer.get();
                                if (index >= b.length) {
                                    index = 0;
                                    sb.append(new String(b,"UTF-8"));
                                }
                            }
                            if (index > 0) {
                                sb.append(new String(b,"UTF-8"));
                            }
                        }
                    }
                    System.out.println(remoteName +  ":" + sb.toString());
                }
            } catch (Exception e) {
                System.out.println(remoteName + "access colsed");
                try {
                    socketChannel.close();
                } catch (IOException ex) {
                }
                break;
            }
        }
    }
}

NIO-Implementierung mit Netty

➀ Verarbeitung, die auf den Zugriff auf der Clientseite wartet


public class EchoServer {
    private final int port;

    public EchoServer(int port) {
        this.port = port;
    }

    public void start() throws Exception {
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            ServerBootstrap sb = new ServerBootstrap();
            //Thread-Pool-Bindung
            sb.group(group)
                    .channel(NioServerSocketChannel.class)
                     //Portnummernbindung
                    .localAddress(this.port)
                    .childHandler(new ChannelInitializer<SocketChannel>() {

                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            System.out.println("connected...; Client:" + ch.remoteAddress());
                            ch.pipeline().addLast(new EchoServerHandler());
                        }
                    });
            //Asynchrone Bindung des Servers
            ChannelFuture cf = sb.bind().sync();
            System.out.println(EchoServer.class + " started and listen on " + cf.channel().localAddress());
            //Serverkanal schließen
            cf.channel().closeFuture().sync();
        } finally {
            //Thread-Pool aufheben
            group.shutdownGracefully().sync();
        }
    }

    public static void main(String[] args) throws Exception {
        //Eingang
        new EchoServer(66666).start();
    }
}

② Derjenige, der die Anfrage bearbeitet


public class EchoServerHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("server channelRead...; received:" + msg);
        ctx.write(msg);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        System.out.println("server channelReadComplete..");
        //WriteAndFlush im leeren Puffer,Schließen Sie die Verbindung
        ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);

    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.out.println("server occur exception:" + cause.getMessage());
        cause.printStackTrace();
        ctx.close();
    }
}

Wechselpunkt

** Die Menge an Code wurde stark reduziert. ** ** ** Dies dient dazu, APIs wie read () und Buffer-Operationen von der Netty-Seite auszublenden und eine praktische High-Layer-API bereitzustellen. Beispiel: die channelRead () -Methode der EchoServerHandler-Klasse: Wenn Daten von der Clientseite empfangen werden, werden sie intern in einen String konvertiert, sodass diese Methode aufgerufen wird.

Zusammenfassung

Diesmal habe ich versucht, den Server mit Netty zu implementieren. Ich werde das nächste Mal die Zusammenarbeit mit der Kundenseite vorstellen.

Recommended Posts

Ich habe versucht, einen Server mit Netty zu implementieren
Ich habe versucht, Log4j2 auf einem Java EE-Server zu verwenden
Ich habe versucht, das GitHub-Repository als Bibliotheksserver zu verwenden
Ich habe versucht, eine Webanwendung voller Fehler mit Kotlin zu implementieren
Ich habe versucht, das Iterator-Muster zu implementieren
[Unity] Ich habe mit NWPathMonitor ein natives Plug-In UniNWPathMonitor erstellt
Ich habe versucht, eine einfache Anwendung mit Dockder + Rails Scaffold zu erstellen
Ich habe versucht, eine einfache Gesichtserkennungs-Android-Anwendung mit OpenCV zu erstellen
Ich habe versucht, Gson zu benutzen
Java Ich habe versucht, einen einfachen Block zu brechen
[Rails] Ich habe versucht, eine Transaktion zu implementieren, die mehrere DB-Prozesse kombiniert
Ich habe versucht, ein Personalmanagement-Tool zu entwickeln
Ich habe versucht, eine Website für das Studium von DUO3.0 zu entwickeln.
Ich habe versucht, eine LINE-Klon-App zu erstellen
Ich habe versucht, TestNG zu verwenden
Ich habe versucht, Galasa zu benutzen
Ich habe versucht, mit AI "A3RT" eine Talk-App in Java zu erstellen.
Ich habe versucht, eine Website zu entwickeln, um Ausgaben zu erfassen.
Ich habe versucht, den Block mit Java zu brechen (1)
Ich habe versucht, mit HCE-F von Android eine Funktion zu implementieren, die Felica Lite entspricht
[Java] Ich habe versucht, über den Verbindungspool eine Verbindung mit Servlet (Tomcat) & MySQL & Java herzustellen
Ich habe versucht, eine Datenbankverbindung in der Android-Entwicklung zu verwenden
Ich habe versucht, die Server-Push-Funktion von Servlet 4.0 zu verwenden
Ich habe versucht, TCP / IP + BIO mit JAVA zu implementieren
Ich habe versucht, die Firebase-Push-Benachrichtigung in Java zu implementieren
Ich habe versucht, SQS mit AWS Java SDK zu betreiben
Ich habe versucht, eine Clova-Fähigkeit in Java zu erstellen
Ich habe versucht, eine Anmeldefunktion mit Java zu erstellen
Ich habe versucht, Sterling Sort mit Java Collector zu implementieren
Ich habe versucht, die Methode der gegenseitigen Teilung von Eugrid in Java zu implementieren
Ich habe versucht, ein Aktienchart mit Java (Jsoup) zu kratzen.
Ich habe versucht, Azure Cloud-Init zu verwenden
Ich habe versucht, Apache Wicket zu verwenden
Ich habe versucht, yum-cron zu verifizieren
Ich habe versucht, mit Wercker ein Docker-Image zu erstellen und zu veröffentlichen, mit dem GlassFish 5 gestartet wird
Ich möchte es zusätzlich implementieren, während ich Kotlin auf einer Site verwende, auf der Java ausgeführt wird
Ich habe versucht, die ähnliche Funktion durch asynchrone Kommunikation zu implementieren
Ich habe versucht, mit Chocolatey eine Java8-Entwicklungsumgebung zu erstellen
Ich habe versucht, TabLayout unter Android eine Trennlinie hinzuzufügen
Ich habe versucht, eine Java EE-Anwendung mit OpenShift zu modernisieren.
[Rails] Ich habe versucht, eine Mini-App mit FullCalendar zu erstellen
Ich möchte eine Produktinformationsbearbeitungsfunktion ~ part1 ~ implementieren
Ich habe versucht, den Chat mit dem Minecraft-Server mit der Discord-API zu verknüpfen
Ich habe versucht, die Umgebung nach und nach mit Docker aufzubauen
[Rails] Ich habe versucht, die Stapelverarbeitung mit der Rake-Task zu implementieren
Ich habe versucht, in Java von einer Zeichenfolge in einen LocalDate-Typ zu konvertieren
Ich habe versucht, Dapr in Java zu verwenden, um die Entwicklung von Mikroservices zu erleichtern
Ich habe einen RESAS-API-Client in Java erstellt
Ich habe versucht, mit Docker eine Padrino-Entwicklungsumgebung zu erstellen
Ich habe versucht, mit Swagger mit Spring Boot zu beginnen
Ich habe eine Docker-Datei erstellt, um Glassfish 5 mit Oracle Java zu starten
Ich habe jetzt versucht, Anakia + Jing zu verwenden