1. Introduction to Mina
Apache MINA(Multipurpose Infrastructure for Network Applications) is a relatively new project organized by Apache. It is a network communication application framework, which provides a very convenient framework for developing high-performance and high availability network applications.
In other words, it is mainly for the communication framework based on TCP/IP and UDP/IP protocol stack (of course, it can also provide JAVA object serialization service, virtual machine pipeline communication service, etc.).
Mina can help us quickly develop high-performance and scalable network communication applications. Mina provides a programming model of event driven and asynchronous (Mina's asynchronous IO uses JAVA NIO as the underlying support by default).
Mina mainly has two branches: 1.x and 2.x. here we will explain the latest version 2.0. If you use Mina 1.x, some functions may not be applicable. To learn Mina, you need to master JAVA IO, JAVA NIO, JAVASocket, JAVA thread and concurrency Library (java.util.concurrent. *).
Mina also provides the encapsulation of Server side and Client side of network communication. No matter which end, Mina is in the following position in the whole Netcom Communication Structure: it can be seen that Mina's API separates the real network communication from our applications. You only need to care about the data you want to send and receive and your business logic.
Similarly, no matter which end, Mina's execution process is as follows:
2. Mina general framework
The application architecture based on MINA framework should be as follows:
Mina's core architecture
The bottom layer of Mina is implemented based on NIO 1.0 of JAVA, and its core architecture is as follows:
Three levels within Mina
- I/O Service - To perform the actual I / O, you can choose an off the shelf service such as (* Acceptor) or write it yourself.
- I/O Filter Chain - This is a filter chain composed of multiple filters, which converts byte data into desired data structures and vice versa
- I/O Handler - Actual business logic part
3. Server application based on MINA framework
For socket communication, Server-based applications are widely used, especially when the concurrency scale reaches a certain degree, it is quite challenging.
Let's take a look at the Server-side application based on MINA framework:
- IOAcceptor listens to the specified port and handles new network connections; Once a new connection arrives, the IOAcceptor will generate a session, and all subsequent requests sent from this IP and port will be processed through this session.
- After the Session is created, all subsequent packets are sent to the filter chain, and the original bytecode is transformed into high-level objects through the filter. This link PacketEncoder/Decoder is very useful.
- Finally, the data packet or object is transmitted to the Handler for business logic processing;
Mina.java
package com.hl.magic.mina; 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; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.charset.StandardCharsets; /** * @Date 2021/10/10 21:00 */ public class Mina { /** * Custom port */ private static final int PORT = 54321; public static boolean connect() { try { IoAcceptor acceptor = new NioSocketAcceptor(); acceptor.getFilterChain().addLast("logger", new LoggingFilter()); acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(StandardCharsets.UTF_8))); acceptor.setHandler(new TimeServerHandler()); acceptor.getSessionConfig().setReadBufferSize(2048); acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10); acceptor.bind(new InetSocketAddress(PORT)); return true; } catch (IOException e) { e.printStackTrace(); return false; } } /** * @param args the command line arguments */ public static void main(String[] args) { boolean connect = connect(); System.out.println("connect:" + connect); } }
- Create IoAcceptor;
- Add log recording and decoding filters, where the log filter records information with SL4J library, and the encoding filter decodes all received information. The line code of the information sent using new TextLineCodecFactory() is MINA's own and has limited functions. It can only handle the String type of text abstainer.
- Set ServerHandler. Here is a custom Handler: TimeServerHandler;
- Set the I/O processor read buffer size 2048 corresponding to the Session; Generally, this parameter does not need to be set;
- Set idle time, here refers to and . All 10 seconds;
- Binding listening port 9123;
TimeServerHandler.java:
package com.hl.magic.mina; import org.apache.mina.core.service.IoHandlerAdapter; import org.apache.mina.core.session.IdleStatus; import org.apache.mina.core.session.IoSession; import java.util.Date; /** * @Date 2021/10/10 21:06 */ public class TimeServerHandler extends IoHandlerAdapter { @Override public void exceptionCaught(IoSession session, Throwable cause) { cause.printStackTrace(); } @Override public void messageReceived(IoSession session, Object message) { 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) { System.out.println("IDLE " + session.getIdleCount(status)); } }
Here are the following main methods:
messageReceived(...), the next step is to process the received message (decoded). Here, judge the received string. If it is "quit", disconnect it; Otherwise, the string format of the current time is output;
Exceptionguess (...), custom exception handling, otherwise the exception will be "eaten";
sessionIdle: when the Session is in the IDLE state, the number of IDLE states is output;
Test, run CMD and enter telnet 127.0.0.1 54321 in the window
Then input a string randomly on the sub CMD window to display the current time: