Java Web开发进阶——WebSocket与实时通信
WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议,广泛应用于需要实时数据交换的应用程序中。它能够实现服务器与客户端之间的双向通信,避免了传统 HTTP 请求/响应的延迟。结合 Spring Boot,开发实时通信应用变得更加高效与简便。
1. WebSocket的基本概念与应用
1.1 什么是WebSocket?
WebSocket 是一种协议,它允许客户端和服务器之间通过持久的连接进行实时双向通信。在传统的 HTTP 协议中,客户端发起请求,服务器响应请求,这种通信方式是单向的,且每次请求都需要重新建立连接。而 WebSocket 通过在客户端和服务器之间建立一个长连接,实现了数据的双向实时传输,极大地提高了应用的实时性和响应能力。
- 全双工通信:WebSocket 允许客户端和服务器同时发送数据,这与传统的请求-响应模型不同。
- 低延迟:由于建立了持久连接,数据传输的延迟非常低,适合实时应用。
- 节省带宽:WebSocket 可以避免每次请求都建立连接,减少了请求头和握手的开销。
1.2 WebSocket的应用场景
WebSocket 的实时通信特性使得它非常适合以下应用场景:
- 实时聊天应用:如在线客服、即时通讯。
- 在线游戏:多人在线互动游戏。
- 股票和金融应用:实时股票价格和市场数据更新。
- 协作应用:如多人协作编辑器、在线文档协作。
- 实时通知系统:推送通知和事件广播。
2. 使用Spring Boot实现WebSocket
2.1 引入Spring Boot WebSocket依赖
Spring Boot 提供了对 WebSocket 协议的原生支持,使用 spring-boot-starter-websocket 依赖即可实现 WebSocket 功能。在 pom.xml 中加入如下依赖:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2.2 配置WebSocket
Spring Boot 支持使用 @Configuration 注解的配置类来配置 WebSocket。通过实现 WebSocketConfigurer 接口并重写 registerWebSocketHandlers 方法,可以自定义 WebSocket 的配置。
例如:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {@Overridepublic void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {registry.addHandler(new ChatWebSocketHandler(), "/chat").setAllowedOrigins("*"); // 允许所有来源的跨域请求}
}
在此配置类中,addHandler 方法指定了 WebSocket 请求路径 /chat,并且配置了处理 WebSocket 消息的 ChatWebSocketHandler 类。
2.3 编写WebSocket处理器
WebSocketHandler 是处理 WebSocket 消息的核心类。在 Spring Boot 中,我们可以自定义一个 WebSocketHandler 来处理连接、消息、关闭等事件。
例如,ChatWebSocketHandler 可以实现以下功能:
- 处理连接建立:客户端连接成功时调用。
- 处理消息传递:接收到客户端消息时调用。
- 处理连接关闭:客户端断开连接时调用。
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketMessage;public class ChatWebSocketHandler extends TextWebSocketHandler {@Overridepublic void afterConnectionEstablished(WebSocketSession session) throws Exception {System.out.println("New WebSocket connection established: " + session.getId());session.sendMessage(new TextMessage("Welcome to the chat room!"));}@Overrideprotected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {String payload = message.getPayload();System.out.println("Received message: " + payload);// Echo the message back to the clientsession.sendMessage(new TextMessage("Echo: " + payload));}@Overridepublic void afterConnectionClosed(WebSocketSession session, org.springframework.web.socket.CloseStatus status) throws Exception {System.out.println("Connection closed: " + session.getId());}
}
在这个 ChatWebSocketHandler 类中,afterConnectionEstablished 用来在客户端连接后发送一条欢迎消息,handleTextMessage 用来处理客户端发送的消息,并回传相同的消息。
2.4 前端WebSocket客户端
在前端页面中,我们可以通过 JavaScript 的 WebSocket API 来连接 WebSocket 服务,并发送接收消息。例如:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>WebSocket Chat</title>
</head>
<body><h1>WebSocket Chat</h1><textarea id="chat" cols="30" rows="10" readonly></textarea><br/><input type="text" id="message" placeholder="Enter message"/><button onclick="sendMessage()">Send</button><script>var socket = new WebSocket("ws://localhost:8080/chat");socket.onopen = function () {console.log("Connected to WebSocket server.");};socket.onmessage = function (event) {document.getElementById("chat").value += "Server: " + event.data + "\n";};function sendMessage() {var message = document.getElementById("message").value;socket.send(message);document.getElementById("chat").value += "You: " + message + "\n";document.getElementById("message").value = "";}</script>
</body>
</html>
在此 HTML 页面中,使用 WebSocket API 建立连接,点击发送按钮时将文本框内容发送到服务器,服务器会回传相同的消息并在页面上显示。
3. 开发实时聊天应用示例
3.1 项目需求
我们的目标是构建一个实时聊天应用,用户可以通过 WebSocket 与其他用户进行即时对话。该应用包括以下功能:
- 用户连接到聊天服务器。
- 用户输入消息并发送。
- 服务器实时回传消息。
- 聊天记录在页面上展示。
3.2 后端实现
我们已经在前面的部分中实现了 ChatWebSocketHandler 和 WebSocket 配置。接下来,我们可以为聊天应用提供更多的功能,如支持多个用户之间的消息转发。
修改 ChatWebSocketHandler 以支持广播消息:
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketMessage;import java.util.HashSet;
import java.util.Set;public class ChatWebSocketHandler extends TextWebSocketHandler {private static final Set<WebSocketSession> sessions = new HashSet<>();@Overridepublic void afterConnectionEstablished(WebSocketSession session) throws Exception {sessions.add(session);session.sendMessage(new TextMessage("Welcome to the chat room!"));}@Overrideprotected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {String payload = message.getPayload();for (WebSocketSession s : sessions) {s.sendMessage(new TextMessage(payload));}}@Overridepublic void afterConnectionClosed(WebSocketSession session, org.springframework.web.socket.CloseStatus status) throws Exception {sessions.remove(session);}
}
这里,我们使用一个 Set 来存储所有连接的 WebSocket 客户端,每次收到消息时,都将消息广播给所有连接的客户端。
3.3 前端实现
前端界面与之前类似,但我们改进了显示聊天记录和输入框的样式。每当一个用户发送消息时,其他所有连接的用户都会看到相同的消息。
<textarea id="chat" cols="30" rows="10" readonly></textarea><br/>
<input type="text" id="message" placeholder="Enter message"/>
<button onclick="sendMessage()">Send</button>
总结
WebSocket 是一种非常适合实时通信的协议,特别是在构建即时通讯、在线协作、实时数据更新等应用时。在 Spring Boot 中实现 WebSocket 非常简单,我们只需要添加相关依赖,配置 WebSocket 处理器,然后在前端使用 WebSocket API 进行连接和消息传递。通过这个简单的示例,我们可以构建一个实时聊天应用,展示 WebSocket 在实时通信中的强大能力。
关于作者:
15年互联网开发、带过10-20人的团队,多次帮助公司从0到1完成项目开发,在TX等大厂都工作过。当下为退役状态,写此篇文章属个人爱好。本人开发期间收集了很多开发课程等资料,需要可联系我

相关文章:
Java Web开发进阶——WebSocket与实时通信
WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议,广泛应用于需要实时数据交换的应用程序中。它能够实现服务器与客户端之间的双向通信,避免了传统 HTTP 请求/响应的延迟。结合 Spring Boot,开发实时通信应用变得更加高效与简便。 1. …...
zerotier搭建虚拟局域网,自建planet
基于该开源项目 自建planet节点,更快速,更安全 本教程依据docker-zerotier-planet 项目文档书写,并以linux(centos 7)和windows作为示例,需要其他系统配置方法,可移步项目文档 一. 前置资源 具有外网ip的服务器 后面…...
SQL面试题1:连续登陆问题
引言 场景介绍: 许多互联网平台为了提高用户的参与度和忠诚度,会推出各种连续登录奖励机制。例如,游戏平台会给连续登录的玩家发放游戏道具、金币等奖励;学习类 APP 会为连续登录学习的用户提供积分,积分可兑换课程或…...
2Spark Core
2Spark Core 1.RDD 详解1) 为什么要有 RDD?2) RDD 是什么?3) RDD 主要属性 2.RDD-API1) RDD 的创建方式2) RDD 的算子分类3) Transformation 转换算子4) Action 动作算子 3. RDD 的持久化/缓存4. RDD 容错机制 Checkpoint5. RDD 依赖关系1) 宽窄依赖2) 为什么要设计宽窄依赖 …...
linux之进程信号(初识信号,信号的产生)
目录 引入一、初识信号(信号预备知识)1.生活中的信号2.Linux中的信号3.信号进程得出的初步结论 二、信号的产生1.通过终端输入产生信号拓展: 硬件中断2.调用系统函数向进程发信号3.硬件异常产生信号4.软件条件产生信号拓展: 核心转储技术总结一下: 引入 一、初识信…...
基于nginx实现正向代理(linux版本)
介绍 在企业开发环境中,局域网内的设备通常需要通过正向代理服务器访问互联网。正向代理服务器充当中介,帮助客户端请求外部资源并返回结果。局域网内也就是俗称的内网,局域网外的互联网就是外网,在一些特殊场景内,例…...
【蓝牙】win11 笔记本电脑连接 hc-06
文章目录 前言步骤 前言 使用电脑通过蓝牙添加串口 步骤 设置 -> 蓝牙和其他设备 点击 显示更多设备 更多蓝牙设置 COM 端口 -> 添加 有可能出现卡顿,等待一会 传出 -> 浏览 点击添加 hc-06,如果没有则点击 再次搜索 确定 添加成…...
小程序组件 —— 31 事件系统 - 事件绑定和事件对象
小程序中绑定事件和网页开发中绑定事件几乎一致,只不过在小程序不能通过 on 的方式绑定事件,也没有 click 等事件,小程序中绑定事件使用 bind 方法,click 事件也需要使用 tap 事件来进行代替,绑定事件的方式有两种&…...
力扣cf补题-1【算法学习day.94】
前言 ###我做这类文章一个重要的目的还是给正在学习的大家提供方向(例如想要掌握基础用法,该刷哪些题?建议灵神的题单和代码随想录)和记录自己的学习过程,我的解析也不会做的非常详细,只会提供思路和一些关…...
系统学习算法:专题四 前缀和
题目一: 算法原理: 这道题是一维前缀和的模板题,通过这道题我们可以了解什么是前缀和 题意很简单,就是先输入数组个数和查询次数,然后将数组的值放进数组,每次查询给2个数,第一个是起点&#x…...
java 迪米特法则,原理、思想、工作流程、实现细节、稳定性、优缺点、应用场景等
迪米特法则(Law of Demeter,LoD),也被称为“最少知识原则”,是一种指导面向对象设计的原则,旨在减少对象之间的耦合度。以下是对迪米特法则的详细解析。 1. 定义 迪米特法则指出:一个对象应该…...
vue项目引入阿里云svg资源图标
1:生成svg图标 登录阿里云官网 1.1 创建项目组 1.2 从阿里云网站上面获取喜欢的图标加入到已有的项目组 1.3 如果团队有自己的设计师,也可以让设计师上传自己的svg图标到阿里云指定的项目组; 使用的时候,把 资源包下载到本地项…...
存储过程和触发器
目录 1、存储过程 1.1 存储过程的概述 1.2 存储过程的类型 1. 系统存储过程 2. 本地存储过程 3. 临时存储过程 4. 扩展存储过程 1.3 T-SQL创建存储过程 1.4 T-SQL执行存储过程 1.5 T-SQL查看存储过程 1.6 T-SQL修改存储过程 1.7 T-SQL删除存储过程 2、触发器 2.1 …...
《拉依达的嵌入式\驱动面试宝典》—计算机网络篇(二)
《拉依达的嵌入式\驱动面试宝典》—计算机网络篇(二) 你好,我是拉依达。 感谢所有阅读关注我的同学支持,目前博客累计阅读 27w,关注1.5w人。其中博客《最全Linux驱动开发全流程详细解析(持续更新)-CSDN博客》已经是 Linux驱动 相关内容搜索的推荐首位,感谢大家支持。 《…...
【深度学习实战】kaggle 自动驾驶的假场景分类
本次分享我在kaggle中参与竞赛的历程,这个版本是我的第一版,使用的是vgg。欢迎大家进行建议和交流。 概述 判断自动驾驶场景是真是假,训练神经网络或使用任何算法来分类驾驶场景的图像是真实的还是虚假的。 图像采用 RGB 格式并以 JPEG 格式…...
Spring Boot 和微服务:快速入门指南
💖 欢迎来到我的博客! 非常高兴能在这里与您相遇。在这里,您不仅能获得有趣的技术分享,还能感受到轻松愉快的氛围。无论您是编程新手,还是资深开发者,都能在这里找到属于您的知识宝藏,学习和成长…...
qt QPainter setViewport setWindow viewport window
使用qt版本5.15.2 引入viewport和window目的是用于实现QPainter画出来的内容随着窗体伸缩与不伸缩两种情况,以及让QPainter在widget上指定的区域(viewport)进行绘制/渲染(分别对应下方demo1,demo2,demo3)。 setViewpo…...
网络安全面试题汇总(个人经验)
1.谈一下SQL主从备份原理? 答:主将数据变更写入自己的二进制log,从主动去主那里去拉二进制log并写入自己的二进制log,从而自己数据库依据二进制log内容做相应变更。主写从读 2.linux系统中的计划任务crontab配置文件中的五个星星分别代表什么ÿ…...
【网络云SRE运维开发】2025第3周-每日【2025/01/14】小测-【第13章ospf路由协议】理论和实操
文章目录 选择题(10道)理论题(5道)实操题(5道) 【网络云SRE运维开发】2025第3周-每日【2025/01/14】小测-【第12章ospf路由协议】理论和实操 选择题(10道) 在OSPF协议中,…...
FreeType 介绍及 C# 示例
FreeType 是一个开源的字体渲染引擎,用于将字体文件(如 TrueType、OpenType、Type 1 等)转换为位图或矢量图形。它广泛应用于操作系统、图形库、游戏引擎等领域,支持高质量的字体渲染和复杂的文本布局。 FreeType 的核心功能 字体…...
智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...
AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...
springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...
uniapp手机号一键登录保姆级教程(包含前端和后端)
目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号(第三种)后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...
uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)
UniApp 集成腾讯云 IM 富媒体消息全攻略(地理位置/文件) 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型,核心实现方式: 标准消息类型:直接使用 SDK 内置类型(文件、图片等)自…...
ZYNQ学习记录FPGA(一)ZYNQ简介
一、知识准备 1.一些术语,缩写和概念: 1)ZYNQ全称:ZYNQ7000 All Pgrammable SoC 2)SoC:system on chips(片上系统),对比集成电路的SoB(system on board) 3)ARM:处理器…...
