深入理解 WebSocket:实时通信的利器

深入理解 WebSocket:实时通信的利器

1. 什么是 WebSocket?

WebSocket 是一种网络通信协议,它允许服务器和客户端之间建立持久的双向通信通道,适用于高频率、低延迟的数据交换场景。在传统的 HTTP 通信中,每次请求都需要客户端发起并等待服务器响应,连接在请求结束后会关闭。这种模式在需要频繁交互的数据场景下效率低下。WebSocket 则通过一次连接握手后建立的持久连接,允许双向数据实时传输,极大地降低了通信延迟。

1.1 WebSocket 与 HTTP 的区别

特性WebSocketHTTP
连接模式持久连接,支持双向通信短连接,请求-响应模型
数据传输方向客户端和服务器可互相发送数据仅客户端发起请求,服务器响应
网络开销较低,减少连接和断开次数较高,每次请求都需重新建立和断开连接
适用场景实时应用,低延迟、高频交互场景静态资源获取、传统 Web 应用
典型应用实时聊天、在线游戏、股票行情、协同编辑等网站内容浏览、资源获取、表单提交等

WebSocket 的优势体现在实时通信的能力上,尤其适用于那些需要服务器实时推送更新数据的场景。

2. WebSocket 的工作原理

WebSocket 使用的是标准的 TCP 协议,但它的连接是从 HTTP 协议升级而来的。这意味着 WebSocket 可以复用 HTTP 的握手机制(通过 Upgrade 头部字段),在最初的连接建立阶段,客户端会发送一个标准的 HTTP 请求,并在头部声明希望使用 WebSocket 协议。如果服务器同意,则返回 101 状态码(协议切换),并从此时起双方就可以通过 WebSocket 进行双向通信。

2.1 握手过程

  • 客户端请求:客户端向服务器发起一个包含 Upgrade: websocket 的 HTTP 请求,表示希望升级到 WebSocket。
  • 服务器响应:服务器验证请求后,如果同意升级,则返回状态码 101 和相应的 WebSocket 握手头部字段。
  • 握手成功:握手成功后,连接变为持久连接,双方可以开始传输数据,直到连接被主动关闭。

WebSocket 使用了标准的 HTTP 端口(80 或 443),因此能够穿透大部分防火墙和代理,且它的全双工特性使得客户端和服务器可以在不需要多次握手的情况下随时交换信息。

3. WebSocket 的应用场景

WebSocket 的设计初衷就是为了解决实时通信的需求,尤其是在高并发、低延迟场景中非常有用。以下是一些典型的应用场景:

3.1 实时聊天应用

在线聊天系统需要服务器能够即时将用户发送的消息广播给其他用户。通过 WebSocket,可以在一个持久连接中让所有用户在第一时间接收到消息,而无需轮询服务器或等待客户端请求,非常适合聊天室、客服系统等场景。

3.2 实时推送通知

新闻网站、股票交易平台和社交媒体常需要实时推送数据,例如新闻更新、股票价格变动或新的消息提醒。WebSocket 可以让服务器在数据发生变化时即时通知客户端,无需客户端频繁轮询服务器。

3.3 在线多人游戏

多人在线游戏需要在用户之间快速同步位置、动作等数据。WebSocket 提供了低延迟、高频率的通信能力,使得游戏中的每个动作都能立即广播给其他玩家,从而保证了流畅的实时互动体验。

3.4 实时协作工具

例如,在线文档编辑工具允许多个用户同时编辑同一个文档,文档的变化需要在所有用户的浏览器中实时同步。通过 WebSocket,服务器能够在某个用户修改文档后,立即将修改内容推送给其他协作者。

4. WebSocket 在 Spring Boot 中的实现方式

Spring Boot 对 WebSocket 的支持非常丰富,开发者可以根据不同的业务场景选择合适的实现方式。以下是三种常见的 WebSocket 实现方式,每种方式有不同的适用场景和特点。

4.1 基于 JSR 356 标准的实现

JSR 356 是 Java 中的 WebSocket 标准 API,它允许开发者通过注解的方式来定义 WebSocket 服务器端点。该实现方式简单直观,开发者只需在类上使用 @ServerEndpoint 注解,便可定义一个 WebSocket 端点。该方式非常适合开发简单的实时通信应用,比如简单的聊天室、通知推送等。

  • 优点:实现简单,代码量少,适合轻量级的 WebSocket 应用。
  • 缺点:功能相对单一,无法灵活控制复杂的业务逻辑。

4.2 基于 WebSocketHandler 的实现

Spring 提供了 WebSocketHandler 接口,允许开发者自定义 WebSocket 的行为。与注解方式不同,WebSocketHandler 方式可以更加灵活地处理消息接收和发送的细节,也支持处理文本、二进制等多种消息格式。此外,开发者还可以配置自定义的拦截器,用于实现用户验证、消息过滤等功能。

  • 优点:灵活性高,适合需要复杂消息处理逻辑的应用。
  • 缺点:相比于注解实现方式,代码较为复杂,适用于需要定制化业务逻辑的场景。

4.3 基于 STOMP 协议的实现

深入理解STOMP协议

STOMP(Simple Text Oriented Messaging Protocol)是一种简单的消息传输协议,常与 WebSocket 一起使用。STOMP 的核心功能是支持发布/订阅模型,允许多个客户端订阅某个消息主题,然后由服务器推送消息到所有订阅者。这种方式非常适合开发多客户端互动的实时系统,比如股票推送、在线协作工具等。

Spring 提供了对 STOMP 的内置支持,开发者可以通过注解轻松实现消息的路由、订阅和分发。

  • 优点:内置消息路由和发布/订阅机制,适合复杂的多人互动场景。
  • 缺点:实现较为复杂,需要理解 STOMP 协议及其在 Spring 中的集成方式。

5. WebSocket 的优势与局限

5.1 优势

  • 双向通信:WebSocket 的全双工通信特性,允许服务器和客户端在同一连接上随时发送数据,而无需多次建立连接。
  • 低延迟:通过持久连接,WebSocket 消除了 HTTP 的频繁握手过程,极大地减少了通信延迟。
  • 适合高并发:WebSocket 协议本身非常轻量级,允许在高并发场景下依然保持低开销的通信。

5.2 局限

  • 适用场景有限:WebSocket 更适用于需要实时数据推送的场景,对于静态内容的获取或不需要频繁通信的应用,HTTP 依然是更合适的选择。
  • 兼容性问题:虽然现代浏览器都支持 WebSocket,但一些老旧的网络基础设施(如防火墙、代理服务器)可能会阻碍 WebSocket 的使用。
  • 状态管理:WebSocket 是持久连接,需要额外的机制来管理连接的生命周期和状态,否则可能导致资源泄露。

6. 结论

WebSocket 作为一种强大的实时通信协议,在现代 Web 应用中扮演着越来越重要的角色,尤其在需要频繁、低延迟通信的场景中。通过 WebSocket,开发者可以实现丰富的实时交互体验,从简单的消息推送到复杂的多人在线协作,都能够通过持久的 WebSocket 连接实现高效的通信。

在 Spring Boot 中,WebSocket 的实现有多种选择,开发者可以根据应用需求选择最合适的方案。对于轻量级的实时应用,可以使用基于 JSR 356 标准的实现;对于需要更高自定义能力的场景,可以选择 WebSocketHandler 实现;而在复杂的多人互动场景中,STOMP 协议的发布/订阅机制是最好的选择。

通过合理使用 WebSocket,可以为用户提供更为实时、互动性强的体验,让 Web 应用变得更加智能和高效。

推荐阅读

WebSocket在SpringBoot中的高级应用

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

thinkphp6开发的通用网站系统源码

thinkphp6开发的通用网站系统源码。 基于ThinkPHP6框架开发的通用后台权限管理系统,底层采用国内最流行的ThinkPHP6框架, 支持内容管理、文章管理、用户管理、权限管理、角色管理等功能。 代码下载百度网盘

jenkins部署Maven和NodeJS项目

在 Java 项目开发中,项目的编译、测试、打包等是比较繁琐的,属于重复劳动的工作,浪费人力和时间成本。以往开发项目时,程序员往往需要花较多的精力在引用 jar 包搭建项目环境上,跨部门甚至跨人员之间的项目结构都有可能…

基于SSM的宿舍管理系统 (源码+定制+文档)

博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…

【MAUI】CommunityToolkit社区工具包介绍

一、为什么需要声明式开发 .NET的MVVM,始于WPF,很古典,它甚至可能是现代前端框架“声明式开发”的鼻祖。声明式开发,之所以出现,是因为命令式开发在UI层和代码层上无法解耦的问题。如下图所示: 1、命令式开发:后台代码需要调用UI层的控件(label.Text),如果更新UI层…

stm32 bootloader跳转程序设计

文章目录 1、bootloader跳转程序设计&#xff08;1&#xff09;跳转程序&#xff08;2&#xff09;、app程序中需要注意<1>、在keil中ROM起始地址和分配的空间大小<2>、在system_stm32f4xx.c中设置VECT_TAB_OFFSET为需要偏移的地址<3>、main函数中使能中断 总…

C初阶(六)--- static 来喽

前言&#xff1a;C语言中有许多关键字&#xff08;关键字是预先保留的标识符&#xff0c;具有特殊意义&#xff0c;不能用作变量 名、函数名等普通标识符。&#xff09; 比如&#xff1a;前面在变量与常量那一节提到的extern 就是一个关键字&#xff0c;应该还记得e…

Grafana链接iframe嵌入Web前端一直跳登录页面的问题记录

概述 公司有个项目使用到Grafana作为监控界面,因为项目方的环境极其复杂,仅物理隔离的环境就有三四个,而且每个都得部署项目,今天在某个环境测试,查看界面遇到一个比较奇怪的Grafana问题,后面针对该问题进行跟踪分析并解决,故而博文记录,用于备忘。 问题 登录项目We…

Pikachu-Sql Inject-insert/update/delete注入

insert 注入 插入语句 insert into tables values(value1,value2,value3); 如&#xff1a;插入用户表 insert into users (id,name,password) values (id,username,password); 当点击注册 先判断是否有SQL注入漏洞&#xff0c;经过判断之后发现存在SQL漏洞。构造insert的pa…

