apache mina是一款可用于开发高性能和高伸缩性网络应用的框架,全称是Multipurpose Infrastructure for Network Applications。主要是基于TCP/IP或者是UDP/IP协议,其高性能主要利用Java NIO的非阻塞式复用通道。mina框架主要包括这么几个核心部分,一个 connector(连接server端用,这个非必须,可以用telnet来远程访问server端),一个acceptor(响应客户端请求用),一个Iohandler(业务数据处理用),一个IoFilterChain(主要用来完成日志记录,协议转换和其他一些需求)。大概业务员过程如下图:具体图不知道怎么上传,具体可以看http://shuofenglxy.blog.163.com/blog/static/172625123201101110727115/ 这个地址,也是我的blog
来看一个比较简单的demo来看看到底mina是怎么work.在看demo之前,先要准备好环境,这个应用主要需要下面的四个jar包: mina-core-2.0.2.jar ,slf4j-api-1.5.11.jar , slf4j-jcl-1.5.8.jar以及commons-logging-1.0.3.jar。
demo示例如下:
server端:
package minaDemo;
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.ProtocolCodecFactory;
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.NioSocketAcceptor;
public class MessageSendServer {
private static final int port = 11111;
public static void main(String[]args) throws IOException{
//服务端监听端口用
IoAcceptor acceptor = new NioSocketAcceptor();
//日志filter
acceptor.getFilterChain().addLast("logger", new LoggingFilter());
//对象序列化工厂,用来将java对象序列化成二进制流
acceptor.getFilterChain().addLast(
"Objectcodec",
new ProtocolCodecFilter(
(ProtocolCodecFactory) new ObjectSerializationCodecFactory()));
//业务处理handler
acceptor.setHandler(new ServerHandler());
//设置监听端口
acceptor.setDefaultLocalAddress(new InetSocketAddress(port));
//开启了监听accptor
acceptor.bind();
System.out.println("Server starts to listen to PORT :"+port);
}
}
serer handler类:
package minaDemo;
import org.apache.mina.core.future.WriteFuture;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import java.util.*;
public class ServerHandler extends IoHandlerAdapter{
@Override
public void messageReceived(IoSession session,Object message)throws Exception{
Message receivedMsg = (Message)message;
if("quit".equalsIgnoreCase(receivedMsg.getContent())){
System.out.println("Session closed");
session.close(true);
}
receivedMsg.setContent("Server response :"+receivedMsg.getContent());
receivedMsg.setDate(Calendar.getInstance().getTime());
WriteFuture future = session.write(receivedMsg);
future.awaitUninterruptibly();
System.out.println("Successfully response to "+session.getRemoteAddress().toString());
}
@Override
public void exceptionCaught(IoSession session, Throwable cause)throws Exception{
session.close(true);
}
}
package minaDemo;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.util.Calendar;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.future.WriteFuture;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFactory;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
public class MessageSendClient {
public static void main(String[] args) throws IOException, InterruptedException {
NioSocketConnector connector = new NioSocketConnector();
connector.getFilterChain().addLast("logger", new LoggingFilter());
connector.getFilterChain().addLast(
"Objectcodec",
new ProtocolCodecFilter((ProtocolCodecFactory) new ObjectSerializationCodecFactory()));
connector.setConnectTimeoutMillis(3000);
connector.setHandler(new ClientHandler());
ConnectFuture cf = connector.connect(new InetSocketAddress("127.0.0.1",
11111));
cf.awaitUninterruptibly();
IoSession session = cf.getSession();
BufferedReader systemIn = new BufferedReader(new InputStreamReader(System.in));
long count =0;
while(true){
String input =systemIn.readLine();
Message msg = new Message();
if(input==""||"quit".equalsIgnoreCase(input.trim())){
msg.setContent(input);
WriteFuture future =session.write(msg);
future.awaitUninterruptibly(3000);
System.out.println("send quit cmd successfully");
session.getCloseFuture().awaitUninterruptibly();
connector.dispose();
System.exit(0);
}
msg.setContent(input);
msg.setId(count);
msg.setDate(Calendar.getInstance().getTime());
count++;
WriteFuture future = session.write(msg);
future.awaitUninterruptibly(3000);
System.out.println("send "+msg.getId()+ " successfully");
Thread.sleep(10000);
}
}
}
客户端handler:
package minaDemo;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
public class ClientHandler extends IoHandlerAdapter{
@Override
public void messageReceived(IoSession session, Object message)
throws Exception {
Message m = (Message)message;
System.out.println(m.getId()+" "+m.getContent()+" "+m.getDate());
}
@Override
public void exceptionCaught(IoSession session, Throwable cause)throws Exception{
session.close(true);
}
}
通过以上简单的代码 一个简单的c/s通信demo就完成了。这里面全部是采用了mina的相关接口来实现。接下来几篇文章会用来分析mina的线程模式,IofilterChain,ProtocalFactory这几个比较重要的点。