当前位置:首页 > 服务端 > Netty与Spring WebSocket

Netty与Spring WebSocket

2022年11月06日 17:57:11服务端10

刚开始的时候,我尝试着用netty实现了websocket服务端的搭建。在netty里面,并没有websocket session这样的概念,与其类似的是channel,每一个客户端连接都代表一个channel。前端的ws请求通过netty监听的端口,走websocket协议进行ws握手连接之后,通过一些列的handler(责链模式)进行消息处理。与websocket session类似地,服务端在连接建立后有一个channel,我们可以通过channel进行与客户端的通信

  /**
    * TODO 根据服务器传进来的id,分配到不同的group
    */
   private static final ChannelGroup GROUP = new DefaultChannelGroup(ImmediateEventExecutor.INSTANCE);

   @Override
   protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
       //retain增加引用计数,防止接下来的调用引用失效
       System.out.println("服务器接收到来自 " + ctx.channel().id() + " 的消息: " + msg.text());
       //将消息发送给group里面的所有channel,也就是发送消息给客户端
       GROUP.writeAndFlush(msg.retain());
   }

那么,服务端用netty还是用spring websocket?以下我将从几个方面列举这两种实现方式的优缺点

使用netty实现websocket

玩过netty的人都知道netty是的线程模型是nio模型,并发量非常高,spring5之前的网络线程模型是servlet实现的,而servlet不是nio模型,所以在spring5之后,spring的底层网络实现采用了netty。如果我们单独使用netty来开发websocket服务端,速度快是绝对的,但是可能会遇到下列问题:
1.与系统的其他应用集成不方便,在rpc调用的时候,无法享受springcloud里feign服务调用的便利性
2.业务逻辑可能要重复实现
3.使用netty可能需要重复造轮子
4.怎么连接上服务注册中心,也是一件麻烦的事情
5.restful服务与ws服务需要分开实现,如果在netty上实现restful服务,有多麻烦可想而知,用spring一站式restful开发相信很多人都习惯了。

使用spring websocket实现ws服务

spring websocket已经被springboot很好地集成了,所以在springboot上开发ws服务非常方便,做法非常简单
第一步:添加依赖

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

第二步:添加配置类

@Configuration
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
    registry.addHandler(myHandler(), "/")
        .setAllowedOrigins("*");
}

@Bean
 public WebSocketHandler myHandler() {
     return new MessageHandler();
 }
}

第三步:实现消息监听类

@Component
@SuppressWarnings("unchecked")
public class MessageHandler extends TextWebSocketHandler {
   private List<WebSocketSession> clients = new ArrayList<>();

   @Override
   public void afterConnectionEstablished(WebSocketSession session) {
       clients.add(session);
       System.out.println("uri :" + session.getUri());
       System.out.println("连接建立: " + session.getId());
       System.out.println("current seesion: " + clients.size());
   }

   @Override
   public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
       clients.remove(session);
       System.out.println("断开连接: " + session.getId());
   }

   @Override
   protected void handleTextMessage(WebSocketSession session, TextMessage message) {
       String payload = message.getPayload();
       Map<String, String> map = JSONObject.parseObject(payload, HashMap.class);
       System.out.println("接受到的数据" + map);
       clients.forEach(s -> {
           try {
               System.out.println("发送消息给: " + session.getId());
               s.sendMessage(new TextMessage("服务器返回收到的信息," + payload));
           } catch (Exception e) {
               e.printStackTrace();
           }
       });
   }
}

从这个demo中,使用spring websocket实现ws服务的便利性大家可想而知了。为了能更好地向spring cloud大家族看齐,我最终采用了spring websocket实现ws服务。
因此我的应用服务架构是这样子的:一个应用既负责restful服务,也负责ws服务。没有将ws服务模块拆分是因为拆分出去要使用feign来进行服务调用。第一本人比较懒惰,第二拆分与不拆分相差在多了一层服务间的io调用,所以就没有这么做了。

作者:Leon_Jinhai_Sun
来源链接:https://blog.csdn.net/Leon_Jinhai_Sun/article/details/118444863

版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。


本文链接:https://www.javaclub.cn/server/68182.html

标签: NettySpring
分享给朋友:

“Netty与Spring WebSocket” 的相关文章

SpringBoot整合Dubbo与zookeeper纯注解版

SpringBoot整合Dubbo与zookeeper纯注解版

一、Dubbo和zk的作用 上回讲到,Dubbo作为一款优秀的RPC框架,封装了dubbo-provider(提供者)和dubbo-consumer(消费者),而provider和consumer之间需要通过注册中心来作为可发现的服务目录。而zookeeper(此处简称zk)提供了服务接口注...

深入浅出 spring-data-elasticsearch

『  风云说:能分享自己职位的知识的领导是个好领导。 』 运行环境 :JDK 7 或 8,Maven 3.0+ 技术栈 :SpringBoot 1.5+, Spring Data Elasticsearch 1.5+ ,Elast...

项目ITP(四) javaweb http json 交互 in action (服务端 spring 手机端 提供各种工具类)勿喷!

项目ITP(四) javaweb http json 交互 in action (服务端 spring 手机端 提供各种工具类)勿喷!

前言   系列文章:[传送门]   洗了个澡,准备写篇博客。然后看书了。时间 3 7 分。我慢慢规律生活,向目标靠近。                       &n...

spring结合Mybatis的框架搭建(一)

spring结合Mybatis的框架搭建(一)

一:前沿   2015年新年上班的第二天,第一天就打了一天的酱油哦,只是下午开始搭建自己毕业设计的框架,搭建的是spring+spring mvc+MyBatis的框架。今天遇到了一个问题,结果弄了我一天时间,所以啊,路还是的一步步的走,弄过了才知道是怎么回事。现在记载下这个问题...

Sentinel Getting Started And Integration of Spring Cloud Alibaba Tutorials

原文链接:Sentinel Getting Started And Integration of Spring Cloud Alibaba Tutorials Sentinel Getting Started And Integration of...

spring常见错误:Error creating bean with name ‘xxx‘

spring常见错误:Error creating bean with name ‘xxx‘

 Error creating bean with name 'userController': Injection of autowired dependencies failed; nested exception is org.springframework.be...

springboot集成mongoDB遇到的一些坑

1.当mongoDB设置了账号密码时,且设置的db为admin(角色为root),此时登录且操作都是OK的,连接可视化工具进行各种操作也是ok的,但是springboot项目里面却是一直超时 原因:设置的账号密码是admin数据库的,然后连接的是自己的其他数据库(cloud...

日志配置(springboot、mybatis、Lombok)

日志配置(springboot、mybatis、Lombok)

Spring Boot在所有内部日志中使用Commons Logging,但是默认配置也提供了对常用日志的支持,如:Java Util Logging,Log4J, Log4J2和Logback。每种Logger都可以通过配置使用控制台或者文件输出日志内容   S...

Spring项目改成SpringBoot项目

Spring项目改成SpringBoot项目

最近到公司实习,被安排了一个活是将一个spring的html5项目改成springboot项目做二次开发,orm用的mybatis,页面Jsp。由于对项目的不熟悉导致产生了很多bug,最后在学长的帮助下终于完成了任务,简单介绍一下我的修改过程。 一...

SpringBoot整合Mqtt

序言        Mqtt就是个Jms的服务协议(我的偏见)。订阅发布,服务器可以使用Emq,官方网址是https://www.emqx.io/ (实在不想在搭建Emq服务器了太求没意思了。故此通过springb...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。