技术笔记:Mina框架(实战详解)

简介: 技术笔记:Mina框架(实战详解)

Apache Mina Server 是一个网络通信应用框架,为开发高性能和高可用性的网络应用程序提供了非常便利的框架。


特点:异步的NIO框架,将UDP当成"面向连接"的协议


一、组件管理


Mina的底层依赖的主要是Java NIO库,上层提供的是基于事件的异步接口


(1)IoService(最底层【起点】)


作用:隐藏底层IO的细节,对上提供统一的基于事件的异步IO接口


IOSocketAcceptor和IOSocketChannel,分别对应TCP协议下的服务端和客户端的IOService,low-level IO经过IOService层后变成IO Event


(2)IoProcessor


作用:负责检查是否有数据在通道上读写


IoProcessor 负责调用注册在IoService 上的过滤器,并在过滤器链之后调用IoHandler


(3)IoFilter(拦截器【关键】)


作用:日志输出、黑名单过滤、数据的编码(write 方向)与解码(read 方向)等功能


(4)IoHandler(业务逻辑处理【终点】)


作用:接收、发送数据


每个IoService都需要指定一个IoHandler


(5)IoSession


作用:是对底层连接(服务器与客户端的特定连接,该连接由服务器地址、端口以及客户端地址、端口来决定)的封装


二、服务端流程:


1、通过SocketAcceptor 同客户端建立连接;


2、连接建立之后 I/O的读写交给了I/O Processor线程,I/O Processor是多线程的;


3、通过I/O Processor 读取的数据经过IoFilterChain里所有配置的IoFilter,IoFilter进行消息的过滤,格式的转换,在这个层面可以制定一些自定义的协议;


4、最后IoFilter将数据交给 Handler 进行业务处理,完成了整个读取的过程;


写入过程也是类似,只是刚好倒过来,通过IoSession.write 写出数据,然后Handler进行写入的业务处理,处理完成后交给IoFilterChain,进行消息过滤和协议的转换,最后通过 I/O Processor 将数据写出到 socket 通道


三、服务端代码实现


1、编写IoService(主要功能:设置过滤器,设置handler,绑定端口)


public class MinaServer {


private static Logger logger = Logger.getLogger(MinaServer.class);


public static void main(String【】 args) {


Configuration config = Configuration.getInstance();


try {


config.readConfiguration();


config.initDataSource();


config.initServiceDef();


// 启动FTP读文件,PE积分后台执行


//此处为内部逻辑,通过FTP读取文件,跳过


} catch (Exception e1) {


e1.printStackTrace();


System.exit(1);


}


try {


config.initInterfaceConfig();


// 启动接口调用互斥map维护线程


InterfaceBusThread interfaceBusThread = new InterfaceBusThread();


interfaceBusThread.start();


} catch (Exception e) {


logger.info("InterfaceBus error!", e);


}


NioSocketAcceptor acceptor = null; // 创建连接


try {


// 创建一个非阻塞的server端的Socket


acceptor = new NioSocketAcceptor(Runtime.getRuntime()


.availableProcessors() + 1);// ioprocesser线程数,一般为cpu数量+1


// 建立工作线程池


Executor threadPool = Executors.newFixedThreadPool(Constant.threadCount);// 设置20个handler线程


// 解决在LINUX服务器上kill掉了,但是端口仍然被占用,要过一段时间才能释放


acceptor.setReuseAddress(true);


// 添加消息过滤器


acceptor.getFilterChain().addLast("codec",


new ProtocolCodecFilter(new XMLObjectCodecFactory()));


//


// 设置服务器能够接收的最大连接数


acceptor.setBacklog(Constant.maxSocketConn);


acceptor.getFilterChain().addLast("executor",


new ExecutorFilter(threadPool));


// 设置读取数据的缓冲区大小


acceptor.getSessionConfig().setReadBufferSize(2048);


// 读写通道10秒内无操作进入空闲状态


acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);


// 绑定逻辑处理器


acceptor.setHandler(new MinaServerHandler()); // 添加业务处理


// 绑定端口


acceptor.bind(new InetSocketAddress(Constant.minaServerPort));


logger.info("server start success... port:"


+ Constant.minaServerPort);


} catch (Exception e) {


logger.error("server start error....", e);


e.printStackTrace();


System.exit(1);


}


}


}


2、编写过滤器(即上面代码的添加消息过滤器,这里使用了Mina自带的换行符编解码器工厂,注意:要在acceptor.bind()方法之前执行)


3、编写IoHandler


public class MinaServerHandler extends IoHandlerAdapter {


private final static Logger log = LoggerFactory.getLogger(TCPServerHandler.class);


@Override


public void messageReceived(IoSession session, Object message) throws Exception {


//业务代码在这里编写处理


String str = message.toString();


System.out.println("The message received is 【" + str + "】");


if (str.endsWith("quit")) {


session.close(true);


return;


}


}


@Override


public void sessionCreated(IoSession session) throws Exception {


//代码效果参考:http://hnjlyzjd.com/xl/wz_24761.html

System.out.println("server session created");

super.sessionCreated(session);


}


@Override


public void sessionOpened(IoSession session) throws Exception {


System.out.println("server session Opened");


super.sessionOpened(session);


}


@Override


public void sessionClosed(IoSession session) throws Exception {


System.out.println("server session Closed");


super.sessionClosed(session);


}


}


