一、MINA框架简介
Apache MINA(Multipurpose Infrastructure for Network Applications) 是用于开发高性能和高可用性的网络应用程序的基础框架,它对Java中的socket和NIO进行了有效和清晰的封装,方便开发人员开发TCP/UDP程序,从而抛开在使用原始的socket时需要考虑的各种繁杂而又烦人问题(线程、性能、会话等),把更多精力专著在应用中的业务逻辑的开发上。
二、MINA框架的常用类:
IoAccepter 相当于服务器端
IoConnector 相当于客户端
IoSession 当前客户端到服务器端的一个连接实例
IoHandler 业务处理逻辑
IoFilter 过滤器用于悬接通讯层接口与业务层接口
三、范例源代码
下面的介绍以 Apache MINA 1.1.7 为例,需要JDK 5.0以上版本,还需要slf4j的jar包。
1、服务器端主类源代码
public class Server {
public static final int PORT = 8080;
public static void main(String[] args) {
try{
IoAcceptor acceptor = new SocketAcceptor();
SocketAcceptorConfig config = new SocketAcceptorConfig();
config.setReuseAddress(true);
//使用字符串编码
//config.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
config.getFilterChain().addLast("codec", new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));
//config.getFilterChain().addLast("logger", new LoggingFilter());
//启动HelloServer
acceptor.bind(new InetSocketAddress(PORT), new ServerSessionHandler(acceptor), config);
System.out.println("Server started on port " + PORT);
}catch(Exception ex){
ex.printStackTrace();
}
}
}
2、服务端业务处理逻辑类源代码
public class ServerSessionHandler extends IoHandlerAdapter {
private IoAcceptor acceptor;
public ServerSessionHandler(IoAcceptor acceptor){
this.acceptor = acceptor;
}
/**
* 有新连接时触发
*/
public void sessionOpened(IoSession session) throws Exception {
session.setIdleTime(IdleStatus.BOTH_IDLE, 60); //session可允许空闲的最大秒数
//session.setAttribute("times", new Integer(0)); //设置session属性值
Set set = acceptor.getManagedSessions(new InetSocketAddress(Server.PORT));
long count = 0;
if(set!=null) count = set.size();
System.out.println("受管理的连接数:" + count);
}
/**
* 收到消息时触发
*/
public void messageReceived(IoSession session, Object message)throws Exception {
Message msg = (Message)message;
msg.setMsgBody("in server side: " + msg.getMsgBody());
session.write(msg);
}
/**
* session超过最大允许空闲时间时触发
*/
public void sessionIdle(IoSession session, IdleStatus status)throws Exception {
System.out.println("Disconnecting the idle");
session.close();
}
/**
* 连接关闭时触发
*/
public void sessionClosed(IoSession session) throws Exception {
System.out.println("session closed from " + session.getRemoteAddress());
Set set = acceptor.getManagedSessions(new InetSocketAddress(Server.PORT));
long count = 0;
if(set!=null) count = set.size();
System.out.println("受管理的连接数:" + count);
}
/**
* 异常发生时触发
*/
public void exceptionCaught(IoSession session, Throwable cause)throws Exception {
cause.printStackTrace();
session.close();
}
}
3、客户端主类源代码
public class Client {
private static final String HOSTNAME = "localhost";
private static final int PORT = 8080;
private static final int CONNECT_TIMEOUT = 30; //seconds
public void sendMessage(String msg){
SocketConnector connector = new SocketConnector();
SocketConnectorConfig config = new SocketConnectorConfig();
config.setConnectTimeout(CONNECT_TIMEOUT);
config.getFilterChain().addLast("codec", new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));
//config.getFilterChain().addLast("logger", new LoggingFilter());
Message message = new Message(1, msg);
connector.connect(new InetSocketAddress(HOSTNAME, PORT), new ClientSessionHandler(message), config);
}
public static void main(String[] args) {
for(int i=1;i<=5;i++){
Client client = new Client();
client.sendMessage("cjm_" + i);
}
}
}
4、客户端业务逻辑处理类源代码
public class ClientSessionHandler extends IoHandlerAdapter {
private Object msg;
public ClientSessionHandler(Object msg){
this.msg = msg;
}
public void sessionOpened(IoSession session) throws Exception {
session.write(this.msg);
}
public void messageReceived(IoSession session, Object message)throws Exception {
Message rm = (Message) message;
System.out.println("message is: " + rm.getMsgBody());
//session.write(rm);
//session.close();
}
public void sessionClosed(IoSession session) throws Exception {
System.out.println("session closed from Client");
}
public void exceptionCaught(IoSession session, Throwable cause)throws Exception {
session.close();
}
}
5、Message类源代码
public class Message implements Serializable{
private static final long serialVersionUID = 1L;
private int type;
private String msgBody;
public Message(int type, String msgBody){
this.type = type;
this.msgBody = msgBody;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getMsgBody() {
return msgBody;
}
public void setMsgBody(String msgBody) {
this.msgBody = msgBody;
}
}