>  기사  >  백엔드 개발  >  Apache Mina 연구 노트(2) - 기본 사항

Apache Mina 연구 노트(2) - 기본 사항

黄舟
黄舟원래의
2017-01-18 09:48:241081검색

1장에서는 MINA에 대한 전반적인 이해를 했습니다. 이번 장에서는 MINA의 클라이언트/서버 모델을 자세히 분석하겠습니다. 그리고 TCP와 UDP를 기반으로 한 몇 가지 예도 제공됩니다.

애플리케이션 구조

서버 구조
클라이언트 구조

단순 TCP 서버
단순 TCP 클라이언트
단순 UDP 서버
단순 UDP 클라이언트

애플리케이션 구조 요약

MINA 프레임워크를 사용한 애플리케이션 구조는 다음과 같다.

Apache Mina 연구 노트(2) - 기본 사항

위에서 볼 수 있듯이 그림에서 MINA는 애플리케이션과 네트워크의 하위 계층을 연결하는 중간 계층 역할을 하며 TCP, UDP는 물론 직렬 통신 프로토콜(RS-232C)까지 처리할 수 있으므로 MINA에서 애플리케이션을 설계하는 데 더 집중할 수 있습니다. 기본 네트워크 통신의 복잡성을 이해할 필요가 없습니다.

MINA 내부 모습은 다음과 같습니다.

Apache Mina 연구 노트(2) - 기본 사항

일반적으로 MINA 애플리케이션은 세 개의 레이어로 나뉩니다.

I/O 서비스 - 실제 I/O 작업
I/O 필터 체인 - 데이터 필터링/전송
I/O 핸들러 - 여기에서 프로그램 논리 완성

따라서 MINA 애플리케이션을 생성하려면 다음 작업만 수행하면 됩니다.

I/O 서비스 생성 - 이미 제공된 서비스(Acceptor) 선택 또는 자체 서비스 생성
필터 체인 생성 - 이미 제공된 서비스 선택 서비스 필터 체인 또는 자신만의 맞춤형 필터 체인 생성
I/OHandler 생성 - 비즈니스 로직 작성 및 다양한 메시지 처리 위는 MINA의 전체 구조입니다. 서버 측:

Apache Mina 연구 노트(2) - 기본 사항간단히 말하면 서버 측에는 들어오는 연결이나 데이터 패킷을 수신하는 I/O Acceptor가 있습니다. 새 세션이 생성되고 이 연결에서 들어오는 후속 요청은 이 세션에서 처리됩니다. 모든 패킷은 세션에서 수락되고 위 그림에 표시된 필터링 체인을 통과합니다. 필터 체인은 패키지의 내용을 수정하는 데 사용됩니다(예: 개체로 변환, 일부 정보 추가 또는 제거). 마지막으로 이러한 패킷은 IOHandler에 의해 처리됩니다. 주목해야 할 또 다른 점은 연결이 도착하면 세션이 설정되며 연결 성공 여부에 관계없이 세션이 설정된다는 것입니다.

클라이언트 모델은 다음과 같습니다.

Apache Mina 연구 노트(2) - 기본 사항



클라이언트 및 서버입니다. 정확히 반대 상태.

클라이언트에는 서버에 연결하기 위한 IOConnector가 있습니다. 그리고 모든 처리는 여전히 IOHandler에 의해 완료됩니다.

간단한 TCP 서버

다음으로 데모로 간단한 TCP 서버를 만듭니다. 먼저 일부 필수 패키지를 IDE로 가져오거나 CLASSPATH를 구성해야 합니다. 구체적인 방법은 자세히 설명하지 않습니다. 예, 필수 패키지는 다음과 같습니다:

MINA 2.x Core
JDK 1.5 이상
SLF4J 1.3.0 이상

Log4J 1.2 사용자: slf4j-api.jar , slf4j-log4j12.jar 및 Log4J 1.2.x
Log4J 1.3 사용자: slf4j-api.jar, slf4j-log4j13.jar 및 Log4J 1.3.x
java.util.logging 사용자: slf4j-api. jar 및 slf4j-jdk14.jar
중요: 로깅 프레임워크와 일치하는 올바른 slf4j-*.jar을 사용하고 있는지 확인하세요.

준비가 완료되면 코드 작성을 시작합니다

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) );  
    }  
}

다음으로 위 코드에 필터 체인 구성을 추가합니다.

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) );  
    }  
}

다음으로 메시지를 처리하는 데 사용되는 핸들러를 정의해야 합니다. 이 핸들러 클래스는 IoHandler 인터페이스를 구현해야 합니다. MINA에서 이 핸들러는 프로그램 개발의 핵심입니다. 이 튜토리얼에서는 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 ));  
    }  
}

마지막으로 전체 서버 코드는 다음과 같습니다.

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) );  
    }  
}

서버를 실행한 후 터미널을 열고 telnet 127.0.0.1 9123 명령을 입력합니다. 입력하면 알 수 있습니다. "quit" 이외의 문자가 있으면 서버는 현재 시간을 터미널에 반환합니다.

간단한 TCP 클라이언트

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) {
rrree
UDP 예제는 작성하지 않겠습니다. 필요하다면 아파치 공식 홈페이지에 가서 살펴보세요.

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

위는 Apache Mina입니다. 학습 주의사항 (2) - 기본 내용, 더 많은 관련 내용은 PHP 중국어 홈페이지(www.php.cn)를 참고해주세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.