ホームページ  >  記事  >  バックエンド開発  >  Apache min 学習ノート (2) - 基礎

Apache min 学習ノート (2) - 基礎

黄舟
黄舟オリジナル
2017-01-18 09:48:241127ブラウズ

第 1 章では、MINA について一般的に理解しました。この章では、MINA のクライアント/サーバー モデルを詳細に分析します。 TCP と UDP に基づくいくつかの例も提供されます。

アプリケーション構造

サーバー構造
クライアント構造

シンプルな TCP サーバー
シンプルな TCP クライアント
シンプルな UDP サーバー
シンプルな UDP クライアント

アプリケーション構造の概要

MINA フレームワークを使用したもの アプリケーション構造は次のとおりです。

上の図からわかるように、MINA はアプリケーションとネットワークの最下層を接続する中間層として機能し、TCP、UDP、さらにはシリアル通信プロトコル (RS-232C) も処理できるため、次のことが可能です。基盤となるネットワーク通信の複雑さを理解せずに、MINA 上のアプリケーションの設計に重点を置くことになります。 Apache min 学習ノート (2) - 基礎

MINA の内部を見てみましょう:



一般的に、MINA アプリケーションは 3 つのレイヤーに分かれています。 Apache min 学習ノート (2) - 基礎

I/O サービス - 実際の I/O 操作

I/O フィルター チェーン - データのフィルター/送信
I/O ハンドラー - ここでプログラムのロジックを完成させます

したがって、MINA アプリケーションを作成するには、必要なのは Do :

I/O サービスの作成 - 提供されたサービス (アクセプター) を選択するか、独自のサービスを作成します
フィルター チェーンの作成 - 提供されたフィルター チェーンを選択するか、独自にカスタマイズしたフィルター チェーンを作成します
I/OHandler の作成 - ビジネス ロジックを作成し、さまざまな処理を行います上記は MINA の全体的な構造です

サーバー側の構造を見てみましょう:


簡単に言えば、今後の接続またはデータを監視するための I/O アクセプターがあります。新しい接続が到着すると、新しいセッションが作成され、この接続からの後続のリクエストはこのセッションで処理されます。すべてのパケットはセッションによって受け入れられ、上の図に示されているフィルタリング チェーンを通過します。フィルター チェーンは、パッケージの内容を変更する (オブジェクトへの変換、情報の追加または削除など) ために使用されます。最後に、これらのパケットは IOHandler によって処理されます。もう 1 つ注意すべき点は、接続が到着すると、接続が成功したかどうかに関係なく、セッションが確立されることです。 Apache min 学習ノート (2) - 基礎

以下はクライアント モデルです:



Apache min 学習ノート (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。 、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 では、この Handler がプログラム開発の鍵となります。このチュートリアルでは、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) {
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();  
      }  
  }

UDP の例はここには書かれていません。必要に応じて、Apache 公式 Web サイトにアクセスしてご覧ください。



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

上記は、Apache Min 学習ノート (2) - 基本的な内容、その他の関連事項です。 PHP 中国語 Web サイト (www.php.cn) のコンテンツに注目してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。