【Spring源码】WebSocket做推送动作的底层实例是谁

简介: 我们都知道WebSocket可以主动推送消息给用户,那做推送动作的底层实例究竟是谁?我们先整体看下整个模块的组织机构。可以看到handleMessage方法定义了每个消息格式采用不同的消息处理方法,而这些方法该类并**没有实现**,而是留给了子类去实现。

一、前瞻

Ok,开始我们今天的对Spring的【模块阅读】。

在这里插入图片描述

那就挑Web里的WebSocket模块,先思考下本次阅读的阅读线索

  1. WebSocket在Spring里起到什么作用
  2. 这个模块采用了什么设计模式
  3. 我们都知道WebSocket可以主动推送消息给用户,那做推送动作的底层实例究竟是谁

二、探索

我们先整体看下整个模块的组织机构。

在这里插入图片描述

要解决阅读线索3,看起来应该从上图里的server模块开始。

找了一圈发现并没有什么线索,那我们就从阅读官方文档这个方向入手。

在这里插入图片描述

官方文档表面心跳采用了SckJS协议,所以我们应该从图2里的sockjs模块开始探索。

既然是发送消息给用户,那必定有send的动作,我们在sockjs模块全局搜索下。

在这里插入图片描述

我们根据搜索定位到了发送消息的WebSocketSession接口

    /**
     * Send a WebSocket message: either {@link TextMessage} or {@link BinaryMessage}.
     * <p><strong>Note:</strong> The underlying standard WebSocket session (JSR-356) does
     * not allow concurrent sending. Therefore, sending must be synchronized. To ensure
     * that, one option is to wrap the {@code WebSocketSession} with the
     * {@link org.springframework.web.socket.handler.ConcurrentWebSocketSessionDecorator
     * ConcurrentWebSocketSessionDecorator}.
     * @see org.springframework.web.socket.handler.ConcurrentWebSocketSessionDecorator
     */
    void sendMessage(WebSocketMessage<?> message) throws IOException;

整体看下该接口的类图,看下是哪些具体的子类对象实现了sendMessage接口。

在这里插入图片描述

我们找到了以上链条的sendMessage具体实现:

    @Override
    public final void sendMessage(WebSocketMessage<?> message) throws IOException {
   
   
        Assert.state(!isClosed(), "Cannot send a message when session is closed");
        Assert.isInstanceOf(TextMessage.class, message, "SockJS supports text messages only");
        sendMessageInternal(((TextMessage) message).getPayload());
    }

发现sockjs确实是像官方文档所说的,用户客户端发送心跳给服务器,服务器再使用以上的sendMessageInternal保存心跳。并不是我们要找的阅读线索3。

我们找下WebSocketSession接口的其他子类链条实现,发现真正发送消息给用户的应该是AbstractWebSocketSession

在这里插入图片描述

可以在代码里找到发送各种消息格式的实现。

到这我们就解决了阅读线索3:

推送动作的底层实例究竟是谁

而关于阅读线索2:WebSocket模块采用了什么设计模式,我们在AbstractWebSocketHandler发现了以下代码块。

public abstract class AbstractWebSocketHandler implements WebSocketHandler {
   
   

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
   
   
    }

    @Override
    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
   
   
        if (message instanceof TextMessage textMessage) {
   
   
            handleTextMessage(session, textMessage);
        }
        else if (message instanceof BinaryMessage binaryMessage) {
   
   
            handleBinaryMessage(session, binaryMessage);
        }
        else if (message instanceof PongMessage pongMessage) {
   
   
            handlePongMessage(session, pongMessage);
        }
        else {
   
   
            throw new IllegalStateException("Unexpected WebSocket message type: " + message);
        }
    }

    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
   
   
    }

    protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) throws Exception {
   
   
    }

    protected void handlePongMessage(WebSocketSession session, PongMessage message) throws Exception {
   
   
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
   
   
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
   
   
    }

    @Override
    public boolean supportsPartialMessages() {
   
   
        return false;
    }

}

可以看到handleMessage方法定义了每个消息格式采用不同的消息处理方法,而这些方法该类并没有实现,而是留给了子类去实现。

也就是说handleMessage方法定义了模板,而具体实现留给了不同子类。

这其实就是采用了模板方法模式

三、总结

而阅读线索1:WebSocket在Spring里起到什么作用,我们可以在官方文档里找到答案。

在这里插入图片描述

未完待续。。。

好了,今天的分享就到这👀。大家能否感受到通过按【模块阅读】这种方式来阅读源码的乐趣呢

创作不易,不妨点赞、收藏、关注支持一下,各位的支持就是我创作的最大动力❤️