4、将IoHandler 注册到IoService(即上面代码的绑定逻辑处理器,注意:要在acceptor.bind()方法之前执行)


5、运行MinaServer中的main 方法,可以看到控制台一直处于阻塞状态,等待客户端连接


四、Maven的pom.xml配置


org.apache.mina


//代码效果参考:http://hnjlyzjd.com/xl/wz_24759.html

mina-core

2.0.7


org.apache.mina


mina-integration-spring


1.1.7


五、测试类(模拟客户端请求)


public class AutoTest {


private final static String IP = "localhost";


private final static int PORT = 9002;


public static void main(String【】 args) {


String msg = "testEquityInsertRevequityinsertrev


13632599010120130620";


System.out.println("testEquityInsertRev request msg:"+msg);


System.out.println("testEquityInsertRev response msg:"+testApi(msg));


}


博客园:


Copyright ?2018 不是植物


【转载文章务必保留出处和署名,谢谢!】

相关文章
|
设计模式 架构师 Java
阿里P8架构师都要学习研究的java加强版23种设计模式神级PDF文档
说在前面的话 Java作为老牌纯正的编程语言,在规范性上有着天然优势。因此本版的设计模式讲解全部用Java语言来描述,并针对Java语言的特性对讲解内容做了相当大的改动。 不知道大家是否听过编程界的一段话:掌握设计模式相当于华山派的"气宗",是程序员的内功修为,虽然在同样的学习时间下,类似Python这种"剑宗"的开发模式见效更快,但是长远来看,"气宗"才是走向软件架构师以上级别的必由之路。 所以,掌握气宗就掌握了编程命脉,然而学习设计模式有四大境界: 接下来给大家分享的就是java溢彩加强版大话设计模式包含的内容知识点。 总目录 主要内容 本文是百万销量的经典畅销书《
240 0
|
9月前
|
存储 Web App开发 运维
发布、部署,傻傻分不清楚?从概念到实际场景,再到工具应用,一篇文章让你彻底搞清楚
部署和发布是软件工程中经常互换使用的两个术语,甚至感觉是等价的。然而,它们是不同的! • 部署是将软件从一个受控环境转移到另一个受控环境,它的目的是将软件从开发状态转化为生产状态,使得软件可以为用户提供服务。 • 发布是将软件推向用户的过程,应用程序需要多次更新、安全补丁和代码更改,跨平台和环境部署需要对版本进行适当的管理,有一定的计划性和管控因素。
1862 1
|
6月前
|
存储 算法 Java
"解锁Java对象数据结构的奥秘:从基础到实战,与热点技术共舞,让你的编程之路更激情四溢!"
【8月更文挑战第21天】Java以对象为核心,它是程序的基本单元与数据处理的基础。对象源自类,拥有属性(字段)和方法。对象在内存中分为对象头(含哈希码、GC信息等)和实例数据区(存储属性值)。例如,`Student`类定义了姓名、年龄等属性及相应的方法。通过`new`关键字实例化对象并调用其方法进行数据操作,是Java编程的关键技能。
39 0
|
8月前
|
存储 Java 数据处理
启航Java编程:基础三部曲-第二部
启航Java编程:基础三部曲-第二部 Java语法全接触:变量、数据类型与运算符详解
82 1
|
9月前
|
程序员 Python
类的设计奥秘:从代码到架构的科普全解
类的设计奥秘:从代码到架构的科普全解
111 2
|
设计模式 前端开发 JavaScript
前端Web开发学习,入门到进阶,推荐几本很不错的书籍
前端Web开发学习,入门到进阶,推荐几本很不错的书籍
192 0
|
设计模式 缓存 负载均衡
你kin你擦!阿里终于肯把内部高并发编程高阶笔记开源出来了
“高并发”三字是近几年开发圈子里热议的一个话题,可能程序员之间闲下来就会讨论所谓的“高并发经验”。值得注意的是即使你和高并发天天打交道,也不一定能获得高并发的经验,高并发只是一个结果,并不是过程。想要玩转高并发,基础最重要,大并发面前,靠得住的只有人,是人来根据具体的应用场景去解决具体的问题。
你kin你擦!阿里终于肯把内部高并发编程高阶笔记开源出来了
【JavaSE专栏23】Java反射有多强? 他拥有这五大神奇功能!
【JavaSE专栏23】Java反射有多强? 他拥有这五大神奇功能!
直击灵魂!美团大牛手撸并发原理笔记,由浅入深剖析JDK源码
并发编程这四个字想必大家最近都在网上看到过有很多的帖子在讨论。我们都知道并发编程可选择的方式有多进程、多线程和多协程。在Java中,并发就是多线程模式。而多线程编程也一直是一个被广泛而深入讨论的领域。如果遇到复杂的多线程编程场景,大多数情况下我们就需要站在巨人的肩膀上利用并发编程框架——JDK Concurrent包来解决相关线程问题。
|
数据采集 算法 Java
库调多了,都忘了最基础的概念-《线程池篇》
库调多了,都忘了最基础的概念-《线程池篇》
140 0
库调多了,都忘了最基础的概念-《线程池篇》