基于mina的短连接组件以及与spring、spring boot的集成

SpringBoot集成Mina快速入门Demo Apache的Mina(Multipurpose Infrastructure Networked Applications)是一个基于java nio的网络通信框架。主要屏蔽了网络通信的一些细节,对Socket进行封装,并且是NIO的一个实现架构,可以帮助我们快速的开发网络通信,常用于游戏的开发、中间件服务端的程序中。Mina最主要的工作就是把底层传输的字节码转换为Java对象,提供给应用程序;或者把应用程序返回的结果转换为字节码,交给底层传输。 阅读详情

尽管各类标准的系统间交互组件已经非常流行,但采用自定义报文、基于原生socket进行系统间数据交互的模式依然存在。

原生socket在做一般的测试性开发时,确实能简便的达成目标。但在做企业应用时,若是在报文交互的需求上,再增加关于传输状态、处理策略等实际需求时,则显得吃力。

mina作为高性能开源网格框架,其功能相当丰富。尽管本文的短连接需求从实现上来看,使用mina作为核心,显得大材小用,但是,从实际应用上,能很好的满足业务需要及便捷的使用(本文很大意义上是马上造了一个简单的轮子)。

为了不陷入细节,后文将首先介绍可使用本文组件的场景、以及如何使用,然后再对组件的内部实现进行介绍,最后提供一个组件的下载地址。

 

一、本文假定的需求场景

1、两个系统间使用自定义报文进行短连接同步交互。即:一方为服务方,一直处于监听状态,另外一方作为客户端连接后,进行数据发送,当收到回应或者设定的超时时间到达后,断开与服务方的连接;

*2、假设自定义报文的格式为:8字节长度+对象的json字符串(UTF-8编码),其中“8字节长度”的值不包含这8个字节,其值为包含“对象的json字符串”经过UTF-8编码之后得到的长度值,8字节长度的编码为long的高节节在前。

    *:关于第2点数据报文的定义在后文的介绍中,主要是影响工具类MessageUtils以及消息解码方法的实现。若采用其他的报文格式,则需要调整MessageUtils中相关方法的实现,另外就是关于长度,需要调整MessageDecoder的doDecode解码方法的实现

 

二、使用本文的组件准备相关

本文基于的mina版本是2.0.17,jdk为1.7。

在使用本文提供的组件时,对maven项目来说,需要做如下依赖:

<dependency>
    <groupId>org.apache.mina</groupId>
    <artifactId>mina-core</artifactId>
    <version>2.0.17</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.46</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.25</version>
</dependency>

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.25</version>
</dependency>

对非maven项目,则需要在你设定的lib里包含以上的jar包。

 

三、如何使用

本文组件的目标是在mina的基础上,将server、client的初始化实现的尽量简单且贴近实际,因此,一般情况下,你仅需构造一个MessageServer、若干个MessageShortClient对象(可在短连接的业务实现处即时构造),然后对server、client对象各自实现一个业务层的MessageProcessor对象并进行关联,对业务层的MessageProcessor,可选择性的实现其方法。

以下服务端测试代码、客务端测试代码是对以上使用方法的直观解释。

1、服务端测试代码:

package com.bn.zbase;

import com.alibaba.fastjson.JSON;
import com.bn.zbase.message.*;
import com.bn.zbase.message.biz.MessageProcessor;
import com.bn.zbase.message.biz.DefaultServerMessageProcessor;
import com.bn.zbase.message.util.MessageUtils;
import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Created by zcn on 2018/4/20.
 */
public class BizServerTests {
    private static final Logger log = LoggerFactory.getLogger(BizServerTests.class);

