现在公司使用的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整体流程介绍的更多相关文章

  1. MQTT 协议学习:003-MQTT通信流程介绍

    背景 有关博文:通信报文的构成 . 上一讲说到可变头与消息体要结合不同的报文类型才能够进行分析(实际上,官方的文档的介绍顺序就是这样的) 那么,我们就来具体看看有关的报文类型. 在此之前 我们捋一捋完 ...

  2. JVM 整体流程介绍

    一. JVM自身的物理结构 从图中可以看出 JVM 的主要组成部分 ClassLoader(类加载器),Runtime Data Area(运行时数据区,内存分区),Execution Engine( ...

  3. Tomcat源码解析-整体流程介绍

    一.架构 下面谈谈我对Tomcat架构的理解 总体架构: 1.面向组件架构 2.基于JMX 3.事件侦听 1)面向组件架构 tomcat代码看似很庞大,但从结构上看却很清晰和简单,它主要由一堆组件组成 ...

  4. MINA学习之体系介绍

    基于MINA应用程序结构图: 我们可以看出,MINA是应用程序(客户端或服务端)和底层基于TCP,UDP等通讯协议的网络层之间的粘合剂.而且各个模块之间是相互独立的,你只需要在MINA体 系基础上设计 ...

  5. 【MINA学习笔记】—— 1.体系结构分析[z]

    前言 Apache的MINA框架是一个早年非常流行的NIO框架,它出自于Netty之父Trustin Lee大神之手.虽然目前市场份额已经逐渐被Netty取代了,但是其作为NIO初学者入门学习框架是非 ...

  6. MINA学习汇总

    MINA学习汇总 Apache Mina Server 是一个网络通信应用框架,用于开发高性能和高可用性的网络应用程序.它主要是对基于TCP/IP.UDP/IP协议栈的通信框架(然,也可以提供JAVA ...

  7. 02-FPGA设计流程介绍——小梅哥FPGA设计思想与验证方法视频教程配套文档

    芯航线——普利斯队长精心奉献 课程目标: 1.了解并学会FPGA开发设计的整体流程 2.设计一个二选一选择器并进行功能仿真.时序仿真以及板级验证 实验平台:芯航线FPGA开发板.杜邦线 实验内容: 良 ...

  8. Mybatis技术原理理——整体流程理解

    前言:2018年,是最杂乱的一年!所以你看我的博客,是不是很空! 网上有很多关于Mybatis原理介绍的博文,这里介绍两篇我个人很推荐的博文 Mybatis3.4.x技术内幕和 MyBaits源码分析 ...

  9. 《从0到1学习Flink》—— Apache Flink 介绍

    前言 Flink 是一种流式计算框架,为什么我会接触到 Flink 呢?因为我目前在负责的是监控平台的告警部分,负责采集到的监控数据会直接往 kafka 里塞,然后告警这边需要从 kafka topi ...

随机推荐

  1. web前端面试系列 - 数据结构(两个栈模拟一个队列)

    一. 用两个栈模拟一个队列 思路一: 1. 一个栈s1作为数据存储,另一个栈s2,作为临时数据存储. 2. 入队时将数据压人s1 3. 出队时将s1弹出,并压人s2,然后弹出s2中的顶部数据,最后再将 ...

  2. antd移动端onClick事件点击无效

    最近空余时间比较多,自己想学习react跟移动端的东西,就选用了antd-mobile库,框架搭好开发过程中遇到个问题,里面绑定的点击事件无效,不仅是antd自带的按钮无效,原生button点击也没反 ...

  3. 二进制安装Mysql 5.6(免编译)

    安装系统基础软包 yum install -y make bc perl gcc openssl openssl-devel ncurses ncurses-devel 安装方式:二进制免编译安装 查 ...

  4. Lance老师UI系列教程第九课->高仿比特币监控大师

    http://blog.csdn.net/lancees/article/details/22898971

  5. Android自己定义控件--下拉刷新的实现

    我们在使用ListView的时候.非常多情况下须要用到下拉刷新的功能.为了了解下拉刷新的底层实现原理,我採用自己定义ListView控件的方式来实现效果. 实现的基本原理是:自己定义ListView, ...

  6. iOS8的UIPresentationController

    本文转载至 http://kyfxbl.iteye.com/blog/2147888 从iOS8开始,controller之间的跳转特效,需要用新的API UIPresentationControll ...

  7. 【BZOJ3007】拯救小云公主 二分+几何+对偶图

    [BZOJ3007]拯救小云公主 Description     英雄又即将踏上拯救公主的道路……     这次的拯救目标是——爱和正义的小云公主.     英雄来到boss的洞穴门口,他一下子就懵了 ...

  8. mac下使用gnu gcc

    1 mac下安装gnu gcc brew search gcc brew install gcc@6 2 mac下编写c/c++代码所需的标准库和头文件 2.1 标准c++的库的头文件都是标准化了的, ...

  9. 小程序 富文本 的页面展示 json 数据处理 go-echo 为小程序提供feed流服务

    go生成页面 返回给web-view {{define "DBHtmlCode"}} <!DOCTYPE html> <html lang="zh-cm ...

  10. 解析json的方式

    一.Javascrip操作json 原始方式: var str1 = '{ "name": "jacun", "addr": "b ...