Apache Mina - 简单的服务端和客户端的搭建

1、什么是Apache Mina?

Apache Mina是一个能够帮助用户开发高性能和高伸缩性网络应用程序的框架。它通过Java NIO技术基于TCP/IP和UDP/IP协议提供了抽象的、事件驱动的、异步的API。简单的说,可以用它来帮助我们快速的开发网络通信。

2、它的工作原理?

Apache Mina - 简单的服务端和客户端的搭建_第1张图片

3、如何使用Apac Mina?

3.1、创建一个Maven工程

应该如何创建Maven工程我这里就不详细介绍了,网上有很多资料大家都可以去看看。在这里我使用的是spring boot框架,所以POM文件是这样的:

[html]  view plain  copy
  1. xml version="1.0" encoding="UTF-8"?>  
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  3.     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  4.     <modelVersion>4.0.0modelVersion>  
  5.   
  6.     <groupId>com.springbootgroupId>  
  7.     <artifactId>minaartifactId>  
  8.     <version>0.0.1-SNAPSHOTversion>  
  9.     <packaging>jarpackaging>  
  10.   
  11.     <name>minaname>  
  12.     <description>Demo for minadescription>  
  13.   
  14.     <parent>  
  15.         <groupId>org.springframework.bootgroupId>  
  16.         <artifactId>spring-boot-starter-parentartifactId>  
  17.         <version>1.2.5.RELEASEversion>  
  18.         <relativePath />   
  19.     parent>  
  20.   
  21.     <properties>  
  22.         <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>  
  23.         <java.version>1.8java.version>  
  24.     properties>  
  25.   
  26.     <dependencies>  
  27.         <dependency>  
  28.             <groupId>org.springframework.bootgroupId>  
  29.             <artifactId>spring-boot-starterartifactId>  
  30.         dependency>  
  31.   
  32.         <dependency>  
  33.             <groupId>org.springframework.bootgroupId>  
  34.             <artifactId>spring-boot-starter-testartifactId>  
  35.             <scope>testscope>  
  36.         dependency>  
  37.   
  38.         <dependency>  
  39.             <groupId>org.apache.minagroupId>  
  40.             <artifactId>mina-coreartifactId>  
  41.             <version>2.0.4version>  
  42.         dependency>  
  43.     dependencies>  
  44.   
  45.     <build>  
  46.         <plugins>  
  47.             <plugin>  
  48.                 <groupId>org.springframework.bootgroupId>  
  49.                 <artifactId>spring-boot-maven-pluginartifactId>  
  50.             plugin>  
  51.         plugins>  
  52.     build>  
  53.   
  54. project>  

3.2、创建服务端程序

接着我们创建一个服务端程序,用来接收和监控传过来的信息

[java]  view plain  copy
  1. package com.springboot.mina.server;  
  2.   
  3. import java.io.IOException;  
  4. import java.net.InetSocketAddress;  
  5. import java.nio.charset.Charset;  
  6.   
  7. import org.apache.log4j.Logger;  
  8. import org.apache.mina.core.service.IoAcceptor;  
  9. import org.apache.mina.core.session.IdleStatus;  
  10. import org.apache.mina.filter.codec.ProtocolCodecFilter;  
  11. import org.apache.mina.filter.codec.textline.TextLineCodecFactory;  
  12. import org.apache.mina.transport.socket.nio.NioSocketAcceptor;  
  13.   
  14. public class MyServer {  
  15.       
  16.     private static Logger logger = Logger.getLogger(MyServer.class); //日志  
  17.     private static final int port = 8899;   //端口  
  18.   
  19.     public static void main(String[] args) {  
  20.         // 创建一个非阻塞的server端的socket  
  21.         IoAcceptor acceptor = new NioSocketAcceptor();  
  22.         // 设置过滤器,选用Mina自带的过滤器一行一行读取代码  
  23.         acceptor.getFilterChain().addLast("myChain"new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));  
  24.         // 设置读取数据的缓冲区大小   
  25.         acceptor.getSessionConfig().setReadBufferSize(2048);  
  26.         // 读写通道10秒内无操作进入空闲状态   
  27.         acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE,10);  
  28.         // 绑定逻辑处理器  
  29.         acceptor.setHandler(new ServerHandler());  
  30.         // 绑定端口,启动服务器  
  31.         try {  
  32.             acceptor.bind(new InetSocketAddress(port));  
  33.         } catch (IOException e) {  
  34.             e.printStackTrace();  
  35.         }  
  36.           
  37.         logger.info("服务已启动,端口是:"+port);  
  38.     }  
  39. }  

