您的位置:首页 > 其它

MINA 快速入门指南(收藏)

2008-10-16 08:52 507 查看
最近用到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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: