Maison > Article > développement back-end > Notes d'étude Apache Mina (2) - Bases
Dans le chapitre 1, nous avons eu une compréhension générale de MINA. Dans ce chapitre, nous ferons une analyse détaillée du modèle client/serveur dans MINA. Et quelques exemples basés sur TCP et UDP seront également fournis.
Structure de l'application
Structure du serveur
Structure du client
Serveur TCP simple
Client TCP simple
Serveur UDP simple
Client UDP simple
Résumé de la structure de l'application
La structure d'une application utilisant le framework MINA est la suivante :
De dessus Comme vous pouvez le voir dans Comme le montre la figure, MINA agit comme une couche intermédiaire pour connecter votre application et la couche inférieure du réseau. Il peut gérer TCP, UDP et même un protocole de communication série (RS-232C), afin que vous puissiez vous concentrer davantage sur la conception d'applications sur MINA. Il n'est pas nécessaire de comprendre la complexité des communications réseau sous-jacentes.
Voici un aperçu de MINA :
De manière générale, les applications MINA sont divisées en trois couches.
Service d'E/S - fonctionnement réel des E/S
Chaîne de filtrage d'E/S - filtrer/transmettre les données
Gestionnaire d'E/S - complétez la logique du programme ici
Ainsi, pour créer une application MINA, il vous suffit de faire :
Créer un service d'E/S - sélectionner un service déjà fourni (Accepteur) ou créer votre propre service
Créer une chaîne de filtres - sélectionner un service déjà fourni service Chaîne de filtres ou créez votre propre chaîne de filtres personnalisée
Créer un I/OHandler - écrivez une logique métier et traitez divers messages Ce qui précède est la structure globale de MINA
Jetons un coup d'œil à la structure du. côté serveur :
Pour faire simple, il y a un accepteur d'E/S côté serveur qui écoute les connexions entrantes ou les paquets de données pour l'arrivée d'une nouvelle connexion, une nouvelle session sera créée et les demandes ultérieures provenant de cette connexion seront traitées dans cette session. Tous les paquets sont acceptés par la session et passent par la chaîne de filtrage indiquée dans la figure ci-dessus. Les chaînes de filtres sont utilisées pour modifier le contenu du package (comme la conversion en objets, l'ajout ou la suppression de certaines informations). Enfin ces paquets sont traités par IOHandler. Une autre chose à noter est que lorsqu'une connexion arrive, une session sera établie, que la connexion réussisse ou non, la session sera établie.
Voici le modèle client :
Client et serveur C'est exactement l’état opposé.
Le client aura un IOConnector pour se connecter au serveur. Et tout le traitement est toujours effectué par IOHandler.
Serveur TCP simple
Ensuite, créez un serveur TCP simple à titre de démonstration : Tout d'abord, vous devez importer certains packages requis dans l'EDI ou configurer votre CLASSPATH. La méthode spécifique ne sera pas détaillée. . Oui, les packages requis sont :
MINA 2.x Core
JDK 1.5 ou supérieur
SLF4J 1.3.0 ou supérieur
Utilisateurs de Log4J 1.2 : slf4j-api.jar. , slf4j-log4j12.jar et Log4J 1.2.x
Utilisateurs de Log4J 1.3 : slf4j-api.jar, slf4j-log4j13.jar et Log4J 1.3.x
utilisateurs de Java.util.logging : slf4j-api. jar et slf4j-jdk14.jar
IMPORTANT : assurez-vous d'utiliser le bon slf4j-*.jar qui correspond à votre framework de journalisation.
Une fois les préparatifs terminés, nous commençons à écrire du 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) ); } }
Ensuite, nous ajoutons la configuration de la chaîne de filtres dans le code ci-dessus.
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) ); } }
Ensuite, nous devons définir le Handler utilisé pour traiter les messages. Cette classe Handler doit implémenter l'interface IoHandler. Dans MINA, ce Handler est la clé du développement du programme. Dans ce tutoriel, nous hériterons de 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 )); } }
Enfin, le code complet du serveur est le suivant :
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) ); } }
Exécutez le serveur, puis ouvrez le terminal et entrez la commande : telnet 127.0.0.1 9123. Vous verrez que lorsque vous entrez autre chose que Lorsqu'un caractère « quitter » est saisi, le serveur renvoie l'heure actuelle au terminal.
Client TCP simple
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(); } }
Je n'écrirai pas l'exemple UDP Si nécessaire, consultez le site officiel d'Apache.
http://mina.apache.org/mina-project/userguide/ch2-basics/sample-udp-client.html
Ce qui précède est Apache Mina Notes d'apprentissage (2) - Contenu de base, veuillez faire attention au site Web PHP chinois (www.php.cn) pour plus de contenu connexe !