SpringBoot整合WebSocket【代码】

系列文章目录

一、SpringBoot连接MySQL数据库实例【tk.mybatis连接mysql数据库】

二、SpringBoot连接Redis与Redisson【代码】

三、SpringBoot整合WebSocket【代码】


文章目录


代码下载地址

SpringBoot整合WebSocket【代码】


一、效果演示

测试链接

二、引入依赖

xml 复制代码
<!--    websocket    -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-websocket</artifactId>
  <version>2.1.1.RELEASE</version>
</dependency>

三、WebSocketConfig

java 复制代码
@Configuration
public class WebSocketConfig {

    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}

四、SessionWrap

SessionWrap 可根据具体需求自定义

java 复制代码
@Data
public class SessionWrap {

    private String from;	// 连接Id

    private String type;	// 来凝结类型

    private Session session;

    private Date lastTime;
}

五、WebSocketServer

java 复制代码
@Slf4j
@Component
@ServerEndpoint(value = "/api/websocket/{from}/{type}")
public class WebSocketServer {

    @Autowired
    private MessageService messageService;

    public static WebSocketServer webSocketServer;

    // 所有的连接会话
    private static CopyOnWriteArraySet<SessionWrap> sessionList = new CopyOnWriteArraySet<>();

    private String from;
    private String type;

    @PostConstruct
    public void init() {
        webSocketServer = this;
        webSocketServer.messageService = this.messageService;
    }

    /**
     * @author Lee
     * @date 2023/7/18 13:57
     * @description 创建连接
     */
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "from") String from, @PathParam(value = "type") String type) {
        this.from = from;
        this.type = type;
        try {
            // 遍历list,如果有会话,更新,如果没有,创建一个新的
            for (SessionWrap item : sessionList) {
                if (item.getFrom().equals(from) && item.getType().equals(type)) {
                    item.setSession(session);
                    item.setLastTime(new Date());
                    log.info("【websocket消息】更新连接,总数为:" + sessionList.size());
                    return;
                }
            }
            SessionWrap sessionWrap = new SessionWrap();
            sessionWrap.setFrom(from);
            sessionWrap.setType(type);
            sessionWrap.setSession(session);
            sessionWrap.setLastTime(new Date());
            sessionList.add(sessionWrap);
            log.info("【websocket消息】有新的连接,总数为:" + sessionList.size());
        } catch (Exception e) {
            log.info("【websocket消息】连接失败!错误信息:" + e.getMessage());
        }
    }

    /**
     * @author Lee
     * @date 2023/7/18 13:57
     * @description 关闭连接
     */
    @OnClose
    public void onClose() {
        try {
            sessionList.removeIf(item -> item.getFrom().equals(from) && item.getType().equals(type));
            log.info("【websocket消息】连接断开,总数为:" + sessionList.size());
        } catch (Exception e) {
            log.info("【websocket消息】连接断开失败!错误信息:" + e.getMessage());
        }
    }

    /**
     * @author Lee
     * @date 2023/7/18 14:04
     * @description 发送消息
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        try {
        	// 对消息进行处理
            JSONObject r = webSocketServer.messageService.insertMessage(message);
            String userId = r.getString("userId");
            for (SessionWrap item : sessionList) {
            // 发送消息的判断逻辑可根据需求修改
                if (item.getFrom().equals(userId) && item.getType().equals("test")) {
                    item.getSession().getBasicRemote().sendText(r.toJSONString());
                    log.info("【websocket消息】发送消息成功:" + r.toJSONString());
                }
            }
        } catch (Exception e) {
            log.info("【websocket消息】发送消息失败!错误信息:" + e.getMessage());
        }
    }

    @OnError
    public void onError(Session session, Throwable error) {

        log.error("用户错误,原因:"+error.getMessage());
        error.printStackTrace();
    }

}
相关推荐
这里是杨杨吖2 小时前
SpringBoot+Vue心理健康咨询系统 附带详细运行指导视频
spring boot·vue·心理健康
遨游DATA2 小时前
Spring Boot 启动失败排查:如何区分多 Bean 冲突与清理阶段异常
java·spring boot·后端
IT_陈寒2 小时前
Java线程池这个坑我算是踩明白了
前端·人工智能·后端
掉头发的王富贵3 小时前
我来入职新公司两个月了,为什么只写了100行代码?
后端·ai编程
从零开始的代码生活_3 小时前
C++ 内存管理:从内存分区到 new/delete 底层原理
开发语言·c++·后端
雪碧聊技术3 小时前
Spring Boot项目如何彻底禁用Nacos(服务发现+配置中心),本地启动不再依赖Nacos
spring boot·nacos·服务发现
31535669133 小时前
Superpowers:GPT-5.6 时代下的流程毒瘤
前端·后端
神奇小汤圆5 小时前
2026 Java岗面试题库(已收录GitHub),覆盖所有考点
后端
ArixBit5 小时前
用 Go 手撸 Agent 框架 #4:工具定义与契约——让 Agent 学会调用多工具
后端
枕星而眠5 小时前
【数据结构】红黑树入门指南
运维·数据结构·c++·后端