Redis 篇-深入了解在 Linux 的 Redis 网络模型结构及其流程(阻塞 IO、非阻塞 IO、IO 多路复用、异步 IO、信号驱动 IO)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 用户空间与内核空间概述 2.0 Redis 网络模型 2.1 Redis 网络模型 - 阻塞 IO 2.2 Redis 网络模型 - 非阻塞 IO 2.3 Redis 网络模型 - IO 多路复用 2.3.1 IO 多路复…

【mmengine】配置器(config)(入门)读取与使用

一、 介绍 MMEngine 实现了抽象的配置类&#xff08;Config&#xff09;&#xff0c;为用户提供统一的配置访问接口。 配置类能够支持不同格式的配置文件&#xff0c;包括 python&#xff0c;json&#xff0c;yaml&#xff0c;用户可以根据需求选择自己偏好的格式。 配置类提供…

【网路通信基础与实践番外二】TCP协议的流量控制和拥塞控制以及二者区别和例题

TCP协议是端对端的协议&#xff0c;因此在数据进行传输的过程受发送方&#xff0c;数据通道&#xff0c;接收方三方状态的影响。我们用水龙头来比喻数据发送方&#xff0c;水管来比喻数据通道&#xff0c;水桶来表示数据接收方。 图(a)表示水桶太小&#xff0c;来不及接受注入…

Unity实战案例全解析:RTS游戏的框选和阵型功能(3)生成范围检测框 +重置框选操作

前篇&#xff1a;Unity实战案例全解析&#xff1a;RTS游戏的框选和阵型功能&#xff08;2&#xff09; 生成选择框-CSDN博客 本案例来源于unity唐老狮&#xff0c;有兴趣的小伙伴可以去泰克在线观看该课程 我只是对重要功能进行分析和做出笔记分享&#xff0c;并未无师自通&…

给出向量求叉乘(在垂直的时候可以简化)

1、可以用那个求行列式的方法求叉乘。 2、在两个向量垂直的时候&#xff0c;可以用简化方法&#xff0c;前面幅度相乘&#xff0c;然后ex叉乘ey是ez 注意叉乘结果无论原向量是不是垂直&#xff0c;叉乘结果都与两个向量垂直

深入探秘 Java 网络编程:从基础到多线程服务器的全方位指南

我的主页&#xff1a;2的n次方_ Java 作为一门功能强大的编程语言&#xff0c;不仅在桌面应用、移动开发、后端开发等领域表现出色&#xff0c;还在网络编程中拥有广泛的应用。网络编程涉及在两个或多个设备之间通过网络进行通信&#xff0c;这对于构建分布式系统、客户端…

【Linux】进程管理:状态与优先级调度的深度分析

✨ 山海自有归期&#xff0c;风雨自有相逢 &#x1f30f; &#x1f4c3;个人主页&#xff1a;island1314 &#x1f525;个人专栏&#xff1a;Linux—登神长阶 ⛺️ 欢迎关注&#xff1a;&#x1f44d;点赞 &#x1…

spring揭秘25-springmvc03-其他组件(文件上传+拦截器+处理器适配器+异常统一处理)

文章目录 【README】【1】文件上传与MultipartResolver【1.1】使用MultipartResolver进行文件上传【1.2】springmvc处理multipart多部件请求流程【1.3】使用springmvc上传文件代码实现&#xff08;springmvc6.10版本&#xff09;&#xff1a; 【2】Handler与HandlerAdaptor&…

stm32单片机学习 - MDK仿真调试

1 进行环境配置 点击 Options for Target&#xff0c;也就是我们俗称的魔法棒。 将"C/C"中的Optimization选项选为Level 0(-O0) 作用:优化等级调为0级,便于调试时分析代码 勾选"Debug"中的Load Application at Starup 和 Run to main() 选项 作用:Load…

Emergency Stop (ES)

文章目录 1. 介绍2. Feature List3. 紧急停止信号触发方式3.1 Port触发紧急停止信号3.2 SMU事件触发紧急停止信号3.3 软件触发紧急停止信号 4. 应用场景4.1 Port4.2 MSC 1. 介绍 Emergency Stop (ES)是Ifx System Control Units (SCU)六大模块之一。详细信息可以参考Infineon-…

latex有哪些颜色中文叫什么,Python绘制出来

latex有哪些颜色中文叫什么&#xff0c;Python绘制出来 为了展示xcolor包预定义的颜色及其对应的中文名称&#xff0c;并使用Python打印出来&#xff0c;我们可以先列出常见的预定义颜色名称&#xff0c;然后将它们翻译成中文&#xff0c;并最后用Python打印出来。 步骤 列出…

移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——13.mapset(模拟实现)

1.对红黑树进行改造 1.1treenode模板参数改变 之前构建treenode模板参数传的是class k,class v(set为k&#xff0c;k&#xff1b;map是k&#xff0c;v&#xff09;&#xff0c;现在直接用T代替 template<class T> //这里直接传了T作为模板参数&#xff0c;T可能是pai…