Author: Lao Jiu – technology big millet

Socializing: Zhihu

Public account: Lao Jiu School (Surprise for newcomers)

Special statement: the original is not easy, without authorization shall not be reproduced or copied, if you need to reproduce can contact the author authorized

preface

When it comes to developing game servers using the Java language, the Mina framework is a good first step.

What is a Mina

Mina is an open source web application framework that helps application programmers easily start high performance, high concurrency web applications. The Mina framework encapsulates both TCP/IP and UDP/IP protocols using Java NI, and the resulting encapsulation represents event-based asynchronous apis for application programmers to use.

Mina is also known as NIO Framework library, C/S Framework library, or Network socket library.

There are extended servers based on the MINA framework: Asyncweb, FtpServer and SSHd server.

The function of Mina

Mina provides the following common functions:

  • Provides a unified API interface for all transport types
    • TCP/IP and UDP/IP using Java NIO technology
    • Serial Communication using RXTX (RS232)
    • In-vm pipeline communication
    • The custom implementation provides a uniform API interface for all transport types
  • Fitler interface similar to Servlet technology filters
  • Low and high level apis
    • Use the ByteBuffers low-order API
    • A high-level API that uses custom message objects
  • Advanced custom threading model
    • Single thread
    • Single thread pool
    • Multiple thread pools
  • Basic IO streams are supported through StreamIoHandler

Server side code demo

