Apache MINA是一个网络应用程序框架,用来帮助用户简单地开发高性能和高可靠性的网络应用程序。它提供了一个通过Java NIO在不同的传输例如TCP/IP和UDP/IP上抽象的事件驱动的异步API。
其中几个主要的组件如下:
I/O Service - 用来处理I/O流,对于Server端就是IOAcceptor的实现类接受Client端的连接请求,对于Client端就是IoConnector的实现类来建立到Server端的连接。
I/O Filter Chain - 用来过滤或转化数据。对于Server端和Client端来说都是IoFilter接口的实现类,MINA自己内建了很多IoFilter接口的实现类。具体可以参考官方文档。
I/O Handler - 用来处理真正业务逻辑的类。对于Server端和Client端来说都是IoHandler接口的实现类,通常来说需要自己编写。
由于Server端和Client端都是基于以上三个组件的,因此对于Server端和Client端编程来说就都有类似的代码结构。
对于Server端来说:
1. 创建I/O service - 这里就是创建IOAcceptor类监听端口。
2. 创建I/O Filter Chain - 这里就是告诉使用那些IoFilter。
3. 创建I/O Handler - 自己的业务逻辑。
对于Client端来说:
1. 创建I/O service - 这里就是创建IOConnector类来建立到Server端的连接。
2. 创建I/O Filter Chain - 这里就是告诉使用那些IoFilter。
3. 创建I/O Handler - 自己的业务逻辑。
对于简单的传输字符串,对mina来说是小菜一碟,当然它也可以用来传输对象。其基本过程为对象(客户端)->字节流(客户端)->发送->接收->字节流(服务器)->对象(服务器)。
服务器端代码(1)
package com.sohu.game.mina.sentObject;
import java.io.IOException;
import java.net.InetSocketAddress;
import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;
import org.apache.mina.transport.socket.SocketAcceptor;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
public class MainServer {
private static MainServer mainServer = null;
private SocketAcceptor acceptor = new NioSocketAcceptor();
private DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();
private int bindPort = 8887;
public static MainServer getInstances() {
if (null == mainServer) {
mainServer = new MainServer();
}
return mainServer;
}
private MainServer() {
//创建I/O Filter Chain
//ProtocolCodecFilter实例用来编码数据,这里使用了ObjectSerializationCodecFactory类来序列化或反序列化数据成java对象。
chain.addLast("myChin", new ProtocolCodecFilter(
new ObjectSerializationCodecFactory()));
acceptor.setHandler(ServerHandler.getInstances());
try {
//让IoAcceptor类实例绑定端口实现监听
acceptor.bind(new InetSocketAddress(bindPort));
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
MainServer.getInstances();
}
}
服务端代码(2)
package com.sohu.game.mina.sentObject;
import java.util.ArrayList;
import java.util.List;
import org.apache.mina.core.filterchain.IoFilterAdapter;
import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
public class ServerHandler extends IoFilterAdapter implements IoHandler {
private static ServerHandler samplMinaServerHandler = null;
public static ServerHandler getInstances() {
if (null == samplMinaServerHandler) {
samplMinaServerHandler = new ServerHandler();
}
return samplMinaServerHandler;
}
private ServerHandler() {
}
// 当连接后打开时触发此方法,一般此方法与 sessionCreated 会被同时触发
public void sessionOpened(IoSession session) throws Exception {
}
public void sessionClosed(IoSession session) {
}
/**
* 创建I/O Handler,这里主要看一下messageReceived方法,其接收了Object对象,然后又发送了一个Object对象给Client端。
*/
public void messageReceived(IoSession session, Object message)
throws Exception {
if (message instanceof UserInfo) {
UserInfo text = (UserInfo) message;
System.out.println("服务器接收到从客户端的姓名:"+text.getName());
System.out.println("服务器接收到从客户端的QQ:"+text.getQQNum());
}
if (message instanceof Condition) {
Condition text = (Condition) message;
List<Student> students = text.getStudents();
List<UserInfo> users = text.getUsers();
System.out.println("服务器端接收到从客户端的学生信息数:"+students.size());
System.out.println("服务器端接收到从客户端的用户信息数:"+users.size());
// System.out.println("服务器接收到从客户端的姓名:"+text.getName());
// System.out.println("服务器接收到从客户端的QQ:"+text.getQQNum());
} else{
if(message instanceof Student){
System.out.println("哈哈");
}
System.out.println("aaa"+message.getClass());
}
}
public void exceptionCaught(IoSession arg0, Throwable arg1)
throws Exception {
}
// 当消息传送到客户端后触发
public void messageSent(IoSession arg0, Object arg1) throws Exception {
}
// 当一个新客户端连接后触发此方法.
public void sessionCreated(IoSession arg0) throws Exception {
}
// 当连接空闲时触发此方法.
public void sessionIdle(IoSession arg0, IdleStatus arg1) throws Exception {
}
}
公共代码(1)
package com.sohu.game.mina.sentObject;
public class Student implements java.io.Serializable{
private String sname;
private Integer age;
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
公共代码(2)
package com.sohu.game.mina.sentObject;
public class UserInfo implements java.io.Serializable{
private String name;
private String QQNum;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getQQNum() {
return QQNum;
}
public void setQQNum(String qQNum) {
QQNum = qQNum;
}
}
客户端代码(1)
package com.sohu.game.mina.sentObject;
import java.net.InetSocketAddress;
import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
public class MainClient {
private static MainClient mainClient = null;
NioSocketConnector connector = new NioSocketConnector();
DefaultIoFilterChainBuilder chain = connector.getFilterChain();
public static MainClient getInstances() {
if (null == mainClient) {
mainClient = new MainClient();
}
return mainClient;
}
private MainClient() {
chain.addLast("myChin", new ProtocolCodecFilter(
new ObjectSerializationCodecFactory()));
connector.setHandler(ClientHandler.getInstances());
connector.setConnectTimeout(30);
connector.setConnectTimeoutMillis(30000);
ConnectFuture cf = connector.connect(new InetSocketAddress("localhost",
8887));
}
public static void main(String args[]) {
MainClient.getInstances();
}
}
客户端代码(2)
package com.sohu.game.mina.sentObject;
import java.util.ArrayList;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
public class ClientHandler extends IoHandlerAdapter {
private static ClientHandler samplMinaClientHandler = null;
public static ClientHandler getInstances() {
if (null == samplMinaClientHandler) {
samplMinaClientHandler = new ClientHandler();
}
return samplMinaClientHandler;
}
private ClientHandler() {
}
public void sessionOpened(IoSession session) throws Exception {
session.write("客户端与服务器的会话打开了……");
UserInfo text=new UserInfo();
text.setName("梅竹寒香");
text.setQQNum("972341215");
Student s1 = new Student();
s1.setAge(89);
s1.setSname("bianzhe");
Student s2 = new Student();
s2.setAge(88);
s2.setSname("ganxin");
Condition con = new Condition();
ArrayList<Student> students = new ArrayList<Student>();
students.add(s1);
students.add(s2);
con.setStudents(students);
ArrayList<UserInfo> users = new ArrayList<UserInfo>();
users.add(text);
con.setUsers(users);
//session.write(con);
session.write(con);
//session.write(text);
}
public void sessionClosed(IoSession session) {
}
public void messageReceived(IoSession session, Object message)
throws Exception {
}
public void messageSent(IoSession arg0, Object arg1) throws Exception {
System.out.println("客户端已经向服务器发送了:"+(String)arg1);
}
}
以上即是通过mina简单传递对象的过程。