springboot整合netty的正确姿势

这篇具有很好参考价值的文章主要介绍了springboot整合netty的正确姿势。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

近期做一些物联网方面项目,使用到了tcp协议,之前公司做过socket短连接,网上找了一个简单的demo,很早便学习到nio方面知识,学习了《netty从入门到精通》这本书,同时也根据网上视频做了几个demo,但学习不太深入,刚好物联网项目,就直接使用netty,前期直接使用这个框架,但作为近十年开发的java程序员,没有spring感觉总少了很多不便,后期改框架时想到了使用springboot整合netty代码。

先说之前项目中做socket代码怎么用spring管理的:利用springboot启动后启动socket服务,是没有被spring管理的

public class CouponApplication {

    public static void main(String[] args) {
        log.info("当前版本为:couponmisserver-0.0.5-SNAPSHOT");
        log.info("版本日期:2020-1-7");
        ApplicationContext context = SpringApplication.run(CouponApplication.class, args);
        //启动stock服务
        Integer port = Integer.valueOf(Config.getConfig().get("socketPort"));
        SocketServer socketServer = new SocketServer();
        socketServer.init(port, context);
    }

}

网上一大神推荐的一个使用`CommandLineRunner `来加一个线程启动netty

/**
 * author: hejz
 * data:  2022-5-9
 */
@SpringBootApplication
@Slf4j
@EnableScheduling
public class Application implements CommandLineRunner {
    @Autowired
    private NettyServer nettyServer;

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        nettyServer.serverRun();
    }

}

我目前也是这样做的,这样netty就被整合到springboot中去了,但是近期chatGPT非常火,晚上无聊时我也拿它来玩时问到它这个问题,看这个大神怎么回答的:

Spring Boot 中可以通过创建自定义的 NettyServerNettyClient 类,并在其中实现 Netty 的服务端或客户端代码,然后在 Spring Boot 的应用程序中将其作为一个 Bean 注入到 Spring 容器中。以下是一个简单的示例代码,演示了如何整合 Netty 到 Spring Boot 应用程序中。

首先,创建一个自定义的 NettyServer 类,用于实现 Netty 的服务端代码:

@Component
public class NettyServer {

    @Value("${netty.server.port}")
    private int port;

    @PostConstruct
    public void start() throws InterruptedException {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();
                            pipeline.addLast(new StringDecoder());
                            pipeline.addLast(new StringEncoder());
                            pipeline.addLast(new NettyServerHandler());
                        }
                    });

            ChannelFuture channelFuture = serverBootstrap.bind(port).sync();
            channelFuture.channel().closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

}

之前网上那个大神给我的建议,我在操作过程中junit测试时总要先把启动netty那个给注释掉,无疑chatGPT大神给我找到了另一种解决方案,而且比我用的要好的多,我直接使用其给的方案重新优化了代码。

一、启动类不要动,还是原来的springboot启动类,在 NettyServer上使用@Component注解让spring扫瞄管理,使用@PostConstruct注解直接运行netty服务

@Component
@Slf4j
public class NettyServer {
    @Autowired
    private NettyServerInitializer nettyServerInitializer;
    @Value("${nettyPort}")
    private Integer nettyPort;
    @PostConstruct
    public void serverRun() {
        //循环组接收连接,不进行处理,转交给下面的线程组
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        //循环组处理连接,获取参数,进行工作处理
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            //服务端进行启动类
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            //使用NIO模式,初始化器等等
            serverBootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).childHandler(nettyServerInitializer);
            //绑定端口
            ChannelFuture channelFuture = serverBootstrap.bind(nettyPort).sync();
            log.info("tcp服务器已经启动…………");
            channelFuture.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}

二、添加NettyServerInitializer类加上@Component注解让spring扫瞄管理,使用@Autowired进行依赖注入管理

@Component
public class NettyServerInitializer extends ChannelInitializer<SocketChannel> {
    Logger log = LogManager.getLogger(NettyServerInitializer.class);
    @Autowired
    private NettyHandler nettyHandler;

    //连接注册,创建成功,会被调用
    @Override
    protected void initChannel(SocketChannel ch) throws Exception {
        log.info("==================netty报告==================");
        log.info("信息:有一客户端链接到本服务端");
        log.info("IP:{}", ch.remoteAddress().getAddress());
        log.info("Port:{}", ch.remoteAddress().getPort());
        log.info("通道id:{}", ch.id().toString());
        log.info("==================netty报告完毕==================");
        ChannelPipeline pipeline = ch.pipeline();
        //定义读写空闲时间——(单位秒)
        pipeline.addLast(new IdleStateHandler(180, 60,180));
        //注册拦截器
        pipeline.addLast(nettyHandler);
    }
}

三、其它NettyServerHandler类加上@Component注解让spring扫瞄管理,使用@Autowired进行依赖注入管理,但注意需要添加@ChannelHandler.Sharable注解,防止程序报错

/**
 * @author:hejz 75412985@qq.com
 * @create: 2023-01-24 22:51
 * @Description: 注册拦截器——每个设备都需要注册
 */
@Component
@ChannelHandler.Sharable
@Slf4j
public class NettyHandler extends SimpleChannelInboundHandler<ByteBuf> {
    @Autowired
    private DtuRegister dtuRegister;   

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
       //读到的客户端信息的逻辑处理(略)
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.getCause();
        NettyServiceCommon.deleteKey(ctx.channel());
        ctx.channel().close();
    }
}

至此,springboot整合netty完美解决,这才是便于理解和操作的方式,感谢网上使用监听器启动netty服务的那位大神,也感谢chatGPT大神给我提供另一种好的思路和方法文章来源地址https://www.toymoban.com/news/detail-448387.html

到了这里,关于springboot整合netty的正确姿势的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Springboot整合Netty,自定义协议实现

    新建springboot项目,并在项目以来中导入netty包,用fastjson包处理jsonStr。 创建netty相关配置信息文件 yml配置文件—— application.yml netty配置实体类—— NettyProperties 与yml配置文件绑定 通过 @ConfigurationProperties(prefix = \\\"netty\\\") 注解读取配置文件中的netty配置,通过反射注入值,需要在

    2024年02月06日
    浏览(40)
  • SpringBoot整合Netty+Websocket实现消息推送

           Netty是一个高性能、异步事件驱动的网络应用框架,用于快速开发可维护的高性能协议服务器和客户端。以下是Netty的主要优势: 高性能 :Netty基于NIO(非阻塞IO)模型,采用事件驱动的设计,具有高性能的特点。它通过零拷贝技术、内存池化技术等手段,进一步提高

    2024年01月20日
    浏览(45)
  • Springboot整合Netty实现RPC服务器

    try { ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.group(boss, worker) .childHandler(new ChannelInitializer() { @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new IdleStateHandler(0, 0, 60)); pipeline.addLast(new JsonDecoder()); pipeline.addLast(new JsonEnco

    2024年04月09日
    浏览(43)
  • 日常记录-SpringBoot整合netty-socketio

    这次整合借鉴了以下博主的智慧 websocket和socketio的区别 socket.io.js最简版单页HTML测试工具 Netty-SocketIO多路复用 springboot学习(四十三) springboot使用netty-socketio实现消息推送 SpringBoot集成SocketIO socketio的核心依赖就只有这个 我在启动类里面定义了启动或者关闭SocketIOServer springboot整合

    2024年02月10日
    浏览(42)
  • netty学习(3):SpringBoot整合netty实现多个客户端与服务器通信

    创建一个SpringBoot工程,然后创建三个子模块 整体工程目录:一个server服务(netty服务器),两个client服务(netty客户端) pom文件引入netty依赖,springboot依赖 NettySpringBootApplication NettyServiceHandler SocketInitializer NettyServer NettyStartListener application.yml Client1 NettyClientHandler SocketInitializ

    2024年02月11日
    浏览(60)
  • Springboot中整合netty启动后,项目无法正常启动?

      1.现象描述 netty等一般放在程序启动后再启动,多以下面方式启动: 如果在 Order 后面还有其它模块被启动,那么其它模块就会被阻塞。 2.原因分析 主线程启动netty后,netty会将主线程阻塞。因此,需要采用异步方式或使用线程池来启动netty。 3.解决办法 添加异步注解@Async

    2024年02月13日
    浏览(36)
  • 【已解决】SpringBoot整合security账号密码正确却提示错误

    SpringSecurity的密码校验并不是直接使用原文进行比较,而是使用加密算法将密码进行加密(更准确地说应该进行Hash处理,此过程是不可逆的,无法解密),最后将用户提供的密码以同样的方式加密后与密文进行比较。对于我们来说,用户提供的密码属于隐私信息,直接明文存

    2024年02月11日
    浏览(49)
  • SpringBoot项目整合WebSocket+netty实现前后端双向通信(同时支持前端webSocket和socket协议哦)

    目录   前言 技术栈 功能展示 一、springboot项目添加netty依赖 二、netty服务端 三、netty客户端 四、测试 五、代码仓库地址   专属小彩蛋:前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站(前言 - 床长人工智能教程

    2024年02月12日
    浏览(50)
  • 【NO.1】近期在项目中遇到的一些实际问题

    发现还是写博客能让自己记录问题比较规律,开个博实时更新自己每天遇到的问题吧。 将地址设置为了淘宝镜像,但使用npm安装还是卡在这一步,或者一段时间后安装失败,最终使用cnpm安装处理好了,咱也不懂为啥,就这么处理吧。 查了下两者的区别:npm是node官方的包管理

    2024年02月04日
    浏览(58)
  • 符号化的正确姿势

    将 .ips crash report 文件拖放到 Xcode Window Devices and Simulators View Device Logs 中, 然后导出 .crash 符号化文件. 使用条件: crash report 对应的 Archive 包是在本机构建的 symbolicatecrash 是一个 exec (可执行文件), Xcode自带, iOS 15 之前的系统产生的 crash report, 可以直接被整个符号化, 文件路径可以

    2024年02月13日
    浏览(69)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包