Mina 框架:
IoService
IoService是对于服务器端接受连接和客户端发起连接两类行为的一个抽象。IoServer用来执行真正的 I/O 操作,以及管理 I/O 会话。两个子接口为IoAcceptor和IoConnector。IoAcceptor用来接受连接,与客户端进行通讯,并发出相应的 I/O 事件交给 IoPorcessor来处理。IoConnector用来发起连接,与服务端进行通讯,并发出相应的 I/O 事件交给 IoPorcessor来处理。
IoServiceListener
IoServiceListener是IoService的监听器,监听与该IoService相关的所有事件,例如,服务被激活、服务闲置、服务被销毁、会话创建、会话销毁等。
IoSession
IoSession表示一个活动的网络连接,与所使用的传输方式无关。IoSession可以用来存储用户自定义的与应用相关的属性。这些属性通常用来保存应用的状态信息,还可以用来在IoFilter器和IoHandler之间交换数据。
IoProcessor
IoProcessor,负责IoFilter和IoHandler进行具体处理,用于为IoSession执行具体的I/O操作。IoProcessor 负责调用注册在IoService上的过滤器,并在过滤器链之后调用IoHandler。一个Processor可以对应N个IoSessions,一个IoSession总是对应一个IoProcessor。
IoFilter
IoFilter是IoServer和IoHander之间的桥梁,从 I/O 服务发送过来的所有 I/O 事件和请求,在到达 I/O 处理器之前,会先由 I/O 过滤器链中的 I/O 过滤器进行处理,比如记录日志、性能分析、访问控制、负载均衡和消息转换等。
IoHandler
IoHandler负责业务处理的,是I/O事件真正得到处理的地方,包含以下一些方法作为业务处理的扩展点
void exceptionCaught(IoSession session, Throwable cause) | 当接口中其他方法抛出异常未被捕获时触发此方法 |
void messageReceived(IoSession session, Object message) | 当接收到客户端的请求信息后触发此方法 |
void messageSent(IoSession session, Object message) | 当信息已经传送给客户端后触发此方法 |
void sessionClosed(IoSession session) | 当连接被关闭时触发,例如客户端程序意外退出等 |
void sessionCreated(IoSession session) | 当一个新客户端连接后触发此方法 |
void sessionIdle(IoSession session, IdleStatus status) | 当连接空闲时触发此方法 |
void sessionOpened(IoSession session) | 当连接后打开时触发此方法,一般此方法与 sessionCreated 会被同时触发 |
准备工作:
org.apache.mina 版本4.0
org.slf4j 1.6.1 (Simple Logging Facade for Java)mina所使用的日志框架,该版本是与mina4.0匹配的版本。
我是用maven管理项目依赖的,使用apache-maven-3.0.4
IDE:IntelliJ IDEA 10.0.3
开始HelloWorld:
1.maven的pom文件:
- <?xml version=“1.0″ encoding=“UTF-8″?>
- <project xmlns=“http://maven.apache.org/POM/4.0.0″
- xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
- xsi:schemaLocation=“http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd”>
- <modelVersion>4.0.0</modelVersion>
- <groupId>example</groupId>
- <artifactId>example</artifactId>
- <version>1.0</version>
- <properties>
- <project.build.sourceEncoding>GBK</project.build.sourceEncoding>
- </properties>
- <dependencies>
- <dependency>
- <groupId>org.apache.mina</groupId>
- <artifactId>mina-core</artifactId>
- <version>2.0.4</version>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>jcl-over-slf4j</artifactId>
- <version>1.6.1</version>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-nop</artifactId>
- <version>1.6.1</version>
- </dependency>
- </dependencies>
- </project>
2. 服务器代码:
a) 首先实现服务端的IoHandler代码SimpleMinaServerHandler。主要功能是打印客户端写入的信息,统计客户端的请求次数以及返回当前客户端是第几次访问。
- package com.chiyan.apach.mina.server;
- import org.apache.mina.core.service.IoHandlerAdapter;
- import org.apache.mina.core.session.IoSession;
- import java.util.concurrent.atomic.AtomicInteger;
- /**
- * Created by IntelliJ IDEA.
- * 简单的消息处理器
- * User: chiyan
- * Date: 12-7-19
- * Time: 上午12:19
- */
- public class SimpleMinaServerHandler extends IoHandlerAdapter {
- private AtomicInteger count = new AtomicInteger(0);
- /**
- * 当一个客户端连接进入时
- */
- @Override
- public void sessionOpened(IoSession session) throws Exception {
- System.out.println(“client connection : ” + session.getRemoteAddress());
- }
- /**
- * 当一个客户端关闭时
- */
- @Override
- public void sessionClosed(IoSession session) throws Exception {
- System.out.println(“client disconnection : ” +session.getRemoteAddress() + “ is Disconnection”);
- }
- /**
- * 当接收到客户端的信息
- *
- * @param session
- * @param message
- * @throws Exception
- */
- @Override
- public void messageReceived(IoSession session, Object message)
- throws Exception {
- String str = (String)message;
- // 打印客户端
- System.out.println(“receive client message : [ " + str +" ]“);
- // 回写消息给客户端
- session.write(count.incrementAndGet());
- }
- }
b) 搭建服务端 MainServer:
- package com.chiyan.apach.mina.server;
- import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
- import org.apache.mina.core.session.IdleStatus;
- 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.SocketSessionConfig;
- import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
- import java.io.IOException;
- import java.net.InetSocketAddress;
- /**
- * Created by IntelliJ IDEA.
- * User: chiyan
- * Date: 12-7-19
- * Time: 上午12:27
- */
- public class MainServer {
- // 服务器端口
- private static final int SERVER_PORT = 8899;
- public static void main(String[] args) throws Exception {
- //创建一个非阻塞的Server端Socket,用NIO
- SocketAcceptor acceptor = new NioSocketAcceptor();
- // 定义每次接收数据大小
- SocketSessionConfig sessionConfig = acceptor.getSessionConfig();
- sessionConfig.setReadBufferSize(2048);
- //创建接受数据的过滤器
- DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();
- //设定这个过滤器将一行一行(/r/n)的读取数据
- chain.addLast(“myChain”, new ProtocolCodecFilter(new TextLineCodecFactory()));
- //设定服务器端的消息处理器: 一个 SimpleMinaServerHandler 对象
- acceptor.setHandler(new SimpleMinaServerHandler());
- //绑定端口,启动服务器
- try {
- acceptor.bind(new InetSocketAddress(SERVER_PORT));
- } catch (IOException e) {
- e.printStackTrace();
- }
- System.out.println(“Mina server is listing port:” + SERVER_PORT);
- }
- }
3. 客户端代码
a)首先实现客户端的IoHandler代码SimpleMinaClientHandler。主要功能是向服务端写消息,接收到服务端计数后再回写服务端。
- package com.chiyan.apach.mina.client;
- import org.apache.mina.core.service.IoHandlerAdapter;
- import org.apache.mina.core.session.IdleStatus;
- import org.apache.mina.core.session.IoSession;
- /**
- * Created by IntelliJ IDEA.
- * User: chiyan
- * Date: 12-7-19
- * Time: 上午12:31
- */
- public class SimpleMinaClientHandler extends IoHandlerAdapter {
- /**
- * 当客户端接受到消息时
- */
- @Override
- public void messageReceived(IoSession session, Object message) throws Exception {
- Integer num = Integer.valueOf((String)message);
- if(num == null || num >10){
- session.close(true);
- return;
- }
- System.out.println(“receive server num : [ " + num + " ]“);
- Thread.sleep(1000);
- session.write(“client received num is : ” + num + “, request next num”);
- }
- /**
- * 当一个客户端被关闭时
- */
- @Override
- public void sessionClosed(IoSession session) throws Exception {
- System.out.println(“client disconnect”);
- }
- /**
- * 当一个客户端连接进入时
- */
- @Override
- public void sessionOpened(IoSession session) throws Exception {
- System.out.println(“create connection to server :” + session.getRemoteAddress());
- session.write(“client started”);
- session.write(“Hello World!”);
- }
- }
b)搭建客户端MainClient
- package com.chiyan.apach.mina.client;
- import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
- import org.apache.mina.core.future.ConnectFuture;
- import org.apache.mina.filter.codec.ProtocolCodecFilter;
- import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
- import org.apache.mina.transport.socket.nio.NioSocketConnector;
- import java.net.InetSocketAddress;
- /**
- * Created by IntelliJ IDEA.
- * User: chiyan
- * Date: 12-7-19
- * Time: 上午12:40
- */
- public class MainClient {
- /**
- * 服务器ip
- */
- private static final String SERVER_IP=“127.0.0.1″;
- /**
- * 服务器端口
- */
- private static final int SERVER_PORT=8899;
- public static void main(String []args){
- //Create TCP/IP connection
- NioSocketConnector connector = new NioSocketConnector();
- //创建接受数据的过滤器
- DefaultIoFilterChainBuilder chain = connector.getFilterChain();
- //设定这个过滤器将一行一行(/r/n)的读取数据
- chain.addLast(“myChain”, new ProtocolCodecFilter(new TextLineCodecFactory()));
- //服务器的消息处理器:一个 SimpleMinaClientHandler 对象
- connector.setHandler(new SimpleMinaClientHandler());
- //set connect timeout
- connector.setConnectTimeoutMillis(30 * 1000);
- //连接到服务器:
- ConnectFuture cf = connector.connect(new InetSocketAddress(SERVER_IP,SERVER_PORT));
- cf.awaitUninterruptibly();
- cf.getSession().getCloseFuture().awaitUninterruptibly();
- connector.dispose();
- }
- }
运行程序:
1.服务端打印:
- Mina server is listing port:8899
- client connection : /127.0.0.1:50497
- receive client message : [ client started ]
- receive client message : [ Hello World! ]
- receive client message : [ client received num is : 1, request next num ]
- receive client message : [ client received num is : 2, request next num ]
- receive client message : [ client received num is : 3, request next num ]
- receive client message : [ client received num is : 4, request next num ]
- receive client message : [ client received num is : 5, request next num ]
- receive client message : [ client received num is : 6, request next num ]
- receive client message : [ client received num is : 7, request next num ]
- receive client message : [ client received num is : 8, request next num ]
- receive client message : [ client received num is : 9, request next num ]
- receive client message : [ client received num is : 10, request next num ]
- client disconnection : /127.0.0.1:50497 is Disconnection
2.客户端打印:
- create connection to server :/127.0.0.1:8899
- receive server num : [ 1 ]
- receive server num : [ 2 ]
- receive server num : [ 3 ]
- receive server num : [ 4 ]
- receive server num : [ 5 ]
- receive server num : [ 6 ]
- receive server num : [ 7 ]
- receive server num : [ 8 ]
- receive server num : [ 9 ]
- receive server num : [ 10 ]
- client disconnect