当前位置: 首页 > news >正文

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 连接上进行全双工通信的协议&#xff0c;广泛应用于需要实时数据交换的应用程序中。它能够实现服务器与客户端之间的双向通信&#xff0c;避免了传统 HTTP 请求/响应的延迟。结合 Spring Boot&#xff0c;开发实时通信应用变得更加高效与简便。 1. …...

zerotier搭建虚拟局域网,自建planet

基于该开源项目 自建planet节点&#xff0c;更快速&#xff0c;更安全 本教程依据docker-zerotier-planet 项目文档书写&#xff0c;并以linux(centos 7)和windows作为示例&#xff0c;需要其他系统配置方法&#xff0c;可移步项目文档 一. 前置资源 具有外网ip的服务器 后面…...

SQL面试题1:连续登陆问题

引言 场景介绍&#xff1a; 许多互联网平台为了提高用户的参与度和忠诚度&#xff0c;会推出各种连续登录奖励机制。例如&#xff0c;游戏平台会给连续登录的玩家发放游戏道具、金币等奖励&#xff1b;学习类 APP 会为连续登录学习的用户提供积分&#xff0c;积分可兑换课程或…...

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.软件条件产生信号拓展: 核心转储技术总结一下&#xff1a; 引入 一、初识信…...

基于nginx实现正向代理(linux版本)

介绍 在企业开发环境中&#xff0c;局域网内的设备通常需要通过正向代理服务器访问互联网。正向代理服务器充当中介&#xff0c;帮助客户端请求外部资源并返回结果。局域网内也就是俗称的内网&#xff0c;局域网外的互联网就是外网&#xff0c;在一些特殊场景内&#xff0c;例…...

【蓝牙】win11 笔记本电脑连接 hc-06

文章目录 前言步骤 前言 使用电脑通过蓝牙添加串口 步骤 设置 -> 蓝牙和其他设备 点击 显示更多设备 更多蓝牙设置 COM 端口 -> 添加 有可能出现卡顿&#xff0c;等待一会 传出 -> 浏览 点击添加 hc-06&#xff0c;如果没有则点击 再次搜索 确定 添加成…...

小程序组件 —— 31 事件系统 - 事件绑定和事件对象

小程序中绑定事件和网页开发中绑定事件几乎一致&#xff0c;只不过在小程序不能通过 on 的方式绑定事件&#xff0c;也没有 click 等事件&#xff0c;小程序中绑定事件使用 bind 方法&#xff0c;click 事件也需要使用 tap 事件来进行代替&#xff0c;绑定事件的方式有两种&…...

力扣cf补题-1【算法学习day.94】

前言 ###我做这类文章一个重要的目的还是给正在学习的大家提供方向&#xff08;例如想要掌握基础用法&#xff0c;该刷哪些题&#xff1f;建议灵神的题单和代码随想录&#xff09;和记录自己的学习过程&#xff0c;我的解析也不会做的非常详细&#xff0c;只会提供思路和一些关…...

系统学习算法:专题四 前缀和

题目一&#xff1a; 算法原理&#xff1a; 这道题是一维前缀和的模板题&#xff0c;通过这道题我们可以了解什么是前缀和 题意很简单&#xff0c;就是先输入数组个数和查询次数&#xff0c;然后将数组的值放进数组&#xff0c;每次查询给2个数&#xff0c;第一个是起点&#x…...

java 迪米特法则,原理、思想、工作流程、实现细节、稳定性、优缺点、应用场景等

迪米特法则&#xff08;Law of Demeter&#xff0c;LoD&#xff09;&#xff0c;也被称为“最少知识原则”&#xff0c;是一种指导面向对象设计的原则&#xff0c;旨在减少对象之间的耦合度。以下是对迪米特法则的详细解析。 1. 定义 迪米特法则指出&#xff1a;一个对象应该…...

vue项目引入阿里云svg资源图标

1&#xff1a;生成svg图标 登录阿里云官网 1.1 创建项目组 1.2 从阿里云网站上面获取喜欢的图标加入到已有的项目组 1.3 如果团队有自己的设计师&#xff0c;也可以让设计师上传自己的svg图标到阿里云指定的项目组&#xff1b; 使用的时候&#xff0c;把 资源包下载到本地项…...

存储过程和触发器

目录 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中参与竞赛的历程&#xff0c;这个版本是我的第一版&#xff0c;使用的是vgg。欢迎大家进行建议和交流。 概述 判断自动驾驶场景是真是假&#xff0c;训练神经网络或使用任何算法来分类驾驶场景的图像是真实的还是虚假的。 图像采用 RGB 格式并以 JPEG 格式…...

Spring Boot 和微服务:快速入门指南

&#x1f496; 欢迎来到我的博客&#xff01; 非常高兴能在这里与您相遇。在这里&#xff0c;您不仅能获得有趣的技术分享&#xff0c;还能感受到轻松愉快的氛围。无论您是编程新手&#xff0c;还是资深开发者&#xff0c;都能在这里找到属于您的知识宝藏&#xff0c;学习和成长…...

qt QPainter setViewport setWindow viewport window

使用qt版本5.15.2 引入viewport和window目的是用于实现QPainter画出来的内容随着窗体伸缩与不伸缩两种情况&#xff0c;以及让QPainter在widget上指定的区域(viewport)进行绘制/渲染&#xff08;分别对应下方demo1&#xff0c;demo2&#xff0c;demo3&#xff09;。 setViewpo…...

