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简单传递对象的过程。