1.什么是MINA?
Apache
MINA
是一个网络应用程序
框架
,用来帮助用户简单地开发高性能和高可扩展性的网络应用程序。它提供了一个通过
Java
NIO在不同的传输例如TCP/IP和UDP/IP上抽象的
事件驱动
的异步API。
Apache MINA 也称为:
● NIO 框架库
●
客户端服务器框架库
● 一个网络
套接字库
MINA框架的特点有:基于java NIO类库开发;采用非阻塞方式的异步传输;事件驱动;支持批量数据传输;支持TCP、UDP协议;控制反转的设计模式(支持Spring);采用优雅的松耦合架构;可灵活的加载过滤器机制;单元测试更容易实现;可自定义线程的数量,以提高运行于多处理器上的性能;采用回调的方式完成调用,线程的使用更容易
当远程客户首次访问采用MINA编写的程序时,IoAcceptor作为线程运行,负责接受来自客户的请求。当有客户请求连接时,创建一个IoSession,该IoSession与IoProcessor、SocketChannel以及IOService联系起来。IoProcessor也作为另外一个线程运行,定时检查客户是否有数据到来,并对客户请求进行处理,依次调用在IOService注册的各个IoFilter,最后调用IoHandler进行最终的逻辑处理,再将处理后的结果Filter后返回给客户端。
1.3Mina的现有应用
1.3Mina的现有应用
MINA框架的应用比较广泛,应用的开源项目有Apache Directory、AsyncWeb、ApacheQpid、QuickFIX/J、Openfire、SubEthaSTMP、red5等。MINA框架当前稳定版本是1.1.6,最新的2.0版本目前已经发布了M1版本
二.MINA框架具体技术
2.1MINA框架的常用类
1.类NioSocketAcceptor
用于创建服务端监听
2.类NioSocketConnector
用于创建客户端连接;
3.类IoSession
用来保存会话属性和发送消息;可以理解为服务器与客户端的特定连接,该连接由服务器地址、端口以及客户端地址、端口来决定。客户端发起请求时,指定服务器地址和端口,客户端也会指定或者根据网络路由信息自动指定一个地址、自动分配一个端口。这个地址、端口对构成一个Session。
1.类NioSocketAcceptor
用于创建服务端监听
2.类NioSocketConnector
用于创建客户端连接;
3.类IoSession
用来保存会话属性和发送消息;可以理解为服务器与客户端的特定连接,该连接由服务器地址、端口以及客户端地址、端口来决定。客户端发起请求时,指定服务器地址和端口,客户端也会指定或者根据网络路由信息自动指定一个地址、自动分配一个端口。这个地址、端口对构成一个Session。
5.类IoFilter
IoFilter用来对客户的请求或发送给客户的数据进行filter。与IoHandler一样,Filter也是基于事件的,通过实现IoFilter接口,就可以对通信过程中的Session的事件进行处理。
6.Event
MINA可以看成是事件驱动的。通常在网络通讯中,可以将整个过程划分为几个基本的阶段,如建立连接、数据通信、关闭连接。
数据通信一般包括数据的发送和接收,由于在通信过程中,可能要多次发送和接收数据,以进行不同的业务交互。不可能一直都接收和发送数据,因此就有Idle出现,在MINA中,如果在设定的时间内没有数据发送或接收,那么就会触发一个Idle事件。由于某种原因,可能会发生错误,导致系统异常发生,引发exception。因此,如果从事件发生的角度看的话,就可以在MINA中将通信看成由一个建立链接(sessionCreated 和 sessionOpened )、多个数据接收和发送、一个关闭连接事件以及多个Idle事件等7种事件组成的过程。
Session是对双方相互通信的抽象,因此通信的过程就是一系列与Session相关的事件。
在MINA现在对TCP的实现中,sessionCreated 和 sessionOpened 没有区别。因此严格来说,有6种类型的事件。
三、代码事例
功能描述:编写一个服务器监听客户机的程序,当客户机访问服务器的时候,服务器输出客户机的访问信息(http),然后将访问信息和第几位客户告诉客户机。
处理器代码:
SamplMinaServerHandler.java
package com.javake.mina.sampleserver;
import org.apache.mina.common.IoHandlerAdapter;
import org.apache.mina.common.IoSession;
public class SamplMinaServerHandler extends IoHandlerAdapter {
//当一个客端端连结进入时
@Override
public void sessionOpened(IoSession session) throws Exception {
System.out.println("incomming client : "+session.getRemoteAddress());
}
//当一个客户端关闭时
@Override
public void sessionClosed(IoSession session) {
System.out.println("one Clinet Disconnect !");
}
//当客户端发送的消息到达时:
@Override
public void messageReceived(IoSession session, Object message)
throws Exception {
//我们己设定了服务器解析消息的规则是一行一行读取,这里就可转为String:
String s=(String)message;
// Write the received data back to remote peer
System.out.println("收到客户机发来的消息: "+s);
//测试将消息回送给客户端
session.write(s+count);
count++;
}
private int count=0;
}
启动服务器的主类:
MainServer.java
package com.javake.mina.sampleserver;
import java.net.InetSocketAddress;
import org.apache.mina.common.DefaultIoFilterChainBuilder;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.transport.socket.SocketAcceptor;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
public class MainServer {
public static void main(String[] args) throws Exception {
//创建一个非阻塞的Server端Socket,用NIO
SocketAcceptor acceptor = new NioSocketAcceptor();
//创建接收数据的过滤器
DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();
//设定这个过滤器将一行一行(/r/n)的读取数据
chain.addLast("myChin", new ProtocolCodecFilter(new TextLineCodecFactory()));
//设定服务器端的消息处理器:一个SamplMinaServerHandler对象,
acceptor.setHandler(new SamplMinaServerHandler());
// 服务器端绑定的端口
int bindPort=9988;
//绑定端口,启动服务器
acceptor.bind(new InetSocketAddress(bindPort));