网络安全面试题汇总(个人经验)

1.谈一下SQL主从备份原理&#xff1f; 答&#xff1a;主将数据变更写入自己的二进制log,从主动去主那里去拉二进制log并写入自己的二进制log,从而自己数据库依据二进制log内容做相应变更。主写从读 2.linux系统中的计划任务crontab配置文件中的五个星星分别代表什么&#xff…...

【网络云SRE运维开发】2025第3周-每日【2025/01/14】小测-【第13章ospf路由协议】理论和实操

文章目录 选择题&#xff08;10道&#xff09;理论题&#xff08;5道&#xff09;实操题&#xff08;5道&#xff09; 【网络云SRE运维开发】2025第3周-每日【2025/01/14】小测-【第12章ospf路由协议】理论和实操 选择题&#xff08;10道&#xff09; 在OSPF协议中&#xff0c…...

FreeType 介绍及 C# 示例

FreeType 是一个开源的字体渲染引擎&#xff0c;用于将字体文件&#xff08;如 TrueType、OpenType、Type 1 等&#xff09;转换为位图或矢量图形。它广泛应用于操作系统、图形库、游戏引擎等领域&#xff0c;支持高质量的字体渲染和复杂的文本布局。 FreeType 的核心功能 字体…...

AX-MES生产制造管理系统-总览

前言说起 MES 就不得不说 ERP&#xff0c;但是 ERP 大家基本上都知道&#xff0c;MES 就不一定了&#xff0c;常见的 ERP 系统包括 SAP、金蝶、用友等&#xff0c;ERP的流程相对来说也比较统一&#xff1b;MES就不同了&#xff0c;基本上熟悉业务流程的软件公司都可以开发并实施…...

Unity安卓构建72小时实战指南:从零到真机运行

1. 这不是“又一本Unity教程”&#xff0c;而是我带三个新人从零上线第一款安卓游戏的真实路径你点开这个标题&#xff0c;大概率正站在两个路口之间&#xff1a;一边是满屏“30天速成Unity”“零基础做爆款”的短视频封面&#xff0c;一边是你刚下载完Unity Hub、卡在Android …...

别再只用Service了!ROS1 Action通信保姆级教程:从导航进度条到任务取消,手把手教你实现带反馈的机器人任务

别再只用Service了&#xff01;ROS1 Action通信保姆级教程&#xff1a;从导航进度条到任务取消&#xff0c;手把手教你实现带反馈的机器人任务当你的机器人正在执行一个长达10分钟的导航任务时&#xff0c;突然发现目标点设置错误&#xff0c;这时候如果只能干等着任务完成或者…...

【MySQL数据库 | 第一篇】 概述

数据库相关概念&#xff1a; 数据库(Database)&#xff1a;数据库是指一组有组织的数据的集合&#xff0c;通过计算机程序进行管理和访问。数据库管理系统&#xff1a;操纵和管理数据库的大型软件SQL&#xff1a;操作关系型数据库的编程语言&#xff0c;定义了一套操作关系型数…...

Spring Security OAuth2 /oauth/token 401原因与Content-Type规范

1. 问题现场还原&#xff1a;一个看似简单却让开发停摆两小时的/oauth/token请求刚接手一个老项目做安全加固&#xff0c;第一件事就是验证OAuth2密码模式的token获取流程。我照着文档写了一条curl命令&#xff1a;curl -X POST http://localhost:8080/oauth/token回车执行&…...

<背包问题>

背包问题是一类组合优化问题&#xff0c;其基本形式是给定一组物品&#xff0c;每个物品都有一个重量和一个价值&#xff0c;以及一个有限的背包容量&#xff0c;目标是在不超过背包容量的前提下&#xff0c;选择物品使得背包中的物品价值最大化。动态规划是解决背包问题的常用…...

告别漫长等待:UE5.2.1 Windows打包效率优化与插件问题排查指南

告别漫长等待&#xff1a;UE5.2.1 Windows打包效率优化与插件问题排查指南第一次点击"打包项目"按钮时&#xff0c;进度条仿佛被冻结的场景&#xff0c;每个UE5开发者都经历过。尤其当项目规模达到数十GB时&#xff0c;等待时间可能超过一小时——这背后隐藏着引擎底…...

大厂校招变了:AI 能力正在进入笔试和面试

最近不少同学投递校招时&#xff0c;应该已经发现一个变化&#xff1a; 以前 JD 里写的是“熟悉 Python / Java / SQL / Office 优先”。 现在越来越多岗位开始出现新的描述&#xff1a; “熟练使用 AI 工具者优先” “了解大模型应用者优先” “具备 AI 辅助编程经验优先” “…...

3大技术突破:重新定义Switch游戏安装性能极限

3大技术突破&#xff1a;重新定义Switch游戏安装性能极限 【免费下载链接】Awoo-Installer A No-Bullshit NSP, NSZ, XCI, and XCZ Installer for Nintendo Switch 项目地址: https://gitcode.com/gh_mirrors/aw/Awoo-Installer Awoo Installer是一款专为破解版Nintendo…...

Win11Debloat:Windows系统精简与隐私保护的专业解决方案

Win11Debloat&#xff1a;Windows系统精简与隐私保护的专业解决方案 【免费下载链接】Win11Debloat A simple, lightweight PowerShell script that allows you to remove pre-installed apps, disable telemetry, as well as perform various other changes to declutter and …...