Heim  >  Artikel  >  Backend-Entwicklung  >  Apache Mina-Studiennotizen (2) – Grundlagen

Apache Mina-Studiennotizen (2) – Grundlagen

黄舟
黄舟Original
2017-01-18 09:48:241079Durchsuche

In Kapitel 1 hatten wir ein allgemeines Verständnis von MINA. In diesem Kapitel werden wir eine detaillierte Analyse des Client/Server-Modells in MINA durchführen. Außerdem werden einige Beispiele basierend auf TCP und UDP bereitgestellt.

Anwendungsstruktur

Serverstruktur
Client-Struktur

Einfacher TCP-Server
Einfacher TCP-Client
Einfacher UDP-Server
Einfacher UDP-Client

Zusammenfassung der Anwendungsstruktur

Die Struktur einer Anwendung, die das MINA-Framework verwendet, ist wie folgt:

Apache Mina-Studiennotizen (2) – Grundlagen

Von oben Wie Sie in sehen können In der Abbildung fungiert MINA als mittlere Schicht, um Ihre Anwendung mit der untersten Schicht des Netzwerks zu verbinden. Es kann TCP, UDP und sogar ein serielles Kommunikationsprotokoll (RS-232C) verarbeiten, sodass Sie sich mehr auf die Entwicklung von Anwendungen auf MINA konzentrieren können. Ohne die Komplexität der zugrunde liegenden Netzwerkkommunikation verstehen zu müssen.

Hier ein Blick ins Innere von MINA:

Apache Mina-Studiennotizen (2) – Grundlagen

Im Allgemeinen sind MINA-Anwendungen in drei Schichten unterteilt.

E/A-Dienst – echte E/A-Operation
E/A-Filterkette – Daten filtern/übertragen
E/A-Handler – Vervollständigen Sie hier die Logik des Programms

Um eine MINA-Anwendung zu erstellen, müssen Sie also nur Folgendes tun:

I/O-Dienst erstellen – wählen Sie einen bereits bereitgestellten Dienst (Akzeptor) aus oder erstellen Sie Ihren eigenen Dienst
Filterkette erstellen – wählen Sie einen bereits bereitgestellten aus Service-Filterkette oder erstellen Sie Ihre eigene benutzerdefinierte Filterkette
Erstellen Sie I/OHandler – schreiben Sie Geschäftslogik und verarbeiten Sie verschiedene Nachrichten

Werfen wir einen Blick auf die Struktur von Serverseite:

Apache Mina-Studiennotizen (2) – Grundlagen

Vereinfacht ausgedrückt gibt es auf der Serverseite einen I/O-Akzeptor, der auf eingehende Verbindungen oder Datenpakete wartet. Es wird eine neue Sitzung erstellt und nachfolgende Anfragen von dieser Verbindung werden in dieser Sitzung verarbeitet. Alle Pakete werden von der Sitzung akzeptiert und durchlaufen die in der Abbildung oben dargestellte Filterkette. Filterketten werden verwendet, um den Inhalt des Pakets zu ändern (z. B. Konvertieren in Objekte, Hinzufügen oder Entfernen einiger Informationen). Abschließend werden diese Pakete vom IOHandler verarbeitet. Beachten Sie außerdem, dass beim Eintreffen einer Verbindung eine Sitzung eingerichtet wird. Unabhängig davon, ob die Verbindung erfolgreich ist oder nicht, wird die Sitzung eingerichtet.

Das Folgende ist das Client-Modell:

Apache Mina-Studiennotizen (2) – Grundlagen



Client und Server Es ist genau der entgegengesetzte Zustand.

Der Client verfügt über einen IOConnector, um eine Verbindung zum Server herzustellen. Und die gesamte Verarbeitung wird weiterhin von IOHandler abgeschlossen.

Einfacher TCP-Server

