MINA 快速入门指南(收藏)

 最近用到Socket套接字编程,在服务器监听方面还没有具体思路,朋友推荐了ApahceMina,就在官方看了一下快速入门文档。原文是英文的,学习之余就将它翻译出来和大家共享!关于Mina的中文简介内容不多就摘抄了一些。

      “MINA是一个Socket的网络框架,但是它提供了方便的Protocol支持,通过它的Encoder和Decoder,你将你的应用可以方便的扩 展并支持各种基于Socket的网络协议,比如HTTP服务器、FTP服务器(当然,这很复杂)、Telnet服务器等等。基于MINA用户可以容易地开 发高性能和高伸缩性的网络应用程序。”

下面是对官方入门文档的中文译版,由于完全参照官方文档在程序具体运行时遇到一些import不足的情况,在示例源码的import部门是我在亲自实践后修改过的,其他的地方都和原文一样。

MINA 快速入门指南

一、准备工作

本文将演示给大家一个基于MINA程序的创建过程,示例将构建一个定时器服务。
以下是作为先决条件的软件包:
1,Mina 1.1 Core
2,JDK 1.5 or greater
3,SLF4J 1.3.0 or greater :
     Log4J 1.2 users: slf4j-api.jar, slf4j-log4j12.jar, and Log4J 1.2.x
     Log4J 1.3 users: slf4j-api.jar, slf4j-log4j13.jar, and Log4J 1.3.x
     java.util.logging users: slf4j-api.jar and slf4j-jdk14.jar
     注意:首先请确认你使用了正确的slf4j-*.jar 。比如说slf4j-log4j12.jar 和log4j-1.3.x.jar 是不能在一起使用的将会出现功能障碍。
(我用了1.2系列,那么所有的软件包就是:
log4j-1.2.14.jar;
mina-core-1.1.2.jar;
slf4j-api-1.2.jar;
slf4j-jdk14-1.2.jar;
slf4j-log4j12-1.2.jar)

      作者在Windows2000 professional和linux系统下均做了测试,如果你的程序不能运行,请尽快和我们联系共同完善MINA的开发工作。当然,本文的示例是独立于 开发环境的,你可以使用你所喜欢的任何IDE,编辑器等等。程序的运行和编译步骤在本文中不做赘述,如果你要学习怎样编译java程序可以从Java tutorial文档中获得帮助。

二、编写MINA time server

我们首先创建一个MinaTimeServer.java文件,代码如下:
public class MinaTimeServer {

      public static void main(String[] args) {
       // code will go here next
      }
}
以上代码简单直接,我们仅仅定义了一个mian方法来作为程序的入口。下面我们开始添加代码来完善我们的定时器服务。
首先,我们需要一个用来监听接入连接的对象。由于程序是基于TCP/IP协议的,所以我们给程序添加一个SocketAcceptor对象。
import org.apache.mina.common.IoAcceptor;
import org.apache.mina.transport.socket.nio.SocketAcceptor;

public class MinaTimeServer {

      public static void main(String[] args) {
          // The following two lines change the default buffer type to 'heap',
          // which yields better performance.
          ByteBuffer.setUseDirectBuffers(false);
          ByteBuffer.setAllocator(new SimpleByteBufferAllocator());

          IoAcceptor acceptor = new SocketAcceptor();
      }
}
有了SocketAcceptor,我们给它绑定一个端口来继续定义操作类。对给SocketAcceptor添加线程模块感兴趣的朋友可以阅读这篇文章“ Configuring Thread Model”。
现在我们为SocketAcceptor添加设置。它允许我们为Socekt配置明确套接字用于允许来自客户端的连接。
import java.io.IOException;
import java.net.InetSocketAddress;
import org.apache.mina.common.IoAcceptor;
import org.apache.mina.transport.socket.nio.SocketAcceptor;

public class MinaTimeServer {

      private static final int PORT = 9123;

      public static void main(String[] args) throws IOException {
          ByteBuffer.setUseDirectBuffers(false);
          ByteBuffer.setAllocator(new SimpleByteBufferAllocator());

          IoAcceptor acceptor = new SocketAcceptor();

          SocketAcceptorConfig cfg = new SocketAcceptorConfig();
          cfg.getFilterChain().addLast( "logger", new LoggingFilter() );
          cfg.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" ))));
      }
}
这里创建了一个SocketAcceptorConfig类的实例用于当我们每次准备启动acceptor的时候进入这个acceptor。
首先,我们设置一个重用地址标识。从 JDK Documentation可以了解更多关于这里的知识。然后我们在配置中添加一个过滤器。
这个过滤器filter将纪录所有信息,例如最近创建的sessions,收到的消息,发送的消息,session关闭。下一个过滤器是一个ProtocolCodecFilter。这个过滤器可以将二进制数据或编码协议数据转换
成消息对象和代替算法。
下面的部分来为acceptor绑定端口。这个方法标志着服务器进程的启动,如果这个方法没有被调用,服务器将不会与客户端进行连接。
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;

