Mina学习之---mina整体流程介绍
现在公司使用的NIO框架一直时候Mina,当然这也的框架还有Netty。虽然一直在用,但只是简单的停留在业务层面,最近面试的时候有问Mina相关的东西。在之前的博客中已经对BIO,NIO,AIO这三种java提供的IO流进行了介绍以及原理的讲解。今天我就打算开始对实现NIO的Mina框架的学习,看看这个框架是如何帮助我们更好的去管理selector,以及ByteBuffer,和我们的channel。以及如何处理高并发。好了今天就对mina框架的几个重要的概念用一个Mina框架入门代码的方式给大家看一下。:
我们先看一下mina服务端的代码:
package cn.nio.mina; import java.io.IOException;
import java.net.InetSocketAddress; import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor; /**
*
* <p>
* mina服务端
* </p>
*
* 类说明
*
* @author duanxj
* @version
*/
public class MinaServer { public static void main(String[] args) {
MinaServer server = new MinaServer();
server.initMinaServer(19898);
} /**
* 初始化Mina服务端
*
* @param port
*/
public void initMinaServer(int port) {
// 创建NioSocketAcceptor对象
NioSocketAcceptor acceptor = new NioSocketAcceptor();
// 创建请求处理类
MinaServerHandler handler = new MinaServerHandler();
try {
// 设置过滤链
acceptor.getFilterChain().addLast("codec",
new ProtocolCodecFilter(new TextLineCodecFactory()));
// 设置处理类
acceptor.setHandler(handler);
// 绑定服务端口
acceptor.bind(new InetSocketAddress(port));
} catch (IOException e) {
e.printStackTrace();
} } }
mina服务端请求处理
package cn.nio.mina; import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession; /**
*
* <p>mina</p>
*
* 类说明
*
* @author duanxj
* @version
*/
public class MinaServerHandler extends IoHandlerAdapter{ @Override
public void exceptionCaught(IoSession session, Throwable cause)
throws Exception {
System.out.println("exceptionCaught");
} @Override
public void messageReceived(IoSession session, Object message)
throws Exception {
String receiverContent = (String)message;
System.out.println("server messageReceived: "+receiverContent);
session.write("Server has received message:duanxiaojun");
} @Override
public void messageSent(IoSession session, Object message) throws Exception {
System.out.println("messageSent");
} @Override
public void sessionClosed(IoSession session) throws Exception {
System.out.println("sessionClosed");
} @Override
public void sessionCreated(IoSession session) throws Exception {
System.out.println("sessionCreated");
} @Override
public void sessionIdle(IoSession session, IdleStatus status)
throws Exception {
System.out.println("sessionIdle");
} @Override
public void sessionOpened(IoSession session) throws Exception {
System.out.println("sessionOpened");
}
}
我们先对服务端的创建做一个简单的介绍。从mina服务端的创建代码可以看出,我们再创建一个mina服务的时候经常使用到的就是这几个对象。首先NioSocketAcceptor 创建用来接收客户端发送来的请求(主要负责实现nio操作相关的实现如accept(),open(),select()等方法)。MinaServerHandler 实现了IoHandlerAdapter用来对接收到的请求进行处理。getFilterChain 设置mina过滤链 对从IOServic饿到IOHandle之前的请求进行过滤处理诸如编解码。最后bind绑定一个特定的端口。好了这样一个简单的mina服务就搭建起来了。但是其中很多知识点我们再接下来的源码解读中进行学习说明,这里只是有个入门,让大家对mina中最主要的几个知识点或者概念有个理解。
下面我们看mina客户端如何来重建用来向服务端发送请求和接收服务端请求处理的结果。先上代码一看:
package cn.nio.mina; import java.net.InetSocketAddress; import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketConnector; /**
*
* <p>
* mina客户端
* </p>
*
* 类说明
*
* @author duanxj
* @version
*/
public class MinaClient { public static void main(String[] args) {
MinaClient client = new MinaClient();
client.initMinaClient("127.0.0.1", 19898);
} public void initMinaClient(String host, int port) {
// 创建NioSocketConnector对象
NioSocketConnector connector = new NioSocketConnector();
// 创建mina客户端处理
MinaClientHandler handler = new MinaClientHandler();
//设置过滤链
connector.getFilterChain().addLast("codec",
new ProtocolCodecFilter(new TextLineCodecFactory()));
//设置处理类
connector.setHandler(handler);
// 创建连接
ConnectFuture future = connector.connect(new InetSocketAddress(host, port));
future.awaitUninterruptibly();// 阻塞直到连接建立,因为我们后面要使用连接成功之后创建的Session对象来进行写数据的操作
IoSession session = future.getSession();// 获得Session对象
session.write("hello world");
}
}
mina客户端业务处理
package cn.nio.mina; import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession; /**
*
* <p>
* mina客户端请求处理
* </p>
*
* 类说明
*
* @author duanxj
* @version
*/
public class MinaClientHandler extends IoHandlerAdapter{ @Override
public void exceptionCaught(IoSession session, Throwable cause)
throws Exception {
System.out.println("exceptionCaught");
} @Override
public void messageReceived(IoSession session, Object message)
throws Exception {
String receiverContent = (String)message;
System.out.println(receiverContent);
} @Override
public void messageSent(IoSession session, Object message) throws Exception {
System.out.println("messageSent");
} @Override
public void sessionClosed(IoSession session) throws Exception {
System.out.println("sessionClosed");
} @Override
public void sessionCreated(IoSession session) throws Exception {
System.out.println("sessionCreated");
} @Override
public void sessionIdle(IoSession session, IdleStatus status)
throws Exception {
System.out.println("sessionIdle");
} @Override
public void sessionOpened(IoSession session) throws Exception {
System.out.println("sessionOpened");
}
}
跟服务端一样,我们先说一下客户端创建的几个主要的概念:NioSocketConnector 用来创建与服务端的连接同时向服务端发送数据。MinaClientHandler处理服务端返回的请求。getFilterChain处理从IOService到IOHandler之间的传输信息的过滤。
好了上面两个简单的mina服务端和mina客户端就创建完毕了。其实如果我们只是使用的话了解到上面这样就可以了,因为很多有关NIO就是同步非堵塞的处理mina框架在NioSocketAcceptor和MinaServerHandler之中已经进行了处理包括对大并发访问的处理,当然NIO天生就是用来处理大并发的,否则就不会有抽象的管道的概念了。因此如果只是想用那么学到这里我觉着就差不多了,保证你会使用了,下面就是我现在所在的公司使用mina进行通信协议的配置文件,大家可以看考一下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> <!-- ProtocolCodecFilter -->
<bean id="digitalcourtProtocolCodecFilter" class="org.apache.mina.filter.codec.ProtocolCodecFilter">
<constructor-arg>
<bean
class="cn.com.chnsys.imp.courtInterface.server.CustomProtocalCodecFactory">
<constructor-arg type="java.lang.String" value="UTF-8" />
</bean>
</constructor-arg>
</bean> <!-- IO过滤线程池 -->
<bean id="executorIoFilter" class="org.apache.mina.filter.executor.ExecutorFilter">
<constructor-arg index="0">
<value>1000</value>
</constructor-arg>
<constructor-arg index="1">
<value>1800</value>
</constructor-arg>
</bean> <!-- Mina过滤器链 -->
<bean id="digitalcourtIoFilterChainBuilder"
class="org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder">
<property name="filters">
<map>
<entry key="executor" value-ref="executorIoFilter" />
<entry key="codecFilter" value-ref="digitalcourtProtocolCodecFilter" />
</map>
</property>
</bean> <!-- 协议IO线程池 -->
<bean id="digitalcourThreadPool" class="cn.com.chnsys.cif.common.utils.ThreadPoolFactory">
<property name="corePoolSize" value="4" />
<property name="keepAliveSeconds" value="60" />
<property name="maxPoolSize" value="32" />
<property name="queueCapacity" value="64" />
</bean> <!-- mina协议接收服务 -->
<bean id="MinaSocketServer"
class="cn.com.chnsys.imp.courtInterface.server.DigitalCourtMinaSocketServer">
<property name="ioHandler">
<bean
class="cn.com.chnsys.imp.courtInterface.server.ProtocolDispatcherHandle">
<property name="handleMap">
<map>
<entry key="login" value-ref="getUserAndLoginProtocol" />
<entry key="getUsers" value-ref="getUserAndLoginProtocol" />
</map>
</property>
<property name="readTimeout" value="30" />
<property name="charset" value="UTF-8" />
<property name="customProtocolInterceptors">
<list>
<!-- 上下文环境处理拦截器 -->
<bean id="serverContextHandlerIntercptor"
class="cn.com.chnsys.imp.courtInterface.protocol.ServerContextHandlerIntercptor">
<property name="userService" ref="userService" />
<property name="ignoreModuleList">
<list>
<value>getSignalSourceUrl</value>
<value>getTDSSignalSourceUrl</value>
<value>getTrialPlansNoPrivilege</value>
</list>
</property>
<property name="ignoreValidateUserList">
<list>
<value>heartBeatTDS</value>
<value>checkCMSConnectable</value>
</list>
</property>
</bean>
</list>
</property>
</bean>
</property>
<property name="threadPool" ref="digitalcourThreadPool" />
<property name="port" value="${port}" />
<property name="ioFilterChainBuilder" ref="digitalcourtIoFilterChainBuilder" />
</bean>
</beans>
从这个配置文件我们可以看到,我们只是实现了对编解码拦截的处理,这是因为我们知道原生态的mina框架是不会处理传输信息的加密的,而在我们的应用中使用到了协议信息的加密技术,所以需要对编解码拦截器进行重写,在这里我主要实现的是对ByteBuffer的解码和编码。详细编解码大家也可以参考一下:
/**
* 重写方法描述 {@inheritDoc}
*/
@Override
public void decode(IoSession ioSession, IoBuffer buffer, ProtocolDecoderOutput out)
throws Exception {
Integer protocolLength = (Integer) ioSession.getAttribute(ProtocolConstant.ATTR_PROTOCLLENGTH);
//具体实现的内容就是对IOBuffer中的字节数据进行编解码。这里我就不能跟大家再说了。
}
好了通过上述的一个mina在企业级的应用大家应该可以看到,其实我们真正在使用的时候,其实并不需要对mina的底层如何实现NIO做更多的了解。
但是,小伙伴们 但是。。。。如果你对技术很热情,很感兴趣我觉着就很有必要去了解了解这个mina框架了,因为人家毕竟处理了一个很厉害的问题啊。哈哈哈 好了今天对mina框架的入门咱们就说到这里,从下一讲开始对mina中的这几个牛逼的概念或者知识点进行源码级别的跟踪学习。咱们下次见。。。
Mina学习之---mina整体流程介绍的更多相关文章
- MQTT 协议学习:003-MQTT通信流程介绍
背景 有关博文:通信报文的构成 . 上一讲说到可变头与消息体要结合不同的报文类型才能够进行分析(实际上,官方的文档的介绍顺序就是这样的) 那么,我们就来具体看看有关的报文类型. 在此之前 我们捋一捋完 ...
- JVM 整体流程介绍
一. JVM自身的物理结构 从图中可以看出 JVM 的主要组成部分 ClassLoader(类加载器),Runtime Data Area(运行时数据区,内存分区),Execution Engine( ...
- Tomcat源码解析-整体流程介绍
一.架构 下面谈谈我对Tomcat架构的理解 总体架构: 1.面向组件架构 2.基于JMX 3.事件侦听 1)面向组件架构 tomcat代码看似很庞大,但从结构上看却很清晰和简单,它主要由一堆组件组成 ...
- MINA学习之体系介绍
基于MINA应用程序结构图: 我们可以看出,MINA是应用程序(客户端或服务端)和底层基于TCP,UDP等通讯协议的网络层之间的粘合剂.而且各个模块之间是相互独立的,你只需要在MINA体 系基础上设计 ...
- 【MINA学习笔记】—— 1.体系结构分析[z]
前言 Apache的MINA框架是一个早年非常流行的NIO框架,它出自于Netty之父Trustin Lee大神之手.虽然目前市场份额已经逐渐被Netty取代了,但是其作为NIO初学者入门学习框架是非 ...
- MINA学习汇总
MINA学习汇总 Apache Mina Server 是一个网络通信应用框架,用于开发高性能和高可用性的网络应用程序.它主要是对基于TCP/IP.UDP/IP协议栈的通信框架(然,也可以提供JAVA ...
- 02-FPGA设计流程介绍——小梅哥FPGA设计思想与验证方法视频教程配套文档
芯航线——普利斯队长精心奉献 课程目标: 1.了解并学会FPGA开发设计的整体流程 2.设计一个二选一选择器并进行功能仿真.时序仿真以及板级验证 实验平台:芯航线FPGA开发板.杜邦线 实验内容: 良 ...
- Mybatis技术原理理——整体流程理解
前言:2018年,是最杂乱的一年!所以你看我的博客,是不是很空! 网上有很多关于Mybatis原理介绍的博文,这里介绍两篇我个人很推荐的博文 Mybatis3.4.x技术内幕和 MyBaits源码分析 ...
- 《从0到1学习Flink》—— Apache Flink 介绍
前言 Flink 是一种流式计算框架,为什么我会接触到 Flink 呢?因为我目前在负责的是监控平台的告警部分,负责采集到的监控数据会直接往 kafka 里塞,然后告警这边需要从 kafka topi ...
随机推荐
- python(8)- python基础数据类型
数据类型 计算机顾名思义就是可以做数学计算的机器,因此,计算机程序理所当然地可以处理各种数值.但是,计算机能处理的远不止数值,还可以处理文本.图形.音频.视 频.网页等各种各样的数据,不同的数据,需要 ...
- com关于IUnknown接口
com定义的每个接口都必须从IUnknown继承过来,主要原因是IUnknown接口提供了两个很重要的特性:生存期控制和接口查询. 客户程序仅仅能通过接口与com对象进行通信.尽管客户程序能够无论对象 ...
- Laravel建站05--缓存、时间日期处理包
缓存 Laravel 给多种缓存系统提供丰富而统一的 API,缓存配置信息位于 config/cache.php,在这个文件中你可以为你的应用程序指定默认的缓存驱动,Laravel 支持当前流行的缓存 ...
- SharePoint ULS Log Viewer 日志查看器
SharePoint ULS Log Viewer 日志查看器 项目描写叙述 这是一个Windows应用程序,更加轻松方便查看SharePoint ULS日志文件.支持筛选和简单的视图. 信息 这是一 ...
- GCJ Qualification Round 2016 C题
题意是给定了一个叫“jamcoin”的定义,让你生成足够数量满足条件的jamcoin. jamcoin其实就可以理解成一个二进制整数,题目要求的要么长度为16位,要么为32位,一头一尾两个位必须是1, ...
- javaweb开发之jsp
一.WEB应用的目录结构 通常我们是在IDE中创建web应用程序,IDE自动为我们实现了WEB的目录结构,下面来看如何徒手创建一个WEB程序. 首先来看一下Tomcat自带的一个web应用的目录结构 ...
- 九度OJ 1108:堆栈的使用 (堆栈)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:6705 解决:1974 题目描述: 堆栈是一种基本的数据结构.堆栈具有两种基本操作方式,push 和 pop.Push一个值会将其压入栈顶, ...
- java之冒泡排序
//冒泡排序(Bubble Sorting)的基本思想是:通过对待排序序列从后向前(从下标较大的元素开始),依次比较相邻元素的排序码,若发现逆序则交换,使排序码较小的元素逐渐从后部移向前部(从下标较大 ...
- virtualbox Units specified don't exist. SHSUCDX can't install.
version infomatin: virtual box: 5.1.12 platform: win10 x64 target OS: win7 x64 问题 在win10系统上,使用virtua ...
- appium():PageObject&PageFactory
Appium Java client has facilities which components to Page Object design pattern and Selenium PageFa ...