Spring Boot 实现 WebSocket(注解方式)
本文介绍如何使用 Spring Boot 的注解方式实现一个简单的 WebSocket 服务,支持客户端与服务器之间进行实时通信。
1. 引入依赖
在 pom.xml 文件中添加 WebSocket 相关依赖。
<dependencies><!-- Spring Boot WebSocket 支持 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>
</dependencies>
2.创建 WebSocket 服务类
使用 @ServerEndpoint 注解定义 WebSocket 的处理逻辑。下面是一个简单的示例类,它处理客户端连接、消息接收和消息发送。
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;@Component
@ServerEndpoint("/ws")
public class WebSocketServer {// 用于存储所有的会话private static final CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<>();private Session session;// 连接建立成功调用的方法@OnOpenpublic void onOpen(Session session) {this.session = session;webSocketSet.add(this);System.out.println("新连接加入: " + session.getId());}// 连接关闭时调用的方法@OnClosepublic void onClose() {webSocketSet.remove(this);System.out.println("连接关闭: " + session.getId());}// 收到客户端消息时调用的方法@OnMessagepublic void onMessage(String message, Session session) {System.out.println("收到消息: " + message);broadcast("服务器: " + message); // 广播消息给所有客户端}// 发送消息给客户端private void sendMessage(String message) throws IOException {this.session.getBasicRemote().sendText(message);}// 广播消息给所有客户端private static void broadcast(String message) {for (WebSocketServer webSocket : webSocketSet) {try {webSocket.sendMessage(message);} catch (IOException e) {e.printStackTrace();}}}
}
3. WebSocket 配置类
在 Spring Boot 中,需要通过配置类注册 WebSocket 端点。
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;@Configuration
public class WebSocketConfig {// 自动注册使用 @ServerEndpoint 注解声明的 WebSocket 端点public ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}
}
4. 编写前端客户端代码
为了测试 WebSocket 服务,可以通过一个简单的 HTML 文件与 WebSocket 服务进行交互。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>WebSocket Test</title>
</head>
<body><h2>WebSocket 测试</h2><input id="messageInput" type="text" placeholder="输入消息"><button onclick="sendMessage()">发送</button><ul id="messages"></ul><script>let socket = new WebSocket("ws://localhost:8080/ws");socket.onmessage = function(event) {let messages = document.getElementById("messages");let messageItem = document.createElement("li");messageItem.textContent = event.data;messages.appendChild(messageItem);};function sendMessage() {let input = document.getElementById("messageInput");let message = input.value;socket.send(message);input.value = '';}</script>
</body>
</html>
5. 启动应用程序
完成以上步骤后,启动 Spring Boot 应用程序。WebSocket 服务将会运行在 ws://localhost:8080/ws,前端可以通过该地址与服务器进行实时通信。
6. 测试 WebSocket
启动应用程序后,打开前端 HTML 页面。
输入消息并点击发送按钮,服务器会收到消息并将其广播给所有连接的客户端。
在浏览器开发工具中也可以观察到 WebSocket 的实时消息交互。
相关文章:
Spring Boot 实现 WebSocket(注解方式)
本文介绍如何使用 Spring Boot 的注解方式实现一个简单的 WebSocket 服务,支持客户端与服务器之间进行实时通信。 1. 引入依赖 在 pom.xml 文件中添加 WebSocket 相关依赖。 <dependencies><!-- Spring Boot WebSocket 支持 --><dependency>&l…...
windows下Qt的安装方法
Qt Creator是个人非常喜欢的一款开发工具,喜欢用其来开发C和CPC平台项目,当然也可以用其来开发Android和Auto平台项目,但其现在采用离线安装,限于网络问题,安装速度非常慢。 现在介绍一种可以完成快速的安装方法。 下…...
嵌入式面试题 ARM常见面试题
一.ARM内核分为哪几类?他们之间有什么区别? ARM内核主要分为三类,Cortex-A,Cortex-R,Cortex-M三种,A代表Applications,向用户提供全方位解决方案,主要用于复制的应用场合,比如智能手机、移动计算平台,数字电视、机顶盒、打印机或服务器等。R代表Real-Time Embedded,…...
分布式调度器--Spring Task 的使用
目录 1、启动类(App.java)上加EnableScheduling注解: 开启基于注解的任务调度器 2、同步定时任务 3、多线程(异步)定时任务 3.1 配置线程池 3.2 开启异步支持 3.3 定义异步方法 4、Api说明 4.1 fixedDelay 4.…...
Java应用程序的测试覆盖率之设计与实现(四)-- jacoco-maven-plugin
一、什么是jacoco-maven-plugin jacoco源码jacoco文档 除了使用jacoco.cli.jar导出并生成覆盖率报告外,还可以使用jacoco-maven-plugin,它是maven集成了jacoco的一款插件。 在工程pom.xml里配置插件jacoco-maven-plugin。 <plugin><groupId&g…...
UI 提供的 progress-step 要怎么实现?
前言 这天突然收到了 UI 修改设计稿的消息通知:“xxx 已修改 xxx 项目并 了你,请及时查看变更内容”,一条、两条、三条 …,修改消息铺天盖地而来,然后就什么都看不到了(因为我选择开启消息免打扰…...
DBSwitch和Seatunel
一、DBSwitch 什么是DBSwitch?它主要用在什么场景? 通过步骤分析可以看到这个是通过配置数据源,采用一次性或定时方案,同步到数据仓库的指定表,并且指定映射关系的工具。有点类似于flinkcdc的增量同步。 参考: dbs…...
【日志】力扣刷题 -- 轮转数组
2024.10.06 【力扣刷题】 经典面试150—转轮数组—中等 189. 轮转数组 - 力扣(LeetCode) 第一次做,暴力循环 // 超出时间限制 void rotate(int* nums, int numsSize, int k) {for(int i 0; i < k; i){int right numsSize - 1;int temp…...
Java 项目 Dockerfile 示例:从基础镜像选择到环境变量配置的详细指南
Java 项目 Dockerfile 示例:从基础镜像选择到环境变量配置的详细指南 本文提供了一个 Java 项目的 Dockerfile 示例,展示了如何为 Java 应用创建高效的 Docker 镜像。Dockerfile 从 OpenJDK 8 的 Java 运行环境开始,配置了工作目录和 JVM 启…...
WebGL编程指南 - 高级变换与动画基础
学习使用一个矩阵变换库,该库封装了矩阵运算的数学细节。快速上手使用该矩阵库,对图形进行复合变换。在该矩阵库的帮助下,实现简单的动画效果。 矩阵变换库:cuon-matrix.js OpenGL中的函数: 书中 cuon-matrix.js 函数…...
银行客户贷款行为数据挖掘与分析
#1024程序员节 | 征文# 在新时代下,消费者的需求结构、内容与方式发生巨大改变,企业要想获取更多竞争优势,需要借助大数据技术持续创新。本文分析了传统商业银行面临的挑战,并基于knn、逻辑回归、人工神经网络三种算法࿰…...
制程质量管理方案设计
质量管理系统框架——QMS 涵盖产生产制造体系的全生命周期的质量管理过程 与SAP、WMS、MES、OA等业务系统进行集成,整合各业务系统中的质量信息 利用整合的全价值链质量信息,寻找质量改进点和质量创新点 系统功能模块管理 系统管理:用户管理…...
uniapp移动端优惠券! 附源码!!!!
本文为常见的移动端uniapp优惠券,共有6种优惠券样式(参考了常见的优惠券),文本内容仅为示例,您可在此基础上调整为你想要的文本 预览效果 通过模拟数据,实现点击使用优惠券让其变为灰色的效果(模…...
【分布式技术】中间件-zookeeper安装配置
文章目录 安装部署1. 安装ZooKeeper2. 配置ZooKeeper3. 启动ZooKeeper服务器4. 使用ZooKeeper命令行客户端5. 使用ZooKeeper的四个基本操作6. ZooKeeper集群模式7. 安全和权限8. 监控和日志 相关文献 安装部署 在Linux环境中操作ZooKeeper通常涉及以下几个方面: 1…...
高等数学 7.6高阶线性微分方程
文章目录 一、线性微分方程的解的结构*二、常数变易法 方程 d 2 y d x 2 P ( x ) d y d x Q ( x ) f ( x ) (1) \cfrac{\mathrm{d}^2 y}{\mathrm{d}x^2} P(x) \cfrac{\mathrm{d}y}{\mathrm{d}x} Q(x) f(x) \tag{1} dx2d2yP(x)dxdyQ(x)f(x)(1) 叫做二阶线性微分方程。…...
LSP的建立
MPLS需要为报文事先分配好标签,建立一条LSP,才能进行报文转发。LSP分为静态LSP和动态LSP两种。 静态LSP的建立 静态LSP是用户通过手工为各个转发等价类分配标签而建立的。由于静态LSP各节点上不能相互感知到整个LSP的情况,因此静态LSP是一个…...
huggingface的数据集下载(linux下clone)
1. 安装lfs sudo apt-get install git-lfs 或者 apt-get install git-lfs 2. git lfs install git lfs install 3. git clone dataset包 第2,3步骤的截图如下:...
Java使用dom4j生成kml(xml)文件遇到No such namespace prefix: xxx is in scope on:问题解决
介绍addAttribute和addNamepsace: addAttribute 方法 addAttribute 方法用于给XML元素添加属性。属性(Attributes)是元素的修饰符,提供了关于元素的额外信息,并且位于元素的开始标签中。属性通常用于指定元素的行为或样式&#…...
深入探讨Java中的LongAdder:使用技巧与避坑指南
文章目录 一、什么是LongAdder?二、LongAdder的简单使用示例代码: 三、LongAdder的工作原理四、LongAdder的常见使用场景五、使用LongAdder时的注意事项(避坑指南)1. 不要滥用LongAdder2. sum()方法与精度问题3. 避免过度使用rese…...
【本科毕业设计】基于单片机的智能家居防火防盗报警系统
基于单片机的智能家居防火防盗报警系统 相关资料链接下载摘要Abstract第1章 绪论1.1课题的背景1.2 研究的目的和意义 第2章 系统总体方案设计2.1 设计要求2.2 方案选择和论证2.2.1 单片机的选择2.2.2 显示方案的选择 第3章 系统硬件设计3.1 整体方案设计3.1.1 系统概述3.1.2 系…...
C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...
Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...
MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...
使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