import org.apache.mina.common.ByteBuffer;
import org.apache.mina.common.IoAcceptor;
import org.apache.mina.common.SimpleByteBufferAllocator;
import org.apache.mina.transport.socket.nio.SocketAcceptor;
import org.apache.mina.filter.LoggingFilter;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.transport.socket.nio.SocketAcceptorConfig;

public class MinaTimeServer {

      private static final int PORT = 9123;

      public static void main(String[] args) throws IOException {
          ByteBuffer.setUseDirectBuffers(false);
          ByteBuffer.setAllocator(new SimpleByteBufferAllocator());

          IoAcceptor acceptor = new SocketAcceptor();

          SocketAcceptorConfig cfg = new SocketAcceptorConfig();
          cfg.getFilterChain().addLast( "logger", new LoggingFilter() );
          cfg.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" ))));

          acceptor.bind( new InetSocketAddress(PORT), new TimeServerHandler(), cfg);
          System.out.println("MINA Time server started.");
      }
}

以上你看到的就是我们定义了一个int型的port变量,然后调用了SocketAcceptor.bind(SocketAddress,IoHandler)方法。
     第一个参数SocketAddress描述了我们监听的网络地址,在这里是端口9123和本地地址。
     第二个参数是一个必须继承 IoHandler接口的类。对于所有应用MINA的程序来说这都是一个服务于所有来自客户端接入请求的骨干部分。在本文中我们继承了IoHandlerAdapter类。
这个类尊从 adapter design pattern(适配器设计模式),从而大大简化了为了响应进入继承自IoHandler接口的类中的请求的代码的数量。
     第三个参数cfg是一个被配置了日志过滤器和编码过滤器的配置信息对象。MINA被用于像那些所有接收到的信息都要穿过为IOAcceptor定义的过滤器链中的所有过滤器。日志过滤器
使用SL4J类库纪录简单的日志信息,编码过滤器codec filter 通过TextLineCodecFactory类对每个接收的信息进行解码decode,对每个发送的信息进行encode编码。
下面是TimeServerHandler类:

import java.util.Date;

import org.apache.mina.common.IdleStatus;
import org.apache.mina.common.IoHandlerAdapter;
import org.apache.mina.common.IoSession;
import org.apache.mina.common.TransportType;
import org.apache.mina.transport.socket.nio.SocketSessionConfig;

public class TimeServerHandler extends IoHandlerAdapter {
public void exceptionCaught(IoSession session, Throwable t) throws Exception {
    t.printStackTrace();
    session.close();
}

public void messageReceived(IoSession session, Object msg) throws Exception {
    String str = msg.toString();
    if( str.trim().equalsIgnoreCase("quit") ) {
     session.close();
     return;
    }

    Date date = new Date();
    session.write( date.toString() );
    System.out.println("Message written...");
}

public void sessionCreated(IoSession session) throws Exception {
    System.out.println("Session created...");

    if( session.getTransportType() == TransportType.SOCKET )
     ((SocketSessionConfig) session.getConfig() ).setReceiveBufferSize( 2048 );

          session.setIdleTime( IdleStatus.BOTH_IDLE, 10 );
}
}
这里我们有了示例程序的操作部分的代码。我们覆盖了一些方法exceptionCaught、messageReceived和 sessionCreated。按照之前的约定,这个类继承遵从适配器设计模式的IoHandlerAdapter类。exceptionCaught 方法将打印简单的错误信息和关闭session。对于大多数程序来说,除非操作类可以再覆盖异常处理,这都是标准的业务操作。
     messageReceived 方法接收来自客户端的消息并在当前时间回写消息给客户端。如果从客户端接收来的消息是“quit”则关闭连接。这个方法也向客户端打印当前时间。
基于你使用的编码协议,穿过这个方法的第二个参数对象“Object msg”将是不同的,和进入session.write(Object)方法的对象相同。如果你没有明确指定一个编码协议,
你将很有可能接收到一个ByteBuffer 对象,而且被要求输出一个ByetBuffer对象。
     sessionCreated方法是典型的session初始化重现。在这种情况下,我们打印出进入方法的对象来测试session的转换类型是否是基于 Socket的,然后设置接收缓冲大小。下面将输入缓冲池的大小设置为2048字节。将空闲时间设成10秒。如果我们覆盖sessionIdle方法,该 方法将每10秒被调用一次。

三、启动Timeserver
现在 我们可以编译运行这个程序。当程序运行时可以看到测试结果。最简单的办法是启动程序然后登陆telnet访问程序:
Client Output

user@myhost:~> telnet 127.0.0.1 9123
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
hello
Mon Apr 09 23:42:55 EDT 2007
quit
Connection closed by foreign host.
user@myhost:~>    MINA Time server started.

Server Output

MINA Time server started.
Session created...
Message written...

原文地址:http://mina.apache.org/quick-start-guide.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值