• 使用Spring Integration接收TCP与UDP请求


    1. 简介

    Spring Integration 是一个开源的项目,它是 Spring 生态系统的一部分,旨在简化企业集成(Enterprise Integration)的开发。它提供了一种构建消息驱动的、松散耦合的、可扩展的企业应用集成解决方案的方式。Spring Integration 基于 Spring Framework 构建,使开发者能够更容易地将不同的系统、应用程序和服务整合到一个协调的整体中。

    Spring Integration 主要有以下作用

    1. 消息驱动的集成:Spring Integration 基于消息传递的模式,允许系统和应用程序通过消息进行通信。这种模式可以用于异步集成,以确保系统能够松散耦合,以及在高负载和大规模情况下具有良好的性能。
    2. 模块化和可扩展:Spring Integration 提供了一组模块,每个模块都用于处理特定类型的集成需求。这些模块可以按需组合和扩展,使开发者能够根据应用程序的需要选择合适的模块,并自定义它们。
    3. 集成各种传输协议和数据格式:Spring Integration 支持各种传输协议(例如,HTTP、JMS、FTP、SMTP等)和数据格式(例如,JSON、XML、CSV等),以便实现不同系统之间的数据传输和转换。
    4. 企业模式的集成:Spring Integration 提供了一些企业集成模式的实现,例如消息路由、消息转换、消息过滤、消息聚合等,以帮助解决不同场景下的集成挑战。
    5. 与 Spring 生态系统的集成:Spring Integration 与 Spring Framework 和 Spring Boot 紧密集成,开发者可以轻松整合已有的 Spring 应用程序,同时利用 Spring 的依赖注入和 AOP(面向切面编程)等功能。

    2. 代码实战

    本文主要介绍 Spring Integration 接收TCP与UDP请求的示例。在项目中,我们偶尔需要接收其他服务的TCP与UDP请求,此时使用Netty可能会过度设计,想要一个轻量级nio的TCP、UDP服务端的话,我们可以选择 Spring Integration。

    环境:

    1. JDK21
    2. SpringBoot 3.1.4
    3. Spring Integration 6.1.3

    2.1 导入依赖

    <parent>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-parentartifactId>
    <version>3.1.4version>
    <relativePath />
    parent>
    <dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-webartifactId>
    dependency>
    <dependency>
    <groupId>org.springframework.integrationgroupId>
    <artifactId>spring-integration-ipartifactId>
    dependency>

    注意:如果你的SpringBoot版本是2.x版本,那么你需要使用JDK21以下的版本,因为JDK中的包名有所更改。

    2.2 建立TCP服务端

    新建配置类TcpServerConfig,其中tcp.server.port需要到application.yml或者application.properties中进行配置。或者你也可以直接填写端口。

    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.integration.annotation.ServiceActivator;
    import org.springframework.integration.channel.DirectChannel;
    import org.springframework.integration.ip.tcp.TcpReceivingChannelAdapter;
    import org.springframework.integration.ip.tcp.connection.AbstractServerConnectionFactory;
    import org.springframework.integration.ip.tcp.connection.TcpNioServerConnectionFactory;
    @Slf4j
    @Configuration
    public class TcpServerConfig {
    @Value("${tcp.server.port}")
    private int PORT;
    /**
    * 创建连接工厂
    * @return
    */
    @Bean
    public AbstractServerConnectionFactory serverConnectionFactory() {
    TcpNioServerConnectionFactory tcpNioServerConnectionFactory = new TcpNioServerConnectionFactory(PORT);
    tcpNioServerConnectionFactory.setUsingDirectBuffers(true);
    return tcpNioServerConnectionFactory;
    }
    /**
    * 创建消息通道
    * @return
    */
    @Bean
    public DirectChannel tcpReceiveChannel() {
    return new DirectChannel();
    }
    /**
    * 创建tcp接收通道适配器
    * @return
    */
    @Bean
    public TcpReceivingChannelAdapter inboundAdapter() {
    TcpReceivingChannelAdapter adapter = new TcpReceivingChannelAdapter();
    adapter.setConnectionFactory(serverConnectionFactory());
    adapter.setOutputChannelName("tcpReceiveChannel");
    return adapter;
    }
    /**
    * 处理请求器
    * @param message
    */
    @ServiceActivator(inputChannel = "tcpReceiveChannel")
    public void messageReceiver(byte[] message) {
    // 处理接收到的TCP消息
    log.info("处理TCP请求");
    }
    }

    注意:在发送tcp报文的时候,tcp报文需要以\r\n结尾,否则无法正常接收报文。

    2.3 建立UDP服务端

    新建配置类UdpServerConfig,其中udp.server.port需要到application.yml或者application.properties中进行配置。或者你也可以直接填写端口。

    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.integration.annotation.ServiceActivator;
    import org.springframework.integration.channel.DirectChannel;
    import org.springframework.integration.dsl.IntegrationFlow;
    import org.springframework.integration.ip.dsl.Udp;
    import org.springframework.messaging.Message;
    @Slf4j
    @Configuration
    public class UdpServerConfig {
    @Value("${udp.server.port}")
    private int PORT;
    /**
    * 创建UDP服务器接收通道适配器
    * @return
    */
    @Bean
    public IntegrationFlow udpIn() {
    return IntegrationFlow.from(Udp.inboundAdapter(PORT))
    .channel("udpReceiveChannel")
    .get();
    }
    /**
    * 创建消息接收通道
    * @return
    */
    @Bean
    public DirectChannel udpReceiveChannel() {
    return new DirectChannel();
    }
    /**
    * 处理接收到的UDP消息
    * @param message
    */
    @ServiceActivator(inputChannel = "udpReceiveChannel")
    public void udpHandleMessage(Message<byte[]> message) {
    // 处理接收到的UDP消息
    byte[] payload = message.getPayload();
    log.info("处理UDP请求");
    }
    }

    3. 总结

    对比Netty,Spring Integration比较轻量级,也更容易集成到 SpringBoot 中,但是性能肯定不如Netty。这里也只是给接收TCP、UDP请求设计方面多一个选择。

  • 相关阅读:
    夜天之书 #67 为什么开源协议不授予商标权利?
    计算机网络第4章(网际层)----总结1
    1827. 最少操作使数组递增-贪心算法-原地修改数组
    MybatisPlus多表关联分页返回结果异常
    ChatGPT学习第三周
    Session会话追踪的实现机制
    java设计模式和面向对象编程思想
    SegNet & DeconvNet——论文阅读
    FastAPI 学习之路(三十三)操作数据库
    速览 NFT 期权赛道代表项目与发展前景
  • 原文地址:https://www.cnblogs.com/jonil/p/17778628.html