Mina, apachemina

Source: Internet
Author: User

Mina, apachemina

1. Introduction to the MINA framework
MINA (Multipurpose Infrastructure for Network Applications) is a basic framework for developing high-performance and high-availability Network Applications. By using the MINA framework, you can save on complex tasks such as underlying I/O and thread concurrency. developers can devote more energy to business design and development. MINA framework is widely used. Open-source projects include Apache Directory, AsyncWeb, Apache Qpid, QuickFIX/J, Openfire, SubEthaSTMP, and red5. The stable version of the MINA framework is 1.1.6, and the latest version 2.0 has released the M1 version.
The MINA framework is developed based on the java NIO class library. It adopts non-blocking asynchronous transmission, event-driven, batch data transmission, and TCP and UDP protocols; design Mode of control reversal (Spring supported); elegant loose coupling architecture; Flexible Loading filter mechanism; easier implementation of unit testing; number of customizable threads, in order to improve the performance of running on the multi-processor; using callback to complete the call, the thread is easier to use.

2. Common classes of the MINA framework
The class NioSocketAcceptor is used to create server listening;
Class NioSocketConnector is used to create client connections;
IoSession is used to save session properties and send messages;
IoHandlerAdapter is used to define business logic. Common methods include:
Method Definition
SessionCreated () is triggered when a session is created.
SessionOpened () is triggered when the session starts.
SessionClosed () is triggered when the session is closed
SessionIdle () is triggered when the session is idle
ExceptionCaught () This method is triggered when exceptions thrown by other methods in the interface are not captured.
MessageRecieved () is triggered when a message is received.
MessageSent () is triggered when a message is sent.


3. server application development example
The following describes how to use the MINA framework for development based on the MINA2.0M1 version. Development Environment for jdk6.0, development tools NetBeans6.0, the jar package slf4j-api.jar, slf4j-jdk14.jar, MINA-core-2.0.0-M1.jar.
First, define a business logic processor TimeServerHandler that inherits from IoHandlerAdapter and implements the following functions: when the client creates a session, the IP address and port of the client device are displayed; when the client inputs quit, the session ends; when the client inputs other content, the current time is sent to the client. The Code is as follows:

1 public class TimeServerHandler extends IoHandlerAdapter 2 {3 @ Override 4 public void sessionCreated (IoSession session) {5 // display the client's ip address and port 6 System. out. println (session. getRemoteAddress (). toString (); 7} 8 @ Override 9 public void messageReceived (IoSession session, Object message) throws Exception 10 {11 String str = message. toString (); 12 if (str. trim (). specified signorecase ("quit") {13 session. close (); // end session 14 return; 15} 16 Date date = new Date (); 17 session. write (date. toString (); // returns the string 18 System for the current time. out. println ("Message written... "); 19} 20} 21 define another class MinaTimeServer to start the server: 22 public class MinaTimeServer 23 {24 private static final int PORT = 9123; // define the listening port 25 public static void main (String [] args) throws IOException 26 {27 IoAcceptor acceptor = new NioSocketAcceptor (); 28 acceptor. getFilterChain (). addLast ("logger", new LoggingFilter (); 29 acceptor. getFilterChain (). addLast ("codec", new ProtocolCodecFilter (new TextLineCodecFactory (Charset. forName ("UTF-8"); // specifies the encoding filter 30 acceptor. setHandler (new TimeServerHandler (); // specify the business logic processor 31 acceptor. setdefalocallocaladdress (new InetSocketAddress (PORT); // set the PORT number to 32 acceptor. bind (); // start listening 33} 34}

4. Test
First, run MinaTimeServer, start the server, and then run "telnet 127.0.0.1 9123" on the command line to log on. The server output is as follows:
16:15:29 org. apache. MINA. filter. logging. LogLevel $4 log
/10.64.2.133: 4140 IP address and port number
Information: CREATED
16:15:29 org. apache. MINA. filter. logging. LogLevel $4 log
Information: OPENED press enter on the client. on the client side, you can see that the server returns the current time:
Thu Feb 21 16:20:14 CST 2008
Server output:
16:20:14 org. apache. MINA. filter. logging. LogLevel $4 log
Information: RECEIVED ed: HeapBuffer [pos = 0 lim = 2 cap = 2048: 0D 0A] receives a carriage return.
Message written...
16:20:14 org. apache. MINA. filter. logging. LogLevel $4 log
Information: SENT: HeapBuffer [pos = 0 lim = 29 cap = 30: 54 68 75 20 46 65 62 20 32 31 20 31 36 3A 32 30...]
16:20:14 org. apache. MINA. filter. logging. LogLevel $4 log
Information: SENT: HeapBuffer [pos = 0 lim = 0 cap = 0: empty] 5. Client development example
First, define the class TimeClientHandler to process the message receiving event:

1 class TimeClientHandler extends IoHandlerAdapter {2 public TimeClientHandler () {3} 4 @ Override 5 public void messageReceived (IoSession session, Object message) throws Exception {6 System. out. println (message); // display the received message 7} 8} 9. then define the MinaTimeClient class to connect to the server and send the message to the server: 10 public class MinaTimeClient {11 public static void main (String [] args) {12 // create a client connector. 13 NioSocketConnector conne= new NioSocketConnector (); 14 connector. getFilterChain (). addLast ("logger", new LoggingFilter (); 15 connector. getFilterChain (). addLast ("codec", new ProtocolCodecFilter (new TextLineCodecFactory (Charset. forName ("UTF-8"); // sets the encoding filter 16 connector. setConnectTimeout (30); 17 connector. setHandler (new TimeClientHandler (); // sets event processor 18 ConnectFuture cf = connector. connect (19 new InetSocketAddress ("127.0.0.1", 9123); // establish a connection 20 cf. awaitUninterruptibly (); // wait until the connection is created. 21 cf. getSession (). write ("hello"); // send message 22 cf. getSession (). write ("quit"); // send message 23 cf. getSession (). getCloseFuture (). awaitUninterruptibly (); // wait for the connection to disconnect 24 connector. dispose (); 25} 26}

6. Summary
The preceding example shows that the code structure of network applications developed using the MINA framework is clearer, and the MINA framework completes the underlying thread management; the built-in encoder of MINA can meet the needs of most users, eliminating the need for developers to decode messages. It is said that the performance of the MINA server program has approached the network service developed in C/C ++ language. Therefore, we recommend that you use the MINA framework during network application development to improve our development efficiency and application execution efficiency.

 

 

II.

Client Communication Process 
1. Establish a connection with the server through socketconne
2. After the link is established, I/O reads and writes are handed over to the I/O Processor thread, and I/O Processor is multi-threaded.
3. data read through I/O Processor is filtered by all the iofilters and iofilters configured in IoFilterChain for message filtering and format conversion. At this level, some custom protocols can be developed.
4. Finally, IoFilter handed over the data to Handler for business processing to complete the entire read process.
5. the write process is similar, but the write process is just reversed through IoSession. write data, Handler processes the written business, and then hand it to IoFilterChain for message filtering and protocol conversion. Finally, data is written to the socket channel through I/O Processor.
IoFilterChain as the message filter chain
1. Reading is a process from low-level protocol to Advanced Protocol. In general, the process of gradually converting byte bytes into Business Objects
2. The write process is generally from the business object to byte.
IoSession throughout the communication process

The entire process can be presented in a diagram.
 
The message arrows are all initiated by NioProcessor-N threads. By default, they are also executed in NioProcessor-N threads.

Class Diagram 
Http://mina.apache.org/class-diagrams.html#ClassDiagrams-ProtocolDecoderclassdiagram

Connector 
As a Connection Client, SocketConector is used to establish a connection with the server. The connection is successful and IoProcessor Thread is created (cannot exceed the specified processorCount). Thread is managed by the specified Thread pool, ioProcessor processes IO using the NIO framework and creates an IoSession. The connection is established through Nio's SocketChannel.

NioSocketConnector conne= new niosocketprocctor (processorCount );
ConnectFuture future = connector. connect (new InetSocketAddress (HOSTNAME, PORT); Create an I/O channel

Acceptor 
As the server connection receiver, SocketAcceptor is used to listen to the port and establish a connection with the client. After the connection is established, all the I/O operations are handed over to IoProcessor for processing.
IoAcceptor acceptor = new NioSocketAcceptor ();
Acceptor. bind (new InetSocketAddress (PORT ));
Protocol 
IoFilter is used to decode and encode messages. For example, the following code uses MyProtocolEncoder to convert a java object into a byte string and uses MyProtocalDecoder to restore the byte string to a java object.

 1 connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new MyProtocalFactory())); 2 ...... 3 public class MyProtocalFactory implements ProtocolCodecFactory { 4  ProtocolEncoderAdapter encoder = new MyProtocolEncoder(); 5  ProtocolDecoder decoder = new MyProtocalDecoder() ; 6  public ProtocolDecoder getDecoder(IoSession session) throws Exception { 7   return decoder; 8  } 9  public ProtocolEncoder getEncoder(IoSession session) throws Exception {10   return encoder;11  }12 }13 ......14 public class MyProtocalDecoder extends ProtocolDecoderAdapter  {15 16  public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out)17    throws Exception {18   19   int  id  = in.getInt();20   int  len = in.getInt();21   byte[]  dst = new byte[len];22   23   in.get(dst);24   25   String name = new String(dst,"GBK");26   27   Item item = new Item();28   item.setId(id);29   item.setName(name);30   out.write(item);31  }32 }33 ......34 public class MyProtocolEncoder extends ProtocolEncoderAdapter {35 36  public void encode(IoSession session, Object message,37    ProtocolEncoderOutput out) throws Exception {38   Item item = (Item)message;39   int byteLen = 8 + item.getName().getBytes("GBK").length ;40   IoBuffer buf = IoBuffer.allocate(byteLen);41   buf.putInt(item.getId());42   buf.putInt(item.getName().getBytes("GBK").length);43   buf.put(item.getName().getBytes("GBK"));44   buf.flip();45   out.write(buf);46   47  }48 }

Handler 
Specific event handling: sessionCreated, sessionOpened, sessionClosed, sessionIdle, predictioncaught, messageReceived, and messageSent.
Connector. setHandler (new MyHandler (); MyHandler inherits the IoHandlerAdapter class or implements the IoHandler interface. The event is finally called by the IoProcessor thread.
Processor
The I/O Processor allows multi-thread read/write. in the development process, you only need to specify the number of threads. Processor performs the I/O continued write operation through the Nio framework. Processor contains references of the Nio Selector. This is also the advantage of mina. If you write Nio directly, you need to write your own code to implement functions similar to Processor. Because I/O Processor is read/write asynchronously, we sometimes need to identify the messages of the same task. For example, a task includes sending, receiving, and feedback messages, in this case, the message header must contain an id that can identify the same task.
Set the number of I/O Porcessor threads: If it is SocketConnector, you can specify it in the constructor, for example, new SocketConnector (processorCount, Executors. newCachedThreadPool (); For SocketAcceptor, the same is true: SocketAcceptor acceptor = new SocketAcceptor (ProcessorCount, Executors. newCachedThreadPool ());
ProcessorCount is the maximum number of Porcessor threads. This value can be optimized through performance tests. The default value is the number of cpu cores + 1 (Runtime. getRuntime (). availableProcessors () + 1 ).
What's strange is that each IoProcessor will locally establish a connection with itself during creation?

IoSession 
IoSession is used to maintain the context of IoService. An IoService establishes an IoSession (a session is connected) after the Connect operation is established, and the IoSession lifecycle ends from the Connection establishment to the disconnection.
IoSession performs two tasks:
1. IoSession can be used to obtain all configuration objects of IoService (holding references to IoService, Processor pool, SocketChannel, SessionConfig, and IoService. IoHandler)
2. Using IoSession. write is the entry for writing data.

About threads 
Http://mina.apache.org/configuring-thread-model.html
ThreadModel 1. x mina has the thread mode option after 2. x.
1.x specifies the thread mode
SocketConnectorConfig cfg = new SocketConnectorConfig ();
Cfg. setThreadModel (ThreadModel. MANUAL );

MINA has three worker threads. 
Acceptor, Connector, I/O processor thread
Acceptor Thread
Generally, as the receiving thread of the server link, the interface IoService is implemented. The number of threads is the number of SocketAcceptor creation.
Connector Thread
Generally, as a client request, a connection thread is established to implement the IoService interface and maintain a connection with the server-side Acceptor. The number of threads is the number of socketconneers created.

Mina's SocketAcceptor and SocketConnector both inherit the BaseIoService and are two different implementations of IoService.
I/O processor Thread 
As the thread that I/O actually processes, it exists on the server side and the client side and is used to process I/O read/write operations. The number of threads can be configured, the default maximum number is the number of CPUs + 1
Server: Specify ProcessorCount when creating a SocketAcceptor
SocketAcceptor acceptor = new SocketAcceptor (Runtime. getRuntime (). availableProcessors () + 1, Executors. newCachedThreadPool ());
Client: Specify ProcessorCount when creating socketconne
SocketConnector conne= new SocketConnector (Runtime. getRuntime (). availableProcessors () + 1, Executors. newCachedThreadPool ());
I/O Processor Thread is attached to IoService. Similar to the above example, SocketConnector conne= new SocketConnector (Runtime. getRuntime (). availableProcessors () + 1, Executors. newCachedThreadPool (); indicates that the SocketConnector Thread allows the CPU to + 1 I/O Processor Thread
Although NioProcessor is multi-thread, only one thread is used for processing the business processing when it is connected to a client (the Processor thread uses only one thread NioProcessor-n for a client connection) if handler's business is time-consuming, it will cause the NioProcessor thread to be congested. When two clients are connected at the same time, 2nd will be created (provided that 1st NioProcessor are busy ), the maximum number of IDs created is specified when the Acceptor constructor is used. If a client has a lot of communication with the server, and the I/O overhead is not large, but the Handler processes the business for a long time, it needs to adopt an independent thread mode, add an ExecutorFitler at the end of FilterChain:
Acceptor. getFilterChain (). addLast (& quot; threadPool & quot;, new ExecutorFilter (Executors. newCachedThreadPool ()));
In this way, the processor and handler threads are separated. Otherwise, the client sends three messages, and the server processes each message for about 10 seconds. Then, these three messages are processed in serial mode, when processing the first message, the subsequent message will be blocked, and the client will have the same problem.

Client Porcessor blocking test: 
1. the following code sends five messages (item) consecutively after the connection is established)
 

Java code
 1 ConnectFuture future = connector.connect(new InetSocketAddress(HOSTNAME, PORT)); 2                 future.awaitUninterruptibly(); 3                 session = future.getSession(); 4                 Item item = new Item(); 5                 item.setId(12345); 6                 item.setName("hi"); 7                 session.write(item); 8                 session.write(item); 9                 session.write(item);10                 session.write(item);11                 session.write(item);

2. The messageSent method of handle is delayed for 3 seconds.

1   public void messageSent(IoSession session, Object message) throws Exception {2         Thread.sleep(3000);3         System.out.println(message);4         5     }

3. Test Results
Five messages are sent in serial mode and are processed by the same IoPorcessor thread.

1   session.write(item);2                 session.write(item);3                 session.write(item);4                 session.write(item);5                 session.write(item);

4. ExecutorFilter is added. ExecutorFilter ensures that handler processing is a separate thread.
Connector. getFilterChain (). addLast (& quot; threadPool & quot;, new ExecutorFilter (Executors. newCachedThreadPool ()));
5. Test Results
Four sessions. wirte are converted into parallel processing, and the server receives five messages at the same time.

 


MINA framework reads and sends data

This melody also touched the stubborn stone
Branches attached
What's wrong, the endless night approaching me?
In the endless sleep of my time and you
We still have the courage to be a hero,
He silently misses you, haha.

MINA framework reads and sends data

This melody also touched the stubborn stone
Branches attached
What's wrong, the endless night approaching me?
In the endless sleep of my time and you
We still have the courage to be a hero,
He silently misses you, haha.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.