package com.mr.game.server.app;
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{
	
    public void exceptionCaught( IoSession session, Throwable cause ) throws Exception
    {
        cause.printStackTrace();
    }

    
    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();
        String messge = "Hello(中文), today is " + date.toString();
        session.write("Your request: " + str);
        
        System.out.println("Message written..." + str);
    }

    
    public void sessionIdle( IoSession session, IdleStatus status ) throws Exception
    {
        System.out.println( "IDLE " + session.getIdleCount( status ));
    }
    
    public void sessionOpened(IoSession session) throws Exception{
		//none}}Copy the code
package com.mr.game.server.app;
import java.io.IOException;
import java.nio.charset.Charset;
import java.net.InetSocketAddress;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
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;
import org.apache.mina.core.session.IdleStatus;

/** * Features: This is the first Mina server application example *
public class App 
{
	private static final int PORT = 9123;
	
    public static void main( String[] args )
    {
    	// Define a receiver
        IoAcceptor acceptor = new NioSocketAcceptor();
        // Add logs
        acceptor.getFilterChain().addLast("logger".new LoggingFilter());
        acceptor.getFilterChain().addLast("codec".new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
        // Process client requests
        acceptor.setHandler(new TimeServerHandler());
        // Set the byte traffic unit for communication
        acceptor.getSessionConfig().setReadBufferSize(2048);
        acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
        try{
	        // Bind ports
	        acceptor.bind(new InetSocketAddress(PORT));
	        System.out.println("The mina server has been started.");
	    }catch(IOException e){ e.printStackTrace(); }}}Copy the code

summary

  • Mina is a framework that encapsulates Java NIO technology
  • Mina implements the concept of network asynchronous communication
  • Mina decouples the network’s physical communications from the business logic code, making it easy for application programmers to program

Mina framework principle

Mina architecture

Mina’s framework is shown below:

Mina encapsulates physical network communication mechanisms such as TCP/UDP/ serialization and virtual channel communication, leaving application programmers to focus on their own business logic.

  • Mina is divided into three levels
    • I/O service layer – Performs the actual I/O operations
    • I/O filter link layer – filters and transforms bytes into desired data structures
    • I/O handle layer – This is where the actual business logic code is placed
  • To create a basic Mina application, you must do the following steps
    • Create I/O Service Layer – Select a service that can be used (Acceptor) or create your own service
    • Create filter chain – Select an existing filter, or create one yourself
    • Create an I/O handle object — write business logic to process different messages

Server architecture

Server architecture

A server listens for network requests at a port, processes messages from the network, and responds to those network requests. Mina uses sessions to handle clients (TCP and UDP-based clients), and the IOAcceptor class listens for network connections and packets. With a new connection, mina will receive a new session object, and the packets received from the session will pass through the specified filter chain. Thus, the filter chain modifies the packet. For example, byte information can be converted into higher-order objects for use, and specific packets can be packaged and decoded. Finally, the objects are packaged/transformed into IOHandler, so the IOHandler is used to populate the business logic code.

summary

  • The MINA framework encapsulates a variety of physical underlying communication mechanisms, allowing application programmers to focus on business logic
  • The MINA framework is divided into three layers: IO service layer, filter link layer and handle layer
  • IOAcceptor objects encapsulate network physical links
  • The result of service object processing is a Sessions object
  • Inherit IoHandlerAdapter to implement the business logic

IoService service layer

IoService service

IoService is designed to abstract server network links, while IoConnector interfaces are designed to abstract client links. The IoService interface provides basic I/O services and manages the Session function of I/ OS. It is the most critical part of the MINA framework.

IoService provides the following functions

  • Session management: Create and delete sessions, and detect idle connections
  • Filter chain management: Handles filters, allowing users to modify the chain arbitrarily
  • Handle invocation: A processing handle is invoked when a message is received (based on event-driven concepts)
  • Statistics management: real-time update the number of messages sent, the number of bytes sent, etc
  • Listener management: Listens to the service so that clients can connect
  • Communication management: handles data transfer between communication parties

Core interface method

IoService,

IoService objects implement the two most important classes: IoAcceptor and IoConnector interfaces.

A server building a service needs to implement an IoAcceptor interface implementation class. The client needs to implement the IoConnector implementation class.

The IoAcceptor interface defines a business logic method, Accept (), that is responsible for creating a new connection. The server receives a network connection request.

Mina objects are available for various types of physical network connections. The following four IoAcceptor implementation classes are provided.

The IoService object implements the two most important classes: IoAcceptor and IoConnector interfaces. A server building a service requires an implementation class that implements an IoAcceptor interface. The IoAcceptor interface defines a business logic method, Accept (), that is responsible for creating a new connection. The server receives network connection requests for various types of physical network connections to mina objects. The following four IoAcceptor implementation classes are provided

summary

  • IoService is the core API of MINA
  • IoService encapsulates a variety of physical network connections, Four IoService implementation tool classes are provided :NioSocketAcceptor, NioDatagramAcceptor, AprSocketAcceptor, VmPipeSocketAcceptor
  • IoService provides session management, filter management, handle processing (message or event processing), and communication management

Sessions, filters, and event handling

The state of the Session

Session is the core of the MINA framework. Each time a new client connects to the server, a new session object is created and stored in memory to the client connection.

A session has three states:

  • The connection
  • idle
  • Shut down

Session is used to hold persistent information about the connection, as well as additional server information. This information is required by the server to process requests from the client and lasts for the lifetime of the session. A session has the following states during its lifetime:

  • Connected: A session is created and can be used
  • Idle: one does not process any requests
    • Idle for read: Indicates the Idle time for which no read is received from the session
    • Idle for Write: Indicates the Idle time for which no data is written to the session
    • Idle for both: time spent Idle without reading or writing
  • Closing: The state in which a session is Closing
  • Closed: INDICATES that a session has been Closed

The Session configuration

This configuration is required when using a Session. There are two configurations for a Session:

  • The standard configuration
    • Received buffer size
    • The size of the sent buffer
    • Idle time
    • Write timeout
  • Custom configurations, there may be additional information you need to know in addition to the above standard configurations. For example, the number of clients that need to know how many connections have been made.

Session is an implementation class that implements the Map interface and holds values in a key/value manner. When a session is created, a container is automatically created

Don’t store too much information in a session, or data structure content with a long lifetime. That is, the lifetime of the stored object cannot be longer than the lifetime of the session. Each session is associated with a chain of filters that are processed during network connection requests and message reads and writes

The default function of Session

Each session stores the following records

  • The number of bytes sent and received by the network
  • The number of messages sent and received by the network
  • To sit idle
  • throughput
  • Other useful information

Handle (event) handling. At least one handle (event) handling is associated with a session. This handle (event) is responsible for distributing messages to the application. The handle is also responsible for sending the packet of response through the session — using the write() method

Session. write(< message content >);

Learn about the default filters

Rewrite the event

When we inherit the IoAdapter instead of implementing the IoFilter interface directly, we need to rewrite the corresponding event handling methods.

Common event

summary

  • Session is the core of the MINA framework. There is a Session object for each client connection
  • Communication with the client is achieved through the read and write methods of the session
  • A session has three main states: connected, idle, and closed
  • A session is associated with a chain of filters that implement the event handling mechanism
  • Filters have 7 main events:
    • sessionCreate
    • sessionOpened
    • sessionClosed
    • sessionIdle
    • exceptionCaught
    • messageReceived
    • messageSent

Mina Core API presentation

Why use IoBuffer

  1. IoBuffer is a Mina application that uses byte buffer objects. It replaces the ByteBuffer class in the NIO package.
  2. There are two reasons not to use ByteBuffer
    • Getter and setter methods are not provided
    • It handles variable length data very well
  3. IoBuffer is an abstract class and therefore cannot be instantiated directly; you need to implement the allocate() method to do so

Set up and use buffers

There are two ways to set buffers

  • The default allocation for heap buffer — IoBuffer. SetUseDirectBuffer (false);
  • Return a heap buffer — IoBuffer buf = IoBuffer. Allocate (1024);

Create an automatically extensible buffer

  • IoBuffer buffer = IoBuffer.allocate(8);
  • buffer.setAutoExpand(true);
  • buffer.putString(“12345678”, encoder);
  • buffer.put((byte)10); // Add more to this buffer

Create a scalable buffer

  • IoBuffer buffer = IoBuffer.allocate(16);
  • buffer.setAutoShrink(true);
  • buffer.put((byte)1);
  • System.out.println(“Initial Buffer capacity = “+buffer.capacity());
  • buffer.shrink();
  • System.out.println(“Initial Buffer capacity after shrink = “+buffer.capacity());
  • buffer.capacity(32);
  • System.out.println(“Buffer capacity after incrementing capacity to 32 = “+buffer.capacity());
  • buffer.shrink();
  • System.out.println(“Buffer capacity after shrink= “+buffer.capacity());

Master ProtocolCodecFilter

TCP ensures that data packets are sent correctly, but does not guarantee that write operations on the sender can be read correctly on the receiver.

In Mina terminology, an IoSession. Write (message) operation without using the ProtocolCodecFilter results in multiple messageReceive events being received. And multiple IoSession. Write (message) operations can cause a single messageReceived event to occur. This will not happen if the server and client are on the same machine, but it will certainly happen on different machines.

Most web applications require the current message to end before the next message can be processed.

Application programmers can implement all of the above logic in IoHander classes, but it is easier to program using a ProtocolCodecFilter object. The ProtocolCodecFilter object is used to decouple network protocol logic from our business logic in IoHandler objects. Since our client is targeted at C++, the messages are transmitted as text strings, so that’s all we need to use on the server side.

summary

  • IoBuffer implements the scalable buffer function
  • ProtocolCodecFilter simplifies message encoding and decoding

The last

Remember to give dashu ❤️ attention + like + collect + comment + forward ❤️

Author: Lao Jiu School – technology big millet

Copyright belongs to the author. Commercial reprint please contact the author for authorization, non-commercial reprint please indicate the source.