3.3、创建服务端的逻辑处理器

在上面我们为服务端注册了一个逻辑处理器acceptor.setHandler(new ServerHandler()),用力具体处理监听动作,接下来我们就要来实现这一处理器

[java]  view plain  copy
  1. package com.springboot.mina.server;  
  2.   
  3. import org.apache.log4j.Logger;  
  4. import org.apache.mina.core.service.IoHandlerAdapter;  
  5. import org.apache.mina.core.session.IdleStatus;  
  6. import org.apache.mina.core.session.IoSession;  
  7.   
  8. public class ServerHandler extends IoHandlerAdapter{  
  9.   
  10.     private static Logger logger = Logger.getLogger(ServerHandler.class);  
  11.       
  12.     //创建连接  
  13.     @Override  
  14.     public void sessionCreated(IoSession session) throws Exception {  
  15.         logger.info("服务器创建session连接!");  
  16.     }  
  17.       
  18.     //打开一个连接  
  19.     @Override  
  20.     public void sessionOpened(IoSession session) throws Exception {  
  21.         logger.info("服务器打开session连接!");  
  22.     }  
  23.       
  24.     //关闭连接  
  25.     @Override  
  26.     public void sessionClosed(IoSession session) throws Exception {  
  27.         logger.info("服务器关闭session连接!");  
  28.     }  
  29.       
  30.     //连接空闲  
  31.     @Override  
  32.     public void sessionIdle(IoSession session, IdleStatus status) throws Exception {  
  33.           
  34.     }  
  35.       
  36.     //有异常时  
  37.     @Override  
  38.     public void exceptionCaught(IoSession session, Throwable cause) throws Exception {  
  39.         logger.info("服务器出现异常"+cause);  
  40.     }  
  41.       
  42.     //接收到消息  
  43.     @Override  
  44.     public void messageReceived(IoSession session, Object message) throws Exception {  
  45.         String str = message.toString();  
  46.         logger.info("服务器收到消息:"+str);  
  47.         if(str.equals("close")){  
  48.             session.write("close");  
  49.             session.close(true);  
  50.         }  
  51.     }  
  52.       
  53.     //将要发送消息  
  54.     @Override  
  55.     public void messageSent(IoSession session, Object message) throws Exception {  
  56.           
  57.     }  
  58. }  
这样子我们服务端就基本搭建完成了,如果你还要实现什么逻辑处理,在逻辑处理器对应的动作方法上写就行了

3.4、创建客户端

服务端创建好了,接下来我们建一个客户端,来发送数据,当然,也可以处理从服务端发过来的信息

[java]  view plain  copy
  1. package com.springboot.mina.client;  
  2.   
  3. import java.net.InetSocketAddress;  
  4. import java.nio.charset.Charset;  
  5.   
  6. import org.apache.log4j.Logger;  
  7. import org.apache.mina.core.future.ConnectFuture;  
  8. import org.apache.mina.core.session.IoSession;  
  9. import org.apache.mina.filter.codec.ProtocolCodecFilter;  
  10. import org.apache.mina.filter.codec.textline.TextLineCodecFactory;  
  11. import org.apache.mina.transport.socket.SocketConnector;  
  12. import org.apache.mina.transport.socket.nio.NioSocketConnector;  
  13.   
  14. public class MyClient {  
  15.   
  16.     private static Logger logger = Logger.getLogger(MyClient.class);  
  17.     private static final String host = "127.0.0.1";  
  18.     private static final int port = 8899;  
  19.       
  20.     public static void main(String[] args) {  
  21.         // 创建连接  
  22.         SocketConnector connector = new NioSocketConnector();  
  23.         // 设置过滤器,选用Mina自带的过滤器一行一行读取代码  
  24.         connector.getFilterChain().addLast("myChain"new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));  
  25.         // 设置连接超时时间  
  26.         connector.setConnectTimeoutMillis(30 * 1000);  
  27.         // 绑定逻辑处理器  
  28.         connector.setHandler(new ClientHandler());  
  29.         // 连接到服务器  
  30.         ConnectFuture future = connector.connect(new InetSocketAddress(host, port));  
  31.         // 等待连接创建完成  
  32.         future.awaitUninterruptibly();  
  33.         // 获得session  
  34.         IoSession session = future.getSession();  
  35.         // 发送消息  
  36.         session.write("你好! \r\n close");  
  37.           
  38.         logger.info("客户端正在连接服务器,"+host+":"+port);  
  39.           
  40.         // 等待连接断开  
  41.         session.getCloseFuture().awaitUninterruptibly();  
  42.         connector.dispose();  
  43.     }  
  44. }  
