Java21 + SpringBoot3集成WebSocket

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

前言

近日心血来潮想做一个开源项目,目标是做一款可以适配多端、功能完备的模板工程,包含后台管理系统和前台系统,开发者基于此项目进行裁剪和扩展来完成自己的功能开发。
本项目为前后端分离开发,后端基于Java21SpringBoot3开发,前端提供了vue、angular、react、uniapp、微信小程序等多种脚手架工程。
本文主要介绍项目中如何集成WebSocket实现服务器端与客户端的双向通信。

相关技术简介

什么是WebSocket

WebSocket 是一种网络通信协议。RFC6455 定义了它的通信标准。
http是一种无状态,无连接,单向的应用层协议,它采用了请求/响应模型,通信请求只能由客户端发起,服务端对请求做出应答处理。这样的弊端显然是很大的,只要服务端状态连续变化,客户端就必须实时响应,都是通过javascript与ajax进行轮询,这样显然是非常麻烦的,同时轮询的效率低,非常的浪费资源(http一直打开,一直重复的连接)。
于是就有了WebSocket,它是一种全面双工通讯的网络技术,任意一方都可以建立连接将数据推向另一方,WebSocket只需要建立一次连接,就可以一直保持。

WebSocket的原理

  1. WebSocket约定了一个通信的规范,通过一个握手的机制,客户端和服务器之间能建立一个类似tcp的连接,从而方便它们之间的通信
  2. 在WebSocket出现之前,web交互一般是基于http协议的短连接或者长连接
  3. WebSocket是一种全新的协议,不属于http无状态协议,协议名为"ws"

WebSocket与HTTP协议的关系

java21 + springboot3集成spring data jpa 偏安,websocket,Java,spring boot,vue.js

WebSocket优点

  1. 减少请求费时费资源:是真正的全双工方式,建立连接后,服务器与客户端时完全对等的,可以相互请求,减少了不必要的网络请求时间损耗和网络流量;
  2. 更持久:WebSocket协议通过第一个request建立TCP连接后,只要不主动关闭,就能一直保持连接状态交换数据;
  3. 服务端可以主动向客户端发送消息;

WebSocket应用场景

社交聊天、弹幕、多玩家游戏、协同编辑、股票基金实时报价、体育实况更新、视频会议/聊天、基于位置的应用、在线教育、智能家居等需要高实时的场景都可以使用WebSocket技术实现。

实现方式

本项目后端基于Java 21SpringBoot3开发,前端基于Vue3实现。

1. 添加maven依赖

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

2. 添加WebSocket配置类,定义ServerEndpointExporter Bean

@Configuration
@EnableWebSocket
public class WebSocketConfig {
    /**
     * 注入ServerEndpointExporter,
     * 这个bean会自动注册使用了@ServerEndpoint注解声明的WebSocket Endpoint
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}

3. 定义WebSocket Endpoint

/**
 * 消息提醒计数WebSocket
 */
@ServerEndpoint("/ws/test/{userId}")
@Component
@Slf4j
public class TestWebSocketServer {
    /**
     * 与某个客户端的连接会话,需要通过它来给客户端发送数据
     */
    private Session session;
    /**
     * 用户ID
     */
    private Long userId;
    /**
     * concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
     * 虽然@Component默认是单例模式的,但springboot还是会为每个websocket连接初始化一个bean,所以可以用一个静态set保存起来。
     */
    private static final CopyOnWriteArraySet<MessageCountWebSocketServer> webSockets = new CopyOnWriteArraySet<>();
    /**
     * 用来存在线连接用户信息
     */
    private static final ConcurrentHashMap<Long, Session> sessionPool = new ConcurrentHashMap<>();

    /**
     * 链接成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "userId") Long userId) {
        this.session = session;
        this.userId = userId;
        webSockets.add(this);
        sessionPool.put(userId, session);
        log.info("建立与UserID:{}的消息提醒计数连接", userId);
    }

    /**
     * 链接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        webSockets.remove(this);
        sessionPool.remove(this.userId);
        log.info("关闭与UserID:{}的消息提醒计数连接", userId);
    }

    /**
     * 收到客户端消息后调用的方法
     */
    @OnMessage
    public void onMessage(String message) {
        log.info("接收到UserID:{}的消息{}", userId, message);
    }

    /**
     * 发送错误时的处理
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("发送到UserID:{}的消息传输失败", userId, error);
    }

    /**
     * 广播消息
     *
     * @param message
     */
    public void sendAllMessage(String message) {
        for (MessageCountWebSocketServer socketServer : webSockets) {
            if (socketServer.session.isOpen()) {
                socketServer.session.getAsyncRemote().sendText(message);
            }
        }
    }

    /**
     * 单人单播消息
     *
     * @param userId
     * @param message
     */
    public void sendOneMessage(Long userId, String message) {
        Session session = sessionPool.get(userId);
        if (session != null && session.isOpen()) {
            session.getAsyncRemote().sendText(message);
        }
    }

    /**
     * 多人单播消息
     *
     * @param userIds
     * @param message
     */
    public void sendMoreMessage(Long[] userIds, String message) {
        for (Long userId : userIds) {
            Session session = sessionPool.get(userId);
            if (session != null && session.isOpen()) {
                session.getAsyncRemote().sendText(message);
            }
        }

    }
}

4. 前端创建WebSocket对象

以下代码基于Vue3的组合式API编写。

<script setup>
  import { onMounted, onBeforeMount } from 'vue';

  /**
   * @type {WebSocket}
   */
  let websocket = null;

  onMounted(async () => {
    initTestWebSocket();
  });

  onBeforeMount(async()=>{
    websocket && websocket.close();
  });

  const initTestWebSocket = async () => {
    const userId = '当前用户ID';
    console.log("尝试建立websockect连接");
    websocket = new WebSocket(`/ws/test/${userId}`);
    websocket.onopen = function (event) {
      console.log("建立连接");
    }
    websocket.onclose = function (event) {
      console.log('连接关闭')
      //尝试重连websocket
      reconnectMessageWebSocket();
    }
    //建立通信后,监听到后端的数据传递
    websocket.onmessage = function (event) {
      // 打印后端传来的数据
      console.log(event.data);
      // 调用WebSocket对象的send方法可向后端发送数据
      // websocket.send("test data");
    }
    websocket.onerror = function () {
      console.log("数据发送失败");
    }
    // 窗口关闭前关闭WebSocket连接
    window.onbeforeunload = function () {
      websocket.close();
    }
  };

  // 重连
  const reconnectMessageWebSocket = () => {
    console.log("正在重连");
    // 进行重连
    setTimeout(() => {
      initTestWebSocket();
    }, 1000);
  }
</script>

总结

本文介绍了WebSocket的相关概念,以及如何基于Java21、SpringBoot3和Vue3使用WebSocket,在使用过程中也遇到了一些问题。

  • 执行mvn packagemvn test命令时报错

    请参阅 Java21 + SpringBoot3使用spring-websocket时执行mvn package报错。

  • 如果后端使用Spring SecurityShiroSa-Token等技术,需要考虑使用@ServerEndpoint注解所配置url的权限控制问题。

我也会及时的更新后续实践中所遇到的问题,希望与诸位看官一起进步。
如有错误,还望批评指正。文章来源地址https://www.toymoban.com/news/detail-818206.html

到了这里,关于Java21 + SpringBoot3集成WebSocket的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • SpringBoot3集成Kafka

    目录 一、简介 二、环境搭建 1、Kafka部署 2、Kafka测试 3、可视化工具 三、工程搭建 1、工程结构 2、依赖管理 3、配置文件 四、基础用法 1、消息生产 2、消息消费 五、参考源码 标签:Kafka3.Kafka-eagle3; Kafka是一个开源的分布式事件流平台,常被用于高性能数据管道、流分析、

    2024年02月12日
    浏览(37)
  • SpringBoot3集成ElasticSearch

    目录 一、简介 二、环境搭建 1、下载安装包 2、服务启动 三、工程搭建 1、工程结构 2、依赖管理 3、配置文件 四、基础用法 1、实体类 2、初始化索引 3、仓储接口 4、查询语法 五、参考源码 标签:ElasticSearch8.Kibana8; Elasticsearch是一个分布式、RESTful风格的搜索和数据分析引擎

    2024年02月12日
    浏览(42)
  • SpringBoot3集成Redis

    目录 一、简介 二、工程搭建 1、工程结构 2、依赖管理 3、Redis配置 三、Redis用法 1、环境搭建 2、数据类型 3、加锁机制 四、Mybatis缓存 1、基础配置 2、自定义实现 五、参考源码 标签:Redis.Mybatis.Lock; 缓存在项目开发中,基本上是必选组件之一,Redis作为一个 key-value 存储系

    2024年02月13日
    浏览(40)
  • SpringBoot3集成Zookeeper

    标签:Zookeeper3.8 ,Curator5.5; ZooKeeper是一个集中的服务,用于维护配置信息、命名、提供分布式同步、提供组服务。分布式应用程序以某种形式使用所有这些类型的服务。 1、修改配置文件 2、服务启动 3、客户端测几个增删查的命令 Curator是一组Java库,它让ZooKeeper的使用变得

    2024年01月23日
    浏览(46)
  • SpringBoot3集成RocketMq

    标签:RocketMq5.Dashboard; RocketMQ因其架构简单、业务功能丰富、具备极强可扩展性等特点被广泛应用,比如金融业务、互联网、大数据、物联网等领域的业务场景; 在 rocketmq-starter 组件中,实际上依赖的是 rocketmq-client 组件的 5.0 版本,由于两个新版框架间的兼容问题,需要添

    2024年02月12日
    浏览(49)
  • SpringBoot3集成PostgreSQL

    标签:PostgreSQL.Druid.Mybatis.Plus; PostgreSQL是一个功能强大的开源数据库系统,具有可靠性、稳定性、数据一致性等特点,且可以运行在所有主流操作系统上,包括Linux、Unix、Windows等。 通过官方文档可以找到大量描述如何安装和使用PostgreSQL的信息。 环境搭建,基于 Centos7 部署

    2024年03月24日
    浏览(47)
  • SpringBoot3集成Quartz

    目录 一、简介 二、工程搭建 1、工程结构 2、依赖管理 3、数据库 4、配置文件 三、Quartz用法 1、初始化加载 2、新增任务 3、更新任务 4、暂停任务 5、恢复任务 6、执行一次 7、删除任务 8、任务执行 四、参考源码 标签:Quartz.Job.Scheduler; Quartz由Java编写的功能丰富的开源作业

    2024年02月13日
    浏览(43)
  • SpringBoot3数据库集成

    标签:Jdbc.Druid.Mybatis.Plus; 项目工程中,集成数据库实现对数据的增晒改查管理,是最基础的能力,而对于这个功能的实现,其组件选型也非常丰富; 通过如下几个组件来实现数据库的整合; Druid连接池 :阿里开源的数据库连接池,并且提供 SQL 执行的监控能力; MybatisPlu

    2024年02月13日
    浏览(44)
  • 【springboot3.x 记录】解决 springboot3 集成 mybatis-plus 报 sqlSession 异常

    2022-12-30,作者最新发布了 3.5.3.1 版本,不需要使用快照版本了 ========================= springboot3 已经发布正式版,第一时间尝鲜看看如何,但是在集成 mybatis-plus 最新版 3.5.2 的时候发现提示异常。 看来 springboot3 在注入这块做了调整,但目前 mybatis-plus 并没有适配到。 于是翻查

    2024年02月13日
    浏览(46)
  • Elasticsearch 搜索测试与集成Springboot3

    Elasticsearch是专门做 搜索 的,它非常擅长以下方面的问题 Elasticsearch对模糊搜索非常擅长(搜索速度很快) 从Elasticsearch搜索到的数据可以根据 评分 过滤掉大部分的,只要返回评分高的给用户就好了(原生就支持排序) 没有那么准确的也能搜出相关的结果(能匹配有相

    2024年01月22日
    浏览(46)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包