Socket通信封装MIna框架--含羞代放

2024-08-29 14:32

本文主要是介绍Socket通信封装MIna框架--含羞代放,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

[TOC]

Mina异步IO使用的Java底层JNI框架,Mina提供服务端和客户端,将我们的业务解耦开发.真正做到高内聚低耦合的思想

核心类

  • IoService :Mina中将服务端和客户端都看成是服务,这里提供统一接口IoService,这个接口的作用就是用来处理套接字机制。也正是IoService来监听消息返回消息这些步骤,
    可以说IoService就是我们Mina中核心
  • IoProcessor:这个接口在另一个线程上,负责检查是否有数据在通道上读写,也就是说它也拥有自己的Selector,这是与我们使用JAVA NIO 编码时的一个不同之处,通常在JAVA NIO 编码中,我们都是使用一个Selector,也就是不区分IoService与IoProcessor 两个功能接口。另外,IoProcessor 负责调用注册在IoService 上的过滤器,并在过滤器链之后调用IoHandler
  • IoFilter : 定义了一些拦截器 , 和我们web中拦截器一样,用来横向拦截处理一些全局的操作(日志处理,编码处理)。其中我们必须注意的是加解密消息。
    作为一个好的框架肯定是有默认的拦截器的(TextLineCodecFactory )。默认拦截器可以叫消息强制转换为String类型。毕竟String最通用
  • IoHandler : 这个是我们处理消息的逻辑,前面的拦截器只是在接受是进行一些验证、翻译的功能。拿到数据之后我们需要做的事情就是在IoHandler中

各个击破

IoService

  • 首先我们已服务端NioSocketAcceptor为列,看看我们的服务类之间的结构依赖关系
    NioSocketAcceptor结构图
  • IoService是服务的鼻祖,无论在我们看来的服务端还是客户端都得继承它(间接继承)。在IoService中我们会定义我们消息的处理过滤器(上文的拦截器),消息处理的业务类
    在上文简介中我们知道,这一步其实是IoProcessor来完成,那么IoProcessor在什么出现呢。比如Mina框架中用来创建服务端类NioSocketAcceptor。他直接继承了AbstractPollingIoAcceptor。而AbstractPollingIoAcceptor类中根据参数创建了我们需要的IoProcessor.从而我们有了IoProcessor就可以执行消息间的通信了。
    IoProcess的产生
  • 所以过滤器、处理器实在我们服务启动之前配置好的。一旦启动成功就无法再修改了。我们服务端NioSocketAcceptor通过bind方法就可以绑定到指定端口上。我们这里的绑
    定实现了多态绑定。我们可以绑定多个服务。

/**
* {@inheritDoc}
*/
@Override
public final void bind(Iterable<? extends SocketAddress> localAddresses) throws IOException {if (isDisposing()) {throw new IllegalStateException("The Accpetor disposed is being disposed.");}if (localAddresses == null) {throw new IllegalArgumentException("localAddresses");}List<SocketAddress> localAddressesCopy = new ArrayList<>();for (SocketAddress a : localAddresses) {checkAddressType(a);localAddressesCopy.add(a);}if (localAddressesCopy.isEmpty()) {throw new IllegalArgumentException("localAddresses is empty.");}boolean activate = false;synchronized (bindLock) {synchronized (boundAddresses) {if (boundAddresses.isEmpty()) {activate = true;}}if (getHandler() == null) {throw new IllegalStateException("handler is not set.");}try {Set<SocketAddress> addresses = bindInternal(localAddressesCopy);synchronized (boundAddresses) {boundAddresses.addAll(addresses);}} catch (IOException | RuntimeException e) {throw e;} catch (Exception e) {throw new RuntimeIoException("Failed to bind to: " + getLocalAddresses(), e);}}if (activate) {getListeners().fireServiceActivated();}
}

在上面我们可以看到bind最后是去激活对应的监听器。我们一个IoServer处理一个线程中的消息。我们监听器就是监听线程内的消息。每一次的绑定都会有不同的监听器、ioSession去专门处理消息之间的通信。我们可以通过IoSession设置一些请求数据完成数据的权限验证。

  • 在服务创建的时候我们正常需要设置IoSession的一些配置。通过getSessionConfig方法获取IoSessionConfig。里面设置参数常用如下:
    • setReadBufferSize : 设置读取数据的缓冲区大小
    • setMinReadBufferSize: 设置缓冲区最大值
    • setMaxReadBufferSize: 设置缓冲区最小值
    • setThroughputCalculationInterval: 设置通道计算时间 默认3s
    • setIdleTime(IdleStatus status, int idleTime): status 设置是一方还是双方 , idLetime 是超过多久就会进入空闲状态
IoAcceptor acceptor=new NioSocketAcceptor();    
acceptor.getSessionConfig().setReadBufferSize(2048);    
acceptor.getSessionConfig.setIdleTime(IdleStatus.BOTH_IDLE,10);

IoFilter