    public static void main(String[] args) {
        MessageProcessor messageProcessor = new DefaultServerMessageProcessor() {
            @Override
            public void processReceivedMessage(IoSession session, String strJsonMessage) {
                log.info("接收到客户端消息:" + strJsonMessage);
                Object objRet = JSON.parse(strJsonMessage);
                session.write(MessageUtils.encodeMessageObj2IoBuffer(objRet));
            }
        };

        MessageServer messageServer = new MessageServer("localhost", 8989);
        messageServer.setMessageProcessor(messageProcessor);
        messageServer.start();

        try {
            Thread.sleep(30 * 10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        messageServer.shutdown();
    }
}

 

2、客户端代码:

package com.bn.zbase;

import com.alibaba.fastjson.JSON;
import com.bn.zbase.message.biz.MessageProcessor;
import com.bn.zbase.message.biz.DefaultClientMessageProcessor;
import com.bn.zbase.message.MessageShortClient;
import com.bn.zbase.message.util.MessageSendResult;
import org.apache.mina.core.session.IoSession;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;

/**
 * Created by zcn on 2018/4/23.
 */
public class BizClientTests {
    private static final Logger log = LoggerFactory.getLogger(BizClientTests.class);

    @Test
    public void testSendObj() throws IOException {
        DiagramEntity objMessage = new DiagramEntity();
        objMessage.setName("张三三");
        objMessage.setCode("X001");

        MessageProcessor clientProcessor = new DefaultClientMessageProcessor() {
            @Override
            public void processReceivedMessage(IoSession session, String strJsonMessage) {
                DiagramEntity objRet = JSON.parseObject(strJsonMessage, DiagramEntity.class);
                log.info("收到服务器反馈:" + JSON.toJSONString(objRet));
            }

            @Override
            public void complete(MessageSendResult sendResult, Object objOriginalMessage) {
                log.info("操作完成状态:" + sendResult.getDesc());
            }
        };

        for (int i = 0; i < 1000; i++) {
            MessageShortClient messageShortClient = new MessageShortClient("localhost", 8989, 10);
            messageShortClient.setMessageProcessor(clientProcessor);
            messageShortClient.sendMessage(objMessage);

            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class DiagramEntity {
    private String name;
    private String code;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }
}


四、实现细节

1、结构


上图为本组件的实现类图:

1.1 在mina派生上,按照其约定,扩展了IoHandler,将其分为ClientMessageHandler、ServerMessageHandler,当然,其实也没做什么特别的工作,主要是在事件处理方法内,添加了业务可能使用的几个探点(探点的实现是MessageProcessor);

1.2 还是mina派生,对编解码器MessageCodecFactory以及具体的编、解码单元(MessageEncoder、MessageDecoder)进行了扩展,这部分也是标准处理(为适应自定义的报文格式),参考了网友的文章,在组件内部的代码内也做了说明;

1.3 报文数据转换工具类MessageUtils。本类提供了适用于假定报文格式的常用数据转换方法,其使用贯穿于整个组件,你可以随时使用其进行数据转换;

1.4 业务层报文数据处理接口MessageProcessor以及其实现类。mina的IoHandler已经对常用的会话、消息事件等做了抽象,然而我们在这里仍做了一个自己的实现:一方面是由于作者想提供一个相对简单明了的业务层处理派生体系;另外一方面,当面对连接参数错误等情况时,一时没有找到IoHandler如何实现判断的方法(当然,之后会更深入的查看mina)。

    MessageProcessor接口的实现是你在实际业务应用时,应该必需要做的,否则按照默认的体系,你除了很方便的创建出server、client对象,将干不了任何业务相关的事儿……

1.5 枚举MessageSendResult。定义了几个常用的发送结果状态,当你在实现MessageProcessor.complete方法进行发送完成后的处理时,可以获取到某种状态,这些状态当前有以下:

OK("会话正常完成", 0),
CONNECT_ERROR("连接错误", 1),
CONNECT_PARAERROR("连接参数错误", 2),
CONNECT_NORESPONSE("未收到服务器应答", 3);

1.6 最后,也是必需要使用到的两个类:MessageServer、MessageShortClient。

对MessageServer,如“三、如何使用”节中的“服务端测试代码”内示例,你通常仅需要使用带参的构造函数(MessageServer(hostname, port))来构造一个server对象,然后设置好其业务消息处理对象MessageProcessor,最后start就完成了(程序结束的时候你应该再使用shutdown关掉服务器)。当然在,spring中集成时,并不需要shutdown。

对MessageClient,当你使用带参构造函数MessageClient(destHostname,destPort)时,默认的空闲超时时间是10秒,即当你发送完消息(sendMessage)后,最多10秒钟,短连接结束,关于连接完成的发送结果状态,你应该使用MessageProcessor的complete完成处理。

 

五、与spring集成

尽管我们当前使用的spring版本已经基本都是支持注解构造bean了,这里我仍然使用xml配置的方式对组件在spring中的集成做说明。其实是非常简单的,仅需要集成MessageServer:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
  <bean id="defaultMinaServerMessageProcessor" class="com.bn.zbase.message.biz.DefaultServerMessageProcessor"></bean>
  
  <bean id="minaMessageServer" class="com.bn.zbase.message.MessageServer" init-method="start">
    <property name="hostname" value="127.0.0.1"></property>
    <property name="port" value="8989"></property>
    <property name="messageProcessor" ref="defaultMinaServerMessageProcessor"></property>
  </bean>
</beans>

 

六、与spring boot集成

spring boot的方式当然是通吃了,这里使用注解配置实现:

package com.bn.zbase.config;

import com.alibaba.fastjson.JSON;
import com.bn.zbase.message.MessageServer;
import com.bn.zbase.message.biz.MessageProcessor;
import com.bn.zbase.message.biz.DefaultServerMessageProcessor;
import com.bn.zbase.message.terminal.AbstractMessageTerminal;
import com.bn.zbase.message.util.MessageUtils;
import org.apache.mina.core.session.IoSession;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Created by zcn on 2018/4/24.
 */
@Configuration
public class MinaMessageConfiguration {

    @Bean(name="messageServer", initMethod = "start")
    public AbstractMessageTerminal messageServer() {
        MessageProcessor messageProcessor = new DefaultServerMessageProcessor() {
            @Override
            public void processReceivedMessage(IoSession session, String strJsonMessage) {
                System.out.println("收到客户端信息:" + strJsonMessage);
                Object objRet = JSON.parse(strJsonMessage);
                session.write(MessageUtils.encodeMessageObj2IoBuffer(objRet));
            }
        };
        MessageServer obj = new MessageServer("localhost", 8989);
        obj.setMessageProcessor(messageProcessor);
        return obj;
    }
}

 

七、其他问题

1、MessageShortClient类并非是线程安全的,事实上,也没有必要,因为本来就是用完即焚;

2、开源问题,在最后的组件下载中,当前提供的是一个源码类型的jar包,并没有提供本组件的实现工程,原因是本组件是基于当前一个未完成的开源框架内实现的(子功能模块),在未来完成开源框架后,将会提供整个项目。

 

八、组件下载

见: https://download.youkuaiyun.com/download/smartcore/10374257


Spring Boot集成WebSSH:从浏览器直连服务器的完整实践 传统SSH客户端在安装配置、权限管理和协作方面存在天然短板,而WebSSH技术通过浏览器直接连接服务器,正在成为运维平台、云厂商控制台和内网管理系统的核心能力。其原理是在浏览器和SSH服务之间引入WebSocket全双工通信,由后端充当代理完成数据转发,既保证了实时交互,又将权限控制收口到服务端。基于Spring Boot框架,配合JSch连接SSH、Xterm.js渲染终端,可以快速搭建一套生产可用的WebSSH方案。然而实际操作中,字符集乱码、WebSocket会话泄漏、跨网络断线以及Nginx代理适配 阅读详情

相关推荐

Spring Boot与Mina深度整合:高效网络服务的开箱即用方案

Spring Boot是由Pivotal团队提供的一个开源Java框架,旨在简化Spring应用的创建和开发过程。它遵循“约定优于配置”的原则,提供了一种快速配置、开发和部署Spring应用程序的方法。Spring Boot的应用程序通常只需要很少的配置即可运行,这大大减少了传统Spring应用的繁琐配置和依赖管理的工作量。

weixin_32661831的博客 869

springboot+mina框架服务端的实现(一) ------ pom依赖、mina配置类、自定义协议以及编解码器的实现

来吧,一步一步搭建mina服务端,原理往后再说! 首先利用springboot的插件新建一个maven项目 一、 pom.xml 所需依赖 首先加入mina核心依赖 <!-- https://mvnrepository.com/artifact/org.apache.mina/mina-core --> <dependency> <groupId>org.a...

一个胖子IT男的博客 6592

Spring Boot与Mina网络应用实践指南

Spring Boot是一个全新的Spring应用程序框架,其核心目的是简化基于Spring的应用开发,它提供了一种快速开发新Spring应用的方式,无需配置过多的样板代码、XML配置和依赖描述文件。通过使用Spring Boot,开发者能够更专注于业务逻辑的实现,而不是底层的配置和框架整合工作。Apache Mina是一个网络应用框架,它基于Java NIO (New I/O) API构建,为开发高性能、高可靠性的网络应用程序提供了一套完整的解决方案。

weixin_42515392的博客 416

Spring boot 集成mina框架

一、Apache mina框架是什么? https://baike.baidu.com/item/Apache%20MINA\ 二、如何集成并使用mina框架 1.引入pom依赖 <dependency> <groupId>org.apache.mina</groupId> <artifact...

chenyi406的博客 3112

springboot整合mina

springboot 整合了mina 并自定义解码器 复制进去导个包即可食用

spring boot 整合mina 串口

找了很长时间网上没有一个详细整合的例子,现在已整合成功 放上来让大家参照,少走弯路,稍后会放出博客说明 使用idea 打开后可以直接使用的例子,很珍贵

Spring Boot集成Mina的Socket资源管理:从稳定通信到高性能优化

Spring Boot集成Mina的Socket资源管理:从稳定通信到高性能优化

1089

springboot 深度整合mina开箱即用

springboot 深度整合mina开箱即用,适合新手上来研究。希望下载过的同学能来评论。

Spring boot 使用mina

spring boot使用mina需要的依赖: <dependency> <groupId>org.apache.mina</groupId> <artifactId>mina-core</artifactId> <version>2.0.13</version> </dependen...

qingyufeng的博客 3629

springboot mina 串口对接

springboot集成mina实现串口协议对接,包含断包、粘包处理。串口协议发送与接收是异步的,发送没有返回,只能通过监听获取。

mina新手教程源码 mina+springboot+idea最简单的案例。

mina新手案例,mina新手教程源码 mina+springboot最简单的案例。用的IDEA * mina服务端 * 1、添加@Controller注解和 @PostConstruct注解,代表启动springboot项目时也调用该类下的该方法, * 启动springboot项目,会启动两个服务两个端口,一个是http服务,一个是mina服务。两个服务互不影响 * 2、如果不想启动springboot,可以单独运行mina服务端的main方法。

spring整合mina开发web项目和简单mina客户端的使用

场景要求在web项目中使用mina与一些客户端通讯xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 htt

ihchenchen的博客 1万+

springboot 整合mina 源码,nio通讯基础教程,mina框架基础教程.rar

springboot 整合mian框架tcp通讯源码, 适合初学者另附java nio及mina相关教程

Spring Boot Starter之Mina框架封装

Mina通信框架封装

何忆清风 5万+

手把手教你解决Kernel panic报错:init找不到的5种排查方法(附NFS挂载实战)

本文深入解析了Linux系统启动时出现“Kernel panic - not syncing: No working init found”报错的根本原因,并提供了五种系统性的排查方法。文章结合NFS挂载根文件系统的实战场景,详细阐述了从动态链接库依赖、内核引导参数、NFS权限配置、文件系统完整性到内核配置干扰的完整排查路径,帮助开发者快速定位并解决这一常见的系统启动故障。

weixin_29159995的博客 193

【Claude Code】Claude Code 使用指南

本文介绍了AI编码助手Claude的基础和进阶操作指南。基础部分涵盖启动命令、模式切换(自动编辑/Plan/Yolo模式)、资源监控等核心功能,重点讲解了斜杠命令的使用方法。进阶操作详细说明了CLAUDE.md文件的创建与管理,包括项目规范、代码风格等内容的配置,以及如何通过该文件建立持久上下文。同时提醒了使用过程中的安全风险,建议通过配置文件限制AI对关键代码的访问权限。全文提供了完整的操作指引和安全建议,帮助开发者高效安全地使用Claude进行编码辅助。

大家好,我是敖云岚,一个沉迷代码的 “技术玩家”。擅长 Java、C++ 开发,对 MySQL、Redis、RabbitMQ 等技术也颇有研究。博客里既有硬核技术干货,也有诙谐幽默的编程日常分享。愿和你一起,笑着学技术,快乐敲代码! 1万+

Spring Boot集成 mina 服务端搭建

Spring Boot集成 mina 服务端搭建 <!--Mina框架依赖 --> <dependency> <groupId>org.apache.mina</groupId> <artifactId>mina-core</artifactId> <version>2.0.2</version>

人生一张西的博客 1336

AI大模型开发——transformer模型超全完整版(0基础可懂)

为了更深入的了解transformer模型,我们首先从transformer的诞生聊起吧。transformer在2017年由Vaswani等人首次提出,它摒弃了之前流行的循环神经网络和卷积神经网络的架构,引入了自注意力机制( Self-Attention),显著提高了处理序列数据的能力和效率。transformer模型的这种设计使其在处理长距离依赖问题时, 相比于传统的循环神经网络和长短期记忆网络(LSTM)表现得更加出色,至此, 开启了NLP技术的新篇章。

m0_74922316的博客 2120

Mina基础(七):Mina整合Spring服务端、Spring boot 客户端

Spring 作为服务端 将类交给Spring管理,通过配置文件注入所需要的Bean,通过配置文件绑定端口启动Mina服务端。 项目整体代码目录结构(见上一篇): 1. 设置I/O接收器 <!-- 设置I/O接收器,指定接收到请求后交给handler处理 --> <!-- 此部分被 NioSocketAcceptor 隐式使用,无此则会...

矢落叶の博客 8113

告别CNN局限:用Transformer+迁移学习搞定高光谱图像分类(附Pytorch代码)

本文探讨了如何利用Transformer的自注意力机制和迁移学习策略解决高光谱图像分类中的挑战。通过结合CNN的局部特征提取和Transformer的全局建模能力,提出的DenseTransformer架构在多个数据集上实现了显著的性能提升。文章还提供了详细的PyTorch实现代码和工程优化技巧,帮助开发者快速应用这一技术。

weixin_32771907的博客 604

±10V ADC 输入电路的高共模差分输入电压

这篇文章分析了±10V ADC输入电路的设计需求与挑战,重点讨论了高共模差分输入电压的处理方案。文章首先明确了设计目标,即安全转换±10V差分信号并保持信号完整性,同时克服高共模电压、阻抗匹配和噪声优化等难点。随后详细比较了仪表放大器和差分放大器的性能特点,并提出了器件选型理论。在信号链架构部分,文章通过公式推导阐述了增益设置、共模抑制设计和输入阻抗匹配等关键技术。此外,还建立了噪声源模型,提出了噪声优化措施。最后,文章总结了设计验证方法,并扩展了在工业保护和生物电信号采集等场景的应用。该设计强调根据具体应

泛红尘的博客 1959

spring boot java开发网络编程Apache Mina

springboot开发 pom.xml添加依赖 <dependency> <groupId>org.apache.mina</groupId> <artifactId>mina-integration-beans</artifactId> <version>2.0.16</version> </dependency> <dependency> <groupId&

qq_42946963的博客 7268

YOLOv8 超参数调优教程! 使用Ray Tune进行高效的超参数调优!

YOLOv8超参数调优教程!😎 使用Ray Tune进行高效的超参数调优!

Coding... 1万+
上一篇: spring集成Thymeleaf,模板页面中调用类的静态成员
下一篇: 扩展fastjson的SimplePropertyPreFilter,以过滤不需要序列化的属性
smartcore
博客等级 码龄19年 30粉丝 47原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值