Erstellen Sie als Nächstes einen einfachen TCP-Server zur Demonstration: Zuerst müssen Sie einige erforderliche Pakete in die IDE importieren oder Ihren CLASSPATH konfigurieren. Die spezifische Methode wird nicht detailliert beschrieben . Ja, die erforderlichen Pakete sind:

MINA 2.x Core
JDK 1.5 oder höher
SLF4J 1.3.0 oder höher

Log4J 1.2-Benutzer: slf4j-api.jar , slf4j-log4j12.jar und Log4J 1.2.x
Log4J 1.3-Benutzer: slf4j-api.jar, slf4j-log4j13.jar und Log4J 1.3.x
java.util.logging-Benutzer: slf4j-api. jar und slf4j-jdk14.jar
WICHTIG: Bitte stellen Sie sicher, dass Sie das richtige slf4j-*.jar verwenden, das zu Ihrem Protokollierungsframework passt.

Nachdem die Vorbereitungen abgeschlossen sind, beginnen wir mit dem Schreiben von Code

import java.net.InetSocketAddress;  
import org.apache.mina.core.service.IoAcceptor;  
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;  
  
public class MinaTimeServer  
{  
    private static final int PORT = 9123;  
    public static void main( String[] args ) throws IOException  
    {  
        IoAcceptor acceptor = new NioSocketAcceptor();  
        acceptor.bind( new InetSocketAddress(PORT) );  
    }  
}

Als nächstes fügen wir die Filterkettenkonfiguration zum obigen Code hinzu.

import java.io.IOException;  
import java.net.InetSocketAddress;  
import java.nio.charset.Charset;  
import org.apache.mina.core.service.IoAcceptor;  
import org.apache.mina.filter.codec.ProtocolCodecFilter;  
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;  
import org.apache.mina.filter.logging.LoggingFilter;  
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;  
  
public class MinaTimeServer  
{  
    public static void main( String[] args )  
    {  
        IoAcceptor acceptor = new NioSocketAcceptor();  
        acceptor.getFilterChain().addLast( "logger", new LoggingFilter() );  //这里会建立所有的日志信息  
        acceptor.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" )))); //第二个过滤器用来传递数据  
        acceptor.bind( new InetSocketAddress(PORT) );  
    }  
}

Als nächstes müssen wir den Handler definieren, der zum Verarbeiten von Nachrichten verwendet wird. Diese Handler-Klasse muss die IoHandler-Schnittstelle implementieren. In MINA ist dieser Handler der Schlüssel zur Programmentwicklung. In diesem Tutorial erben wir von IoHandlerAdapter.

import java.util.Date;  
import org.apache.mina.core.session.IdleStatus;  
import org.apache.mina.core.service.IoHandlerAdapter;  
import org.apache.mina.core.session.IoSession;  
  
public class TimeServerHandler extends IoHandlerAdapter  
{  
    @Override  
    public void exceptionCaught( IoSession session, Throwable cause ) throws Exception  
    {  
        cause.printStackTrace();  
    }  
    @Override  
    public void messageReceived( IoSession session, Object message ) throws Exception  
    {  
        String str = message.toString();  
        if( str.trim().equalsIgnoreCase("quit") ) {  
            session.close();  
            return;  
        }  
        Date date = new Date();  
        session.write( date.toString() );  
        System.out.println("Message written...");  
    }  
    @Override  
    public void sessionIdle( IoSession session, IdleStatus status ) throws Exception  
    {  
        System.out.println( "IDLE " + session.getIdleCount( status ));  
    }  
}

Abschließend lautet der vollständige Servercode wie folgt:

import java.io.IOException;  
import java.net.InetSocketAddress;  
import java.nio.charset.Charset;  
  
import org.apache.mina.core.service.IoAcceptor;  
import org.apache.mina.core.session.IdleStatus;  
import org.apache.mina.filter.codec.ProtocolCodecFilter;  
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;  
import org.apache.mina.filter.logging.LoggingFilter;  
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;  
  
