Springboot整合WebSocket

Springboot整合WebSocket

本文实现如何将WebSocket在SpringBoot中整合并且使用,SpringBoot中WebSocket组件已经非常完善,使用起来并不困难。

WebSocket使用方式有很多,这里主要展示常用的两种:

  1. 点对点式,通过userId进行消息的收发
  2. 订阅式,通过topic进行消息订阅、取消订阅、消息群发

本文源码:

  • Github源代码地址:https://github.com/xunfeng224/Springboot/tree/main/springboot-WebSocket
  • Gitee源代码地址:https://gitee.com/xfeng520/Springboot/tree/main/springboot-WebSocket

引入

WebSocket 是一种基于 TCP 协议的全双工通信协议,它允许客户端和服务器之间建立持久的、双向的通信连接。相比传统的 HTTP 请求 - 响应模式,WebSocket 提供了实时、低延迟的数据传输能力。通过 WebSocket,客户端和服务器可以在任意时间点互相发送消息,实现实时更新和即时通信的功能。WebSocket 协议经过了多个浏览器和服务器的支持,成为了现代 Web 应用中常用的通信协议之一。它广泛应用于聊天应用、实时数据更新、多人游戏等场景,为 Web 应用提供了更好的用户体验和更高效的数据传输方式。

项目结构

请添加图片描述

整合流程

添加依赖

pom.xml 中添加 spring-boot-starter-websocket 依赖。

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

创建WebSocket操作类

此类为WebSocket服务端端点,WebSocket功能实现及处理都在此类中完成。
注解@ServerEndpoint(“/websocket/{userId}”)中"/websocket/{userId}"为ws链接url,其中userId参数用于点对点式

该类方法虽然多,但是都很简单,主要原理为通过ConcurrentHashMap保存客户端连接信息,并使用Session对客户端进行消息发送

可分为三大部分:

  1. @OnMessage、@OnOpen、@OnClose、@OnError注解所修饰的方法,在端点处理客户端的连接、断开、消息等事件时会自动调用
  2. 点对点式WebSocker实现,流程为,在@OnOpen建立连接时获取到客户端id即userId,将userId对应的session存入Map,后续通过userId获取session进行消息发送,即可实现服务端对客户端通信
  3. 订阅式WebSocket实现,客户端需要发送一条SocketMessage进行Topic订阅,在SocketMessage.Header中消息类型messageType=“SUBSCRIBE”,订阅主题topic=“[指定的主题]”,在@OnMessage接受到此消息时,服务端将Topic与订阅该Topic的session集合存储起来,后续通过Topic获取session集合,向该Topic订阅者群发消息
package com.xunfeng.example.websocket;

import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * 服务端 WebSocket 端点
 * 接口路径 ws://localhost:8080/websocket/userId;
 * 注意:此处端口为SpringBoot服务端口,即server.port=8080
 */
@Component
@Slf4j
@ServerEndpoint("/websocket/{userId}")
public class WebSocket {
   


    /**
     * 与某个客户端的连接会话,需要通过它来给客户端发送数据
     */
    private Session session;

    /**
     * 订阅
     */
    public static final String SUBSCRIBE = "subscribe";

    /**
     * 取消订阅
     */
    public static final String UNSUBSCRIBE = "unsubscribe";

    /**
     * 订阅主题 ->会话id列表 以Topic订阅形式进行消息推送
     */
    public static ConcurrentHashMap<String, Set<Session>> topicSessionMap = new ConcurrentHashMap<>();


    /**
     * 用户ID
     */
    private String userId;

    /**
     * concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
     * 虽然@Component默认是单例模式的,但springboot还是会为每个websocket连接初始化一个bean,所以可以用一个静态set保存起来。
     * 注:底下WebSocket是当前类名
     */
    private static final CopyOnWriteArraySet<WebSocket> WEB_SOCKETS = new CopyOnWriteArraySet<>();

    /**
     * 用来存在线连接用户信息
     */
    private static final ConcurrentHashMap<String, Session> SESSION_POOL = new ConcurrentHashMap<String, Session>();

    /**
     * 链接成功调用的方法
     */
    @OnOpen
    public v
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值