相关文章
|
1月前
|
设计模式 Java 开发者
如何快速上手【Spring AOP】?从动态代理到源码剖析(下篇)
Spring AOP的实现本质上依赖于代理模式这一经典设计模式。代理模式通过引入代理对象作为目标对象的中间层,实现了对目标对象访问的控制与增强,其核心价值在于解耦核心业务逻辑与横切关注点。在框架设计中,这种模式广泛用于实现功能扩展(如远程调用、延迟加载)、行为拦截(如权限校验、异常处理)等场景,为系统提供了更高的灵活性和可维护性。
|
5月前
|
前端开发 Java 物联网
智慧班牌源码,采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署
智慧班牌系统是一款基于信息化与物联网技术的校园管理工具,集成电子屏显示、人脸识别及数据交互功能,实现班级信息展示、智能考勤与家校互通。系统采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署与私有化定制。核心功能涵盖信息发布、考勤管理、教务处理及数据分析,助力校园文化建设与教学优化。其综合性和可扩展性有效打破数据孤岛,提升交互体验并降低管理成本,适用于日常教学、考试管理和应急场景,为智慧校园建设提供全面解决方案。
382 70
|
10月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
263 2
|
11月前
|
开发框架 前端开发 网络协议
Spring Boot结合Netty和WebSocket,实现后台向前端实时推送信息
【10月更文挑战第18天】 在现代互联网应用中,实时通信变得越来越重要。WebSocket作为一种在单个TCP连接上进行全双工通信的协议,为客户端和服务器之间的实时数据传输提供了一种高效的解决方案。Netty作为一个高性能、事件驱动的NIO框架,它基于Java NIO实现了异步和事件驱动的网络应用程序。Spring Boot是一个基于Spring框架的微服务开发框架,它提供了许多开箱即用的功能和简化配置的机制。本文将详细介绍如何使用Spring Boot集成Netty和WebSocket,实现后台向前端推送信息的功能。
2604 1
|
6月前
|
Java 微服务 Spring
微服务——SpringBoot使用归纳——Spring Boot中使用拦截器——拦截器使用实例
本文主要讲解了Spring Boot中拦截器的使用实例,包括判断用户是否登录和取消特定拦截操作两大场景。通过token验证实现登录状态检查,未登录则拦截请求;定义自定义注解@UnInterception实现灵活取消拦截功能。最后总结了拦截器的创建、配置及对静态资源的影响,并提供两种配置方式供选择,帮助读者掌握拦截器的实际应用。
208 0
|
6月前
|
存储 监控 数据可视化
SaaS云计算技术的智慧工地源码,基于Java+Spring Cloud框架开发
智慧工地源码基于微服务+Java+Spring Cloud +UniApp +MySql架构,利用传感器、监控摄像头、AI、大数据等技术,实现施工现场的实时监测、数据分析与智能决策。平台涵盖人员、车辆、视频监控、施工质量、设备、环境和能耗管理七大维度,提供可视化管理、智能化报警、移动智能办公及分布计算存储等功能,全面提升工地的安全性、效率和质量。
118 0
|
8月前
|
监控 JavaScript 数据可视化
建筑施工一体化信息管理平台源码,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
智慧工地云平台是专为建筑施工领域打造的一体化信息管理平台,利用大数据、云计算、物联网等技术,实现施工区域各系统数据汇总与可视化管理。平台涵盖人员、设备、物料、环境等关键因素的实时监控与数据分析,提供远程指挥、决策支持等功能,提升工作效率,促进产业信息化发展。系统由PC端、APP移动端及项目、监管、数据屏三大平台组成,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
307 7
|
9月前
|
存储 缓存 Java
Spring面试必问:手写Spring IoC 循环依赖底层源码剖析
在Spring框架中,IoC(Inversion of Control,控制反转)是一个核心概念,它允许容器管理对象的生命周期和依赖关系。然而,在实际应用中,我们可能会遇到对象间的循环依赖问题。本文将深入探讨Spring如何解决IoC中的循环依赖问题,并通过手写源码的方式,让你对其底层原理有一个全新的认识。
204 2
|
10月前
|
前端开发 Java 开发者
Spring生态学习路径与源码深度探讨
【11月更文挑战第13天】Spring框架作为Java企业级开发中的核心框架,其丰富的生态系统和强大的功能吸引了无数开发者的关注。学习Spring生态不仅仅是掌握Spring Framework本身,更需要深入理解其周边组件和工具,以及源码的底层实现逻辑。本文将从Spring生态的学习路径入手,详细探讨如何系统地学习Spring,并深入解析各个重点的底层实现逻辑。
219 9