public class MinaTimeServer  
{  
    private static final int PORT = 9123;  
    public static void main( String[] args ) throws IOException  
    {  
        IoAcceptor acceptor = new NioSocketAcceptor();  
        acceptor.getFilterChain().addLast( "logger", new LoggingFilter() );  
        acceptor.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" ))));  
        acceptor.setHandler( new TimeServerHandler() );  //这里设置Handler  
        acceptor.getSessionConfig().setReadBufferSize( 2048 );       //这是设置ssesion缓冲区  
        acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 );  
        acceptor.bind( new InetSocketAddress(PORT) );  
    }  
}

Starten Sie den Server, öffnen Sie dann das Terminal und geben Sie den Befehl ein: telnet 127.0.0.1 9123. Sie werden sehen Wenn Sie etwas anderes als „Quit“ eingeben, gibt der Server die aktuelle Uhrzeit an das Terminal zurück.

Einfacher TCP-Client

import java.net.InetSocketAddress;  
import org.apache.mina.core.RuntimeIoException;  
import org.apache.mina.core.future.ConnectFuture;  
import org.apache.mina.core.session.IoSession;  
import org.apache.mina.example.sumup.codec.SumUpProtocolCodecFactory;  
import org.apache.mina.filter.codec.ProtocolCodecFilter;  
import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;  
import org.apache.mina.filter.logging.LoggingFilter;  
import org.apache.mina.transport.socket.nio.NioSocketConnector;  
   
  /** 
   * (<strong>Entry Point</strong>) Starts SumUp client. 
   * 
   * @author <a href="http://mina.apache.org">Apache MINA Project</a> 
   */  
  public class Client {  
     private static final String HOSTNAME = "localhost";  
    
      private static final int PORT = 8080;  
    
     private static final long CONNECT_TIMEOUT = 30*1000L; // 30 seconds  
    
      // Set this to false to use object serialization instead of custom codec.  
      private static final boolean USE_CUSTOM_CODEC = true;  
    
      public static void main(String[] args) throws Throwable {  
          if (args.length == 0) {  
              System.out.println("Please specify the list of any integers");  
              return;  
          }  
    
          // prepare values to sum up  
         int[] values = new int[args.length];  
          for (int i = 0; i < args.length; i++) {  
              values[i] = Integer.parseInt(args[i]);  
          }  
    
          NioSocketConnector connector = new NioSocketConnector();  
    
          // Configure the service.  
          connector.setConnectTimeoutMillis(CONNECT_TIMEOUT);  
          if (USE_CUSTOM_CODEC) {
connector.getFilterChain().addLast(  
                      "codec",  
                      new ProtocolCodecFilter(  
                              new SumUpProtocolCodecFactory(false)));  
          } else {  
              connector.getFilterChain().addLast(  
                      "codec",  
                      new ProtocolCodecFilter(  
                              new ObjectSerializationCodecFactory()));  
          }  
          connector.getFilterChain().addLast("logger", new LoggingFilter());  
    
          connector.setHandler(new ClientSessionHandler(values));  
    
          IoSession session;  
          for (;;) {  
              try {  
                  ConnectFuture future = connector.connect(new InetSocketAddress(  
                          HOSTNAME, PORT));  
                  future.awaitUninterruptibly();  
                  session = future.getSession();  
                  break;  
             } catch (RuntimeIoException e) {  
                  System.err.println("Failed to connect.");  
                  e.printStackTrace();  
                  Thread.sleep(5000);  
              }  
          }  
    
          // wait until the summation is done  
         session.getCloseFuture().awaitUninterruptibly();  
            
          connector.dispose();  
      }  
  }

Ich werde das UDP-Beispiel nicht schreiben. Schauen Sie sich bei Bedarf die offizielle Apache-Website an.

http://mina.apache.org/mina-project/userguide/ch2-basics/sample-udp-client.html

Das Obige ist Apache Mina Lernnotizen (2) - Grundlegende Inhalte. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.php.cn)!


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn