Java SpringBoot集成WebSocket

news2025/1/9 15:31:26

SpringBoot集成WebSocket

  • 引入依赖
  • WebSocket配置
    • 拦截器配置
    • 总体配置类
    • WebSocket服务类
  • 控制层测试
  • 测试
    • 使用在线连接工具(自行百度)
    • 连接地址:ws://IP+端口号/websocket
    • 测试
    • 发送消息测试
  • @公众号:一颗星宇宙

引入依赖

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

WebSocket配置

拦截器配置

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;

import java.util.Map;

/**
 * @author wuzhenyong
 * ClassName:WebSocketInterceptor.java
 * date:2023-07-04 13:58
 * Description: WebSocket拦截器配置
 */
@Component
@Slf4j
public class WebSocketInterceptor implements HandshakeInterceptor {
    /**
     * 在握手之前 可用于权限认证
     *
     * @param serverHttpRequest  服务器http请求
     * @param serverHttpResponse 服务器http响应
     * @param webSocketHandler   网络套接字处理程序
     * @param map                地图
     * @return boolean
     * @throws Exception 异常
     */
    @Override
    public boolean beforeHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Map<String, Object> map) throws Exception {
        log.info("握手之前");
        return true;
    }

    /**
     * 握手之后
     *
     * @param serverHttpRequest  服务器http请求
     * @param serverHttpResponse 服务器http响应
     * @param webSocketHandler   网络套接字处理程序
     * @param e                  e
     */
    @Override
    public void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Exception e) {
        log.info("握手之后");
    }
}

总体配置类

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

/**
 * @author wuzhenyong
 * ClassName:WebSocketConfig.java
 * date:2023-07-04 15:28
 * Description: WebSocket配置
 */
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
    /**
     * 拦截器容器注册
     *
     * @return {@link WebSocketInterceptor}
     */
    @Bean
    public WebSocketInterceptor getWebSocketInterceptor() {
        return new WebSocketInterceptor();
    }

    /**
     * WebSocket服务注册
     *
     * @return {@link WebSocketServer}
     */
    @Bean
    public WebSocketServer myServer() {
        return new WebSocketServer();
    }

    /**
     * 端点注册
     *
     * @return {@link ServerEndpointExporter}
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
    
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        // 此处定义webSocket的连接地址以及允许跨域
        registry.addHandler(myServer(), "/websocket").addInterceptors(getWebSocketInterceptor()).setAllowedOrigins("*");
        // 同上,同时开启了Sock JS的支持,目的为了支持IE8及以下浏览器
        registry.addHandler(myServer(), "/sockjs/websocket").addInterceptors(getWebSocketInterceptor()).setAllowedOrigins("*").withSockJS();
    }
}

WebSocket服务类

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

/**
 * @author wuzhenyong
 * ClassName:WebSocketServer.java
 * date:2023-07-04 15:46
 * Description: WebSocket服务
 */
@Component
@Slf4j
public class WebSocketServer implements WebSocketHandler {
    private static Set<WebSocketSession> webSocketSet = new HashSet<>();

    /**
     * 连接后回调
     *
     * @param session 会话
     * @throws Exception 异常
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        webSocketSet.add(session);
        log.info("有新连接加入.当前在线人数为:{}" , webSocketSet.size());
    }

    /**
     * 收到消息触发
     *
     * @param session 会话
     * @param message 消息
     * @throws Exception 异常
     */
    @Override
    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
        log.info("收到新的消息.内容:{}" ,message.getPayload().toString());
    }

    /**
     * 异常
     *
     * @param session   会话
     * @param throwable throwable
     * @throws Exception 异常
     */
    @Override
    public void handleTransportError(WebSocketSession session, Throwable throwable) throws Exception {
        webSocketSet.remove(session);
        log.info("websocket发生异常!" , throwable);
    }

    /**
     * 关闭连接
     *
     * @param session     socket会话
     * @param closeStatus 关闭状态
     * @throws Exception 异常
     */
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
        webSocketSet.remove(session);
        log.debug("webSocket关闭连接,状态:{},当前连接数:{}", closeStatus, webSocketSet.size());
    }

    /**
     * 是否支持消息分片
     *
     * @return boolean
     */
    @Override
    public boolean supportsPartialMessages() {
        return false;
    }

    /**
     * 发送消息
     *
     * @param message 消息
     * @throws IOException ioexception
     */
    public static void sendString(String message) throws IOException {
        for (WebSocketSession webSocket : webSocketSet) {
            if (webSocket.isOpen()) {
                webSocket.sendMessage(new TextMessage(message));

            }
        }
        log.debug("webSocket发送消息内容:{},当前连接数:{}", message, webSocketSet.size());
    }
}

控制层测试

import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author wuzhenyong
 * ClassName:WebSocketController.java
 * date:2023-07-04 15:54
 * Description: WebSocket发送消息测试
 */
@RestController
@RequestMapping("/ws")
public class WebSocketController {
    @ApiOperation(value = "发送webSocket消息")
    @PostMapping("/sendMsg")
    public String sendWebSocketMessage(@RequestParam("msg") String msg) {
        // 发送webSocket消息
        WebSocketServer.sendString(msg);
        return "发送成功";
    }

}

测试

使用在线连接工具(自行百度)

连接地址:ws://IP+端口号/websocket

测试

在这里插入图片描述
在这里插入图片描述

发送消息测试

在这里插入图片描述

@公众号:一颗星宇宙

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/717404.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

液晶铝薄膜的干蚀特性

引言 对于先进的薄膜晶体管液晶显示器(TFT-LCD)制造工艺来说&#xff0c;薄膜层已逐渐取代传统的湿法蚀刻工艺。对于栅电极&#xff0c;一般使用铝(Al)&#xff0c;在Al中加入一些金属&#xff0c;除了可以保持低电阻率和增强Al薄膜的耐腐蚀性外&#xff0c;还可以防止在后退火…

these parameters are deprecated, see docs for addKeyword

在使用json schema中的自定义关键字时发生该报错&#xff0c;因为直接第一个参数直接传keyname&#xff0c;如下 但是这种方法已经弃用&#xff0c;应该用官方支持的写法&#xff0c;不要直接传keyword,以键值对形式写出来&#xff0c;也有可能是其他书写不规范造成的问题&am…

嵌入式系统移植

一、系统分层 移植的目的 不同架构的处理器指令集不兼容&#xff0c;即便是相同的处理器架构&#xff0c;板卡不同驱动代码也不兼容 Linux是一个通用的内核并不是为某一个特定的处理器架构或板卡设计的&#xff0c;所以从官方获取Linux源码后我们要先经过相应的配置使其与我们当…

企业src-白帽赚钱的合理途径

0、什么是src 安全响应中心&#xff08;Security Response Center&#xff09;&#xff1a;SRC通常是一个组织或者公司设立的部门或团队&#xff0c;负责接收、跟踪和响应安全漏洞报告&#xff0c;以及协调修补措施。SRC与安全研究人员和其他报告者合作&#xff0c;以确保及时…

FastDFS【FastDFS概述(简介、核心概念 、上传机制 、下载机制)】(一)-全面详解(学习总结---从入门到深化)

目录 为什么要使用分布式文件系统 FastDFS概述_简介 FastDFS概述_核心概念 FastDFS概述_上传机制 FastDFS概述_下载机制 为什么要使用分布式文件系统 单机时代 初创时期由于时间紧迫&#xff0c;在各种资源有限的情况下&#xff0c;通常就直接在 项目目录下建立静态文件夹…

CentOs7 阿里云如何做云盘扩容?

不罗嗦直接说主题&#xff1a; 在开发中遇到得问题&#xff1a;磁盘满了&#xff0c;删又不知道从何下手&#xff0c;万一删错了那就是巨大得灾难&#xff0c;所以我们就需要磁盘扩容&#xff0c;当然磁盘为什么满&#xff1f;怎么排查以后再说&#xff0c;这里主要是说磁盘如…

Windows PCL GPU版本编译过程

网上教程很少&#xff0c;但是想用PCL GPU功能&#xff0c;于是决定自己踩坑&#xff0c;我有几个不同的环境组合&#xff1a; (1)win10cuda10.0vs2019PCL1.11.1cmake3.18.5&#xff08;失败&#xff09; (2)win10cuda11.2vs2019PCL1.11.1cmake3.18.5&#xff08;成功&#x…

【算法|动态规划系列No.5】leetcode62. 不同路径

个人主页&#xff1a;平行线也会相交 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 平行线也会相交 原创 收录于专栏【手撕算法系列专栏】【LeetCode】 &#x1f354;本专栏旨在提高自己算法能力的同时&#xff0c;记录一下自己的学习过程&#xff0c;希望…

No7.精选前端面试题,享受每天的挑战和学习

文章目录 详细说明下 Composition Api 与 Vue 2.x使用的Options Api详细说明下Proxy和Object.defineProperty详细说明下Loader和Plugin分析下vue2.0和vue3.0的原理vue3和react的异同点 详细说明下 Composition Api 与 Vue 2.x使用的Options Api Composition API 是 Vue 3 中引…

弱网测试(Charles模拟)

一、介绍 移动应用的网络环境多样&#xff0c;而且会出现在不同网络之间切换的场景&#xff0c;即使是在同一网络环境下&#xff0c;也会出现网络连接状态时好时坏的情况&#xff0c;比如时高时低的延迟、经常丢包、频繁断线&#xff0c;在乘坐地铁、穿越隧道&#xff0c;和地…

今日大模型日报

XPhoneBERT&#xff5c;文本到语音转换的音素表示的预训练多语言模型 XPhoneBERT: A Pre-trained Multilingual Model for Phoneme Representations for Text-to-Speech Linh The Nguyen, Thinh Pham, Dat Quoc Nguyen Github地址&#xff1a;https://github.com/VinAIResearch…

IO流~~

就是用来读写数据 2&#xff1a;IO流的分类 3&#xff1a;字节流的使用 1&#xff1a;文件字节输入流&#xff1a;每次读取一个字节 作用&#xff1a;以内存为基准&#xff0c;把磁盘文件中的数据以字节的形式读取到内存中去 性能慢读取中文字符输出无法避免乱码问题 2&…

数字化升级提效85%,箭牌不止家居智能

近年来&#xff0c;随着人们对生活品质的追求不断提升&#xff0c;家居行业也逐渐朝着更加智能化、个性化、环保可持续和互联网的方向发展。有数据显示&#xff0c;2023年中国家居市场规模将达到2万亿元人民币&#xff0c;年复合增长率为8.3%。激烈的市场竞争之下&#xff0c;可…

操作系统——第一章概论(下)

提示&#xff1a;冠盖满京华&#xff0c;斯人独憔悴 文章目录 声明1.3.1 操作系统的运行机制1.3.2 中断和异常1.3.3 系统调用1.4.1 操作系统体系结构1.4.2 操作系统体系1.5 操作系统引导1.6 虚拟机 声明 本文章内容是根据王道教材以及王道的视频课所写&#xff0c;写的目的方…

Java中操作文件(一)

目录 一、引入 二、File概述 2.1、属性 2.2、构造方法 2.3、方法 2.4、代码示例 示例1 示例2 示例3 示例4 示例5 示例6 示例7 示例8 一、引入 文件是操作系统中的重要概念&#xff0c;Java作为一个跨平台语言&#xff0c;可以针对不同的操作系统处理文件。…

83、基于STM32单片机录音机录音笔语音存储回放TF卡TFT屏系统设计(程序+原理图+PCB源文件+参考论文+硬件设计资料+元器件清单等)

单片机主芯片选择方案 方案一&#xff1a;AT89C51是美国ATMEL公司生产的低电压&#xff0c;高性能CMOS型8位单片机&#xff0c;器件采用ATMEL公司的高密度、非易失性存储技术生产&#xff0c;兼容标准MCS-51指令系统&#xff0c;片内置通用8位中央处理器(CPU)和Flash存储单元&a…

Springboot 接口对接文件及对象

两个sprongboot项目实现文件对接&#xff0c;在传入文件同时传递其他对象信息&#xff0c;比如接口如下 一、创建文件 例如在D盘下创建1.txt&#xff0c;里边写入内容 2、传送方代码实现 import org.springframework.core.io.FileSystemResource; import org.springframework.…

保护您的密码安全:ADSelfService Plus防止密码被盗

在数字时代&#xff0c;密码的安全性至关重要。随着黑客攻击的不断增加&#xff0c;我们必须采取必要的措施来保护我们的密码免受盗窃和滥用。在这篇文章中&#xff0c;我们将介绍ADSelfService Plus&#xff0c;这是一种强大的密码管理和自助服务解决方案&#xff0c;可以帮助…

反向代理缓存服务器 Squid 、Nginx、CDN部署讲解

目录 一、Squid 反向代理1.1 概念1.2 工作机制1.3 搭建 二、 Nginx 反向代理缓存 一、Squid 反向代理 1.1 概念 如果 Squid 反向代理服务器中缓存了该请求的资源&#xff0c;则将该请求的资源直接返回给客户端&#xff1b;否则反向代理服务器将向后台的 Web 服务器请求资源&a…

三者ICG聚甲基菁染料:ICG COOH,ICG NHS,ICG NH2,具有良好的水溶性

一、ICG-COOH--CAS号&#xff1a;181934-09-8 ICG-COOH&#xff08;吲哚菁绿羧酸&#xff09;中末端羧酸在活化剂&#xff08;如EDC或HATU&#xff09;存在下可与伯胺基反应&#xff0c;形成稳定的酰胺键。ICG是一种带负电荷的聚甲基菁染料&#xff0c;具有良好的水溶性&#…