springboot 整合 netty框架, 实现 心跳检测,自动重连

简介: springboot 整合 netty框架, 实现 心跳检测,自动重连

Spring Boot 整合 Netty 框架实现心跳检测和自动重连

1. 引入依赖

pom.xml 中添加 Netty 和 Spring Boot 相关依赖。

<dependencies>
    <!-- Spring Boot Starter -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    
    <!-- Netty Dependency -->
    <dependency>
        <groupId>io.netty</groupId>
        <artifactId>netty-all</artifactId>
        <version>4.1.63.Final</version>
    </dependency>
    
    <!-- 其他相关依赖 -->
</dependencies>
2. 配置 Netty 服务端

创建一个 Netty 服务器启动类,配置心跳检测机制。

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.timeout.IdleStateHandler;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
 
import java.util.concurrent.TimeUnit;
 
@Component
public class NettyServer implements CommandLineRunner {
 
    private final int port = 8080;
 
    @Override
    public void run(String... args) throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
 
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
             .channel(NioServerSocketChannel.class)
             .childHandler(new ChannelInitializer<SocketChannel>() {
                 @Override
                 public void initChannel(SocketChannel ch) throws Exception {
                     ch.pipeline().addLast(new IdleStateHandler(5, 7, 10, TimeUnit.SECONDS));
                     ch.pipeline().addLast(new HeartbeatHandler());
                 }
             })
             .option(ChannelOption.SO_BACKLOG, 128)
             .childOption(ChannelOption.SO_KEEPALIVE, true);
 
            ChannelFuture f = b.bind(port).sync();
            f.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }
}
3. 实现心跳检测处理器

创建一个 HeartbeatHandler 类处理心跳检测。

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.handler.timeout.IdleState;
 
public class HeartbeatHandler extends ChannelInboundHandlerAdapter {
 
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent event = (IdleStateEvent) evt;
            if (event.state() == IdleState.READER_IDLE) {
                System.out.println("读空闲");
                // 关闭连接
                ctx.close();
            } else if (event.state() == IdleState.WRITER_IDLE) {
                System.out.println("写空闲");
            } else if (event.state() == IdleState.ALL_IDLE) {
                System.out.println("读写空闲");
                // 发送心跳包
                ctx.writeAndFlush("ping\n");
            }
        } else {
            super.userEventTriggered(ctx, evt);
        }
    }
 
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }
}
4. 配置 Netty 客户端

创建一个 Netty 客户端启动类,实现自动重连和心跳检测。

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.timeout.IdleStateHandler;
import org.springframework.stereotype.Component;
 
import java.util.concurrent.TimeUnit;
 
@Component
public class NettyClient {
 
    private final String host = "localhost";
    private final int port = 8080;
    private final int MAX_RETRY = 5;
    private int retry = 0;
 
    public void start() {
        EventLoopGroup group = new NioEventLoopGroup();
 
        try {
            Bootstrap b = new Bootstrap();
            b.group(group)
             .channel(NioSocketChannel.class)
             .option(ChannelOption.SO_KEEPALIVE, true)
             .handler(new ChannelInitializer<SocketChannel>() {
                 @Override
                 public void initChannel(SocketChannel ch) throws Exception {
                     ch.pipeline().addLast(new IdleStateHandler(0, 4, 0, TimeUnit.SECONDS));
                     ch.pipeline().addLast(new ClientHeartbeatHandler());
                 }
             });
 
            connect(b);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    private void connect(Bootstrap b) {
        b.connect(host, port).addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                if (future.isSuccess()) {
                    System.out.println("连接服务器成功");
                } else {
                    System.out.println("连接服务器失败,尝试重连");
                    retry++;
                    if (retry < MAX_RETRY) {
                        future.channel().eventLoop().schedule(() -> connect(b), 2 << retry, TimeUnit.SECONDS);
                    } else {
                        System.out.println("重连失败次数达到最大,放弃连接");
                    }
                }
            }
        });
    }
}
5. 实现客户端心跳处理器

创建一个 ClientHeartbeatHandler 类处理心跳包。

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.handler.timeout.IdleState;
 
public class ClientHeartbeatHandler extends ChannelInboundHandlerAdapter {
 
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent event = (IdleStateEvent) evt;
            if (event.state() == IdleState.WRITER_IDLE) {
                System.out.println("发送心跳包");
                ctx.writeAndFlush("ping\n");
            }
        } else {
            super.userEventTriggered(ctx, evt);
        }
    }
 
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("连接断开,尝试重连");
        // 在这里实现重连逻辑
        // 比如: ctx.channel().eventLoop().schedule(() -> connect(), 5, TimeUnit.SECONDS);
    }
 
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }
}
6. 启动 Spring Boot 应用

在 Spring Boot 的主类中启动 Netty 服务器和客户端。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
 
import javax.annotation.PostConstruct;
 
@SpringBootApplication
public class NettySpringBootApplication {
 
    @Autowired
    private NettyServer nettyServer;
 
    @Autowired
    private NettyClient nettyClient;
 
    public static void main(String[] args) {
        SpringApplication.run(NettySpringBootApplication.class, args);
    }
 