在IoService中有获取filter链的一个方法 DefaultIoFilterChainBuilder getFilterChain() , 我们需要做的就是定义过滤器,然后通过该方法获取过滤链加入到请求链上。我们自定义过滤器也很简单,只需要继承IoFilterAdapter这个类就好了。

  acceptor.getFilterChain().addLast("codec",  new ProtocolCodecFilter(new TextLineCodecFactory( 
Charset.forName("UTF-8"),LineDelimeter.WINDOWS.getValue(),LineDelimiter. WINDOWS.getValue()))    
);    

TextLineCodecFactory 这个类是Mina提供的编解码工厂,这个工厂的特性是以换行符'rn'为结束通信的标志。也就是说如果我们传递消息没有换行符,另外一段会继续接受消息知道接受到'rn'才会接受,并把接受到的消息通过编解码器转到IoHandler层供业务层处理。(这里博主被坑在这里了)

IoHandler

  • 到了这一步,我们的通信基本就已经完成了。剩下的事情已经和Mina基本没多大关联了。我们将在这里处理业务逻辑,使用到的就是Handler提供的接收消息和发送消息两个功能。
    这里我们需要注意的是Handler提供messageReceivedmessageSent并不是字面意思。前者就是消息的接受,但是后者并不是消息的发送。我们常用的发送消息是session.write方法。

总结

    今天我们了解了Mina工作的流程,主要就是IoFilter和IoHandler实现消息的通信 。 千里之行始于足下,一点一点的进步。下面贴出一份总结的图谱帮助我们理解Mina流程

Mina流程

加入战队

加入战队

微信公众号

微信公众号

这篇关于Socket通信封装MIna框架--含羞代放的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1118127

相关文章

Python用Flask封装API及调用详解

《Python用Flask封装API及调用详解》本文介绍Flask的优势(轻量、灵活、易扩展),对比GET/POST表单/JSON请求方式,涵盖错误处理、开发建议及生产环境部署注意事项... 目录一、Flask的优势一、基础设置二、GET请求方式服务端代码客户端调用三、POST表单方式服务端代码客户端调用四

解决若依微服务框架启动报错的问题

《解决若依微服务框架启动报错的问题》Invalidboundstatement错误通常由MyBatis映射文件未正确加载或Nacos配置未读取导致,需检查XML的namespace与方法ID是否匹配,... 目录ruoyi-system模块报错报错详情nacos文件目录总结ruoyi-systnGLNYpe

Python Web框架Flask、Streamlit、FastAPI示例详解

《PythonWeb框架Flask、Streamlit、FastAPI示例详解》本文对比分析了Flask、Streamlit和FastAPI三大PythonWeb框架:Flask轻量灵活适合传统应用... 目录概述Flask详解Flask简介安装和基础配置核心概念路由和视图模板系统数据库集成实际示例Stre

Olingo分析和实践之OData框架核心组件初始化(关键步骤)

《Olingo分析和实践之OData框架核心组件初始化(关键步骤)》ODataSpringBootService通过初始化OData实例和服务元数据,构建框架核心能力与数据模型结构,实现序列化、URI... 目录概述第一步:OData实例创建1.1 OData.newInstance() 详细分析1.1.1

Python实现MQTT通信的示例代码

《Python实现MQTT通信的示例代码》本文主要介绍了Python实现MQTT通信的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 安装paho-mqtt库‌2. 搭建MQTT代理服务器(Broker)‌‌3. pytho

Spring 框架之Springfox使用详解

《Spring框架之Springfox使用详解》Springfox是Spring框架的API文档工具,集成Swagger规范,自动生成文档并支持多语言/版本,模块化设计便于扩展,但存在版本兼容性、性... 目录核心功能工作原理模块化设计使用示例注意事项优缺点优点缺点总结适用场景建议总结Springfox 是

Golang如何对cron进行二次封装实现指定时间执行定时任务

《Golang如何对cron进行二次封装实现指定时间执行定时任务》:本文主要介绍Golang如何对cron进行二次封装实现指定时间执行定时任务问题,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录背景cron库下载代码示例【1】结构体定义【2】定时任务开启【3】使用示例【4】控制台输出总结背景

Python的端到端测试框架SeleniumBase使用解读

《Python的端到端测试框架SeleniumBase使用解读》:本文主要介绍Python的端到端测试框架SeleniumBase使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全... 目录SeleniumBase详细介绍及用法指南什么是 SeleniumBase?SeleniumBase

Python中对FFmpeg封装开发库FFmpy详解

《Python中对FFmpeg封装开发库FFmpy详解》:本文主要介绍Python中对FFmpeg封装开发库FFmpy,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、FFmpy简介与安装1.1 FFmpy概述1.2 安装方法二、FFmpy核心类与方法2.1 FF

如何解决Druid线程池Cause:java.sql.SQLRecoverableException:IO错误:Socket read timed out的问题

《如何解决Druid线程池Cause:java.sql.SQLRecoverableException:IO错误:Socketreadtimedout的问题》:本文主要介绍解决Druid线程... 目录异常信息触发场景找到版本发布更新的说明从版本更新信息可以看到该默认逻辑已经去除总结异常信息触发场景复