ok,我们创建了一个客户端程序,并在session.write("你好! \r\n close")发送了一条数据,“\r\n”是换行符,我们设置的过滤器是Mina本身提供的逐行读取

3.5、创建客户端的逻辑处理器
同3.3相同,同样要为客户端注册一个逻辑处理器,甚至代码都相差不多

[java]  view plain  copy
  1. package com.springboot.mina.client;  
  2.   
  3. import org.apache.log4j.Logger;  
  4. import org.apache.mina.core.service.IoHandler;  
  5. import org.apache.mina.core.session.IdleStatus;  
  6. import org.apache.mina.core.session.IoSession;  
  7.   
  8. public class ClientHandler implements IoHandler {  
  9.   
  10.     private static Logger logger = Logger.getLogger(ClientHandler.class);  
  11.       
  12.     // 有异常  
  13.     @Override  
  14.     public void exceptionCaught(IoSession session, Throwable cause) throws Exception {  
  15.         logger.info("程序出现异常"+cause);  
  16.     }  
  17.   
  18.     // 接收到消息时  
  19.     @Override  
  20.     public void messageReceived(IoSession session, Object message) throws Exception {  
  21.         String str = message.toString();  
  22.         logger.info("客户端收到消息:"+str);  
  23.         if(str.equals("close")){  
  24.             session.close(true);  
  25.         }  
  26.     }  
  27.   
  28.     // 将要发送消息  
  29.     @Override  
  30.     public void messageSent(IoSession session, Object message) throws Exception {  
  31.   
  32.     }  
  33.   
  34.     // 关闭连接  
  35.     @Override  
  36.     public void sessionClosed(IoSession session) throws Exception {  
  37.         logger.info("客户端关闭session连接!");  
  38.     }  
  39.   
  40.     // 创建连接  
  41.     @Override  
  42.     public void sessionCreated(IoSession session) throws Exception {  
  43.         logger.info("客户端创建session连接!");  
  44.     }  
  45.   
  46.     // 连接空闲  
  47.     @Override  
  48.     public void sessionIdle(IoSession session, IdleStatus arg1) throws Exception {  
  49.           
  50.     }     
  51.   
  52.     // 打开一个连接  
  53.     @Override  
  54.     public void sessionOpened(IoSession session) throws Exception {  
  55.         logger.info("客户端开始session连接!");  
  56.     }  
  57.   
  58. }  
好了,这样我们基于Mina的服务端和客户端就搭建完成了,因为都是写在了Main()方法里,只要右键->run as Java Application就能把程序跑起来了,你可以两个一起跑,也可以只运行服务器,打开命令行,输入
[plain]  view plain  copy
  1. telnet 127.0.0.1 8899  
就可以和端口建立通信了,在控制台就可以看到你输入的内容了。

4、Mina具体技术

程序写好了,我们来看看上面用到了Mina的哪些东西

1、类NioSocketAcceptor;创建一个服务端监听

2、类NioSocketConnecto;创建一个客户端监听

3、IoHandler接口;          封装了不同事件的处理

4、类IoSession;                  用来保存会话属性和发送消息,可以理解为服务端和客户端之间的特定连接

5、类IoFilter;      用来对数据进行过滤。我们上面使用的是Mina自带的逐行读取的过滤器,如果有需要,我们要可以定义自己的过滤器


Apacha Mina官网:http://mina.apache.org/mina-project/

在线API文档:http://tool.oschina.net/apidocs/apidoc?api=mina

你可能感兴趣的:(Apache Mina - 简单的服务端和客户端的搭建)