    @PostConstruct
    public void startNetty() {
        new Thread(() -> {
            try {
                nettyServer.run();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();
 
        new Thread(() -> nettyClient.start()).start();
    }
}

关键点总结

依赖引入:确保引入了 Spring Boot 和 Netty 的必要依赖。

Netty 服务器配置:使用 ServerBootstrap 配置服务器端,包括心跳检测处理。

Netty 客户端配置:使用 Bootstrap 配置客户端,实现自动重连和心跳检测。

心跳处理器:在服务器端和客户端分别实现心跳检测处理器,处理心跳包和连接超时。

Spring Boot 集成:在 Spring Boot 应用启动时启动 Netty 服务器和客户端。


相关文章
|
4天前
|
存储 监控 数据可视化
SaaS云计算技术的智慧工地源码,基于Java+Spring Cloud框架开发
智慧工地源码基于微服务+Java+Spring Cloud +UniApp +MySql架构,利用传感器、监控摄像头、AI、大数据等技术,实现施工现场的实时监测、数据分析与智能决策。平台涵盖人员、车辆、视频监控、施工质量、设备、环境和能耗管理七大维度,提供可视化管理、智能化报警、移动智能办公及分布计算存储等功能,全面提升工地的安全性、效率和质量。
|
10天前
|
存储 人工智能 开发框架
Spring AI Alibaba 应用框架挑战赛圆满落幕,恭喜获奖选手
Spring AI Alibaba 应用框架挑战赛圆满落幕,恭喜获奖选手
|
12天前
|
存储 人工智能 开发框架
Spring AI Alibaba 应用框架挑战赛圆满落幕,恭喜获奖选手
第二届开放原子大赛 Spring AI Alibaba 应用框架挑战赛决赛于 2 月 23 日在北京圆满落幕。
|
21天前
|
前端开发 Java 数据库连接
Spring框架初识
Spring 是一个分层的轻量级开源框架,核心功能包括控制反转(IOC)和面向切面编程(AOP)。主要模块有核心容器、Spring 上下文、AOP、DAO、ORM、Web 模块和 MVC 框架。它通过 IOC 将配置与代码分离,简化开发;AOP 提供了声明性事务管理等增强功能。
73 21
Spring框架初识
|
1月前
|
XML Java 开发者
通过springboot框架创建对象(一)
在Spring Boot中,对象创建依赖于Spring框架的核心特性——控制反转(IoC)和依赖注入(DI)。IoC将对象的创建和管理交由Spring应用上下文负责,开发者只需定义依赖关系。DI通过构造函数、setter方法或字段注入实现依赖对象的传递。Spring Boot的自动配置机制基于类路径和配置文件,自动为应用程序配置Spring容器,简化开发过程。Bean的生命周期包括定义扫描、实例化、依赖注入、初始化和销毁回调,均由Spring容器管理。这些特性提高了开发效率并简化了代码维护。
|
2月前
|
SQL Java 数据库连接
对Spring、SpringMVC、MyBatis框架的介绍与解释
Spring 框架提供了全面的基础设施支持,Spring MVC 专注于 Web 层的开发,而 MyBatis 则是一个高效的持久层框架。这三个框架结合使用,可以显著提升 Java 企业级应用的开发效率和质量。通过理解它们的核心特性和使用方法,开发者可以更好地构建和维护复杂的应用程序。
136 29
|
2月前
|
开发框架 运维 监控
Spring Boot中的日志框架选择
在Spring Boot开发中,日志管理至关重要。常见的日志框架有Logback、Log4j2、Java Util Logging和Slf4j。选择合适的日志框架需考虑性能、灵活性、社区支持及集成配置。本文以Logback为例,演示了如何记录不同级别的日志消息,并强调合理配置日志框架对提升系统可靠性和开发效率的重要性。
|
3月前
|
Java 开发者 Spring
理解和解决Spring框架中的事务自调用问题
事务自调用问题是由于 Spring AOP 代理机制引起的,当方法在同一个类内部自调用时,事务注解将失效。通过使用代理对象调用、将事务逻辑分离到不同类中或使用 AspectJ 模式,可以有效解决这一问题。理解和解决这一问题,对于保证 Spring 应用中的事务管理正确性至关重要。掌握这些技巧,可以提高开发效率和代码的健壮性。
162 13
|
3月前
|
设计模式 XML Java
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
本文详细介绍了Spring框架的核心功能,并通过手写自定义Spring框架的方式,深入理解了Spring的IOC(控制反转)和DI(依赖注入)功能,并且学会实际运用设计模式到真实开发中。
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
|
3月前
|
IDE Java 测试技术
互联网应用主流框架整合之Spring Boot开发
通过本文的介绍,我们详细探讨了Spring Boot开发的核心概念和实践方法,包括项目结构、数据访问层、服务层、控制层、配置管理、单元测试以及部署与运行。Spring Boot通过简化配置和强大的生态系统,使得互联网应用的开发更加高效和可靠。希望本文能够帮助开发者快速掌握Spring Boot,并在实际项目中灵活应用。
89 5