WebSocket知识点笔记(一)

news2025/1/23 0:39:59

WebSocket

​ WebSocket是一种在单个TCP连接上进行全双工通信的协议。它使得客户端和服务端之间的消息传递更加高效,允许服务器主动向客户端推送数据。

一.WebSocket全双工通信

WebSocket提供了真正的双向通信,客户端和服务端可以同时发送和接收消息

1.1传统HTTP模型 vs WebSocket全双工模型

1.1.1 HTTP请求/响应模型

1.客户端发起请求,服务器响应

2.每次通信都需要建立新的TCP连接,增加了延迟

3.服务器不能主动向客户端推送数据,只能在客户端请求时响应

1.1.2 WebSocket全双工通信

1.单个TCP连接保持打开状态,用于双向通信

2.客户端和服务端可以随时发送消息,无需等待对方完成操作

3.服务器可以主动向客户端推送数据,实现真正的实时通信

1.2 全双工通信的工作原理

1.2.1 连接建立(通过HTTP升级请求实现协议转换)

​ 客户端通过WebSocket对象发起连接请求,使用HTTP协议中的Upgrade头将连接升级为WebSocket协议,服务器同意升级后,返回101状态码,并保持连接打开,直到被显式关闭。

1.初始HTTP请求

​ 客户端通过标准的HTTP协议发起一个请求,该请求包含一个Upgrade头,表示希望将连接升级为WebSocket协议

    GET /chat HTTP/1.1
    Host: example.com
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
    Sec-WebSocket-Version: 13 
2.服务器响应

​ 如果服务器支持WebSocket并同意升级,它会返回一个101状态码(Switching Protocols),并确认升级到WebSocket协议

    HTTP/1.1 101 Switching Protocols
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
3.连接保持打开

​ 一旦握手成功,HTTP连接升级为WebSocket连接并保持打开状态,用于后续的双向通信,直到被显式关闭。

1.2.2 数据帧传输(使用帧结构封装数据,支持文本和二进制格式)

​ 一旦连接建立,客户端和服务器可以在任何时候发送消息,消息以帧的形式进行传输,每个帧包含一个或多个数据包,客户端和服务器之间的消息传递是独立的,互不干扰的。

1.消息分帧

​ WebSocket使用帧(frame)来封装数据,每个帧包含一个或多个数据包,并且可以是文本或二进制数据。每个帧都有一个固定的头部结构,包括操作码(opcode)、负载长度等字段。

2.消息传递

​ 客户端和服务器可以在任何时候发送帧,无需等待对方完成操作,发送的消息可以是完整的,也可以是分段的(多个帧组成一个完整的消息)。

3.控制帧

​ 除了数据帧,WebSocket还定义了多种控制帧,如关闭帧(Close Frame)、Ping帧和Pong帧,用于管理和维护连接状态。

1.2.3 并发通信(客户端和服务器可以同时发送消息)
1.独立的数据流

​ WebSocket连接中的数据流是独立的,客户端和服务器可以同时发送和接收消息,互不干扰,这个特性使得双方可以在同一时间进行多任务处理,例如客户端发送用户输入的同时,服务器推送最新的通知。

1.2.4 连接管理(通过心跳机制和异常处理确保连接的稳定性和可靠性)
1.心跳机制

​ 为了确保连接的有效性,WebSocket提供了心跳机制,客户端和服务端可以定期发送Ping和Pong帧来检测连接状态。如果一段时间内没有收到对方的响应,可以认为连接已断开,并采取相应的措施(如重连)。

2.异常处理

​ 当出现网络故障或其他异常情况时,WebSocket连接可能会中断,此时客户端和服务器可以通过捕获异常时间(如onError和onClose)来进行处理。

​ 例如,在Java中

    @OnClose
    public void onClose(Session session){
        sessions.remove(session);
        broadcast("User "+session.getId()+" disconnected",session);
    }
    @OnError
    public void onError(Session session,Throwable error){
        error.printStackTrace();
        sessions.remove(session);
        broadcast("User "+session.getId()+" encountered an error :" + error.getMessage(),session);
    }
1.2.5 连接关闭
1.正常关闭

​ 客户端或服务器可以主动发送关闭帧(Close Frame)来关闭连接,对方收到关闭帧后,也会发送一个关闭帧作为确认,然后双方关闭连接。

2.异常关闭

​ 如果一方突然断开连接(如网络故障),另一方会在一定时间内检测到连接丢失,并触发关闭事件。

二.WebSocket的优缺点

2.1 WebSocket的优势

2.1.1 低延迟

​ 相比于传统的HTTP请求/响应模式,WebSocket减少了通信延迟,因为不需要每次都建立新的连接,减少了每次通信的握手时间。

1.即时消息传递

​ 在传统的HTTP请求/响应模型中,客户端必须先发起请求,服务器才能响应。而WebSocket连接一旦建立,服务器可以主动向客户端推送数据,无需等待客户端请求。

​ 这种即时消息传递显著减少了通信延迟,特别适合需要实时更新的应用场景。

2.减少握手开销

​ 每次HTTP请求都需要重新建立TCP连接,这会增加额外的握手时间,而WebSocket连接保持打开状态,减少了频繁建立和关闭连接的开销,从而减低延迟。

2.1.2 高效资源利用

​ 单个连接可以处理多条消息,减少了频繁建立和关闭连接的开销。

1.单个连接多个用途

​ WebSocket使用单个TCP连接进行双向通信,避免了频繁创建和销毁连接带来的资源消耗。相比于轮询(polling)和长轮询(long polling),WebSocket显著减少了网络带宽和服务器资源的占用。

2.轻量级协议头

​ WebSocket协议头信息非常小,相比于HTTP协议头,减少了不必要的网络流量,进一步提高了效率。

2.1.3 实时性

​ 服务器可以主动推送数据给客户端,非常适合需要实时更新的应用场景

1.服务器推送

​ WebSocket允许服务器主动向客户端推送数据,实现了真正的实时通信,这对于需要及时更新的应用非常重要。

2.事件驱动架构

​ 客户端和服务器可以在任何时候发送消息,基于事件驱动的架构使得应用能够快速响应用户操作和服务器通知,提供更好的用户体验。

2.1.4 简化开发
1.易于实现

​ WebSocket提供了简单的API,使得开发者可以轻松地在客户端和服务器之间建立双向通信。

​ 例如,在Java中使用WebSokcet只需少量代码+注解即可实现基本功能。

 @ServerEndpoint("/chat")
public class ChatServer {
    private static Set<Session> sessions = Collections.synchronizedSet(new HashSet<>());
    @OnOpen
    public void onOpen(Session session) {
        sessions.add(session);
        broadcast("User connected: "+ session.getId(),session);
    }
    @OnMessage
    public void onMessage(String message,Session  session){
        broadcast("User "+session.getId()+" : "+message,session);
    }
    @OnClose
    public void onClose(Session session){
        sessions.remove(session);
        broadcast("User "+session.getId()+" disconnected",session);
    }
    @OnError
    public void onError(Session session,Throwable error){
        error.printStackTrace();
        sessions.remove(session);
        broadcast("User "+session.getId()+" encountered an error :" + error.getMessage(),session);
    }
    private void broadcast(String message,Session exclude){
        synchronized (sessions){
            for(Session session:sessions){
                try {
                    if(session.equals(exclude)){
                        continue;
                    }
                    session.getBasicRemote().sendText(message);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

2.丰富的库支持

​ 许多编程语言和框架都提供了对WebSocket的良好支持,developer可以选择适合自己项目的库或框架,快速构建WebSocket应用。

2.1.5 增强用户体验
1.无缝交互

​ WebSocket的全双工通信使得应用可以更流程地与用户互动,提供无缝的用户体验。例如,在线聊天应用中,用户可以立即看到其他用户的回复,而无需刷新页面。

2.实时反馈

​ 对于需要实时反馈的应用,如在线游戏或协作编辑工具,WebSocket可以确保用户操作得到即时响应,增强用户的参与感和满意度。

2.1.6 适用于多种应用场景
1.实时聊天室

​ WebSocket可以实现实时的消息传递,非常适合构建聊天室或即时通讯应用,无需轮询服务器,提供流程的聊天体验。

2.协作编辑工具

​ 允许多个用户同时编辑同一个文档,并实时同步修改。

3.在线游戏

​ 对于需要低延迟交互的游戏,WebSocket提供了更好的性能,确保玩家的操作和游戏状态同步更新。

4.金融数据更新

​ WebSocket可以用来实时推送最新的股票价格或其他金融数据,帮助用户及时做出决策。

5.物联网设备监控

​ 实时监控设备状态并推送更新给客户端,提高设备管理的效率。

2.2 WebSocket的缺点

2.2.1 连接保持开销
1.长时间占用资源

​ WebSocket连接一旦建立,会一直保持打开状态,直到显示关闭,这可能导致服务器资源(如内存、文件描述符等)被长时间占用,尤其是在高并发场景下。

2.网络带宽消耗

​ 虽然WebSocket协议头比较小,但长时间保持连接仍然会占用一定的网络带宽,特别是在大量用户同时在线的情况下。

2.2.2 防火墙和代理问题
1.企业级网络限制

​ 某些企业或组织的防火墙和代理服务器可能会组织WebSocket连接,因为它们默认只允许HTTP/HTTPS流量通过,这种限制可能需要额外的配置或使用HTTPS WebSocket(wss://),但这增加了复杂性。

2.2.3 不支持断点续传
1.数据完整性问题

​ WebSocket不支持断点续传功能,如果连接意外中断,未完成的消息传输将丢失,需要重新发送整个消息。对于大文件传输或长时间的任务,这可能会导致效率低下或数据丢失。

2.2.4 浏览器兼容性
1.旧浏览器支持有限

​ 尽管现代浏览器普遍支持WebSocket,但在一些老旧版本的浏览器中,WebSocket支持可能缺失或不稳定,developer可能需要提供回退机制(如轮询或长轮询)以确保兼容性。

2.2.5 复杂的错误处理
1.异常情况处理复杂

​ WebSocket连接可能会因为网络故障,服务器重启等原因突然断开,developer需要实现复杂的状态管理和重连逻辑,以确保应用的稳定性和可靠性。

2.心跳机制维护

​ 为了确保连接的有效性,通常需要实现心跳机制(Ping/Pong帧)。虽然这有助于检测连接状态,但也增加了开发和维护的复杂性。

2.2.6 安全性考虑
1.加密需求

​ WebSocket默认不加密,必须通过WSS(WebSocket Secure)协议(使用TLS加密)来确保数据传输的安全性。实现WSS需要额外的配置和证书管理,增加了部署的复杂性。

2.跨域安全

​ WebSocket也面临跨域资源共享(CORS)的问题,需要在服务端进行适当的配置以确保安全访问。

2.2.7 不适合所有应用场景
1.非实时需求

​ 对于不需要实时通信的应用场景,WebSocket可能是过度设计。例如,简单的表单提交或静态页面加载,使用传统的HTTP请求/响应模型更为合适。

2.高延迟容忍度

​ 如果应用对延迟要求不高,或者可以接受一定的延迟,使用轮询或长轮询可能是更简单且有效的解决方案。

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

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

相关文章

云计算、AI与国产化浪潮下DBA职业之路风云变幻,如何谋破局启新途?

引言 在近日举办的一场「云和恩墨大讲堂」直播栏目中&#xff0c;云和恩墨联合创始人李轶楠、副总经理熊军和欧冶云商数据库首席薛晓刚共同探讨了DBA的现状与未来发展。三位专家从云计算、人工智能、国产化替代等多个角度进行了深入的分析和探讨&#xff0c;为从业者提供了宝贵…

npm install 报错:Command failed: git checkout 2.2.0-c

[TOC](npm install 报错&#xff1a;Command failed: git checkout 2.2.0-c) npm install 报错&#xff1a;Command failed: git checkout 2.2.0-c export NODE_HOME/usr/local/node-v14.14.0-linux-x64 npm config set registry https://registry.npmmirror.com 使用如上环…

场馆预定平台高并发时间段预定实现V2

&#x1f3af; 本文档介绍了场馆预订系统接口V2的设计与实现&#xff0c;旨在解决V1版本中库存数据不一致及性能瓶颈的问题。通过引入令牌机制确保缓存和数据库库存的最终一致性&#xff0c;避免因服务器故障导致的库存错误占用问题。同时&#xff0c;采用消息队列异步处理库存…

图解Git——分布式Git《Pro Git》

分布式工作流程 Centralized Workflow&#xff08;集中式工作流&#xff09; 所有开发者都与同一个中央仓库同步代码&#xff0c;每个人通过拉取、提交来合作。如果两个开发者同时修改了相同的文件&#xff0c;后一个开发者必须在推送之前合并其他人的更改。 Integration-Mana…

将 AzureBlob 的日志通过 Azure Event Hubs 发给 Elasticsearch(1.标准版)

问题 项目里使用了 AzureBlob 存储了用户上传的各种资源文件&#xff0c;近期 AzureBlob 的流量费用增长很快&#xff0c;想通过分析Blob的日志&#xff0c;获取一些可用的信息&#xff0c;所以有了这个需求&#xff1a;将存储账户的日志&#xff08;读写&#xff0c;审计&…

【json_object】mysql中json_object函数过长,显示不全

问题&#xff1a;json只显示部分 解决&#xff1a; SET GLOBAL group_concat_max_len 1000000; -- 设置为1MB&#xff0c;根据需要调整如果当前在navicat上修改&#xff0c;只有效本次连接和后续会话&#xff0c;重新连接还是会恢复默认值1024 在my.ini配置文件中新增或者修…

Flink底层架构与运行流程

这张图展示了Flink程序的架构和运行流程。 主要组件及功能&#xff1a; Flink Program&#xff08;Flink程序&#xff09;&#xff1a; 包含Program code&#xff08;程序代码&#xff09;&#xff0c;这是用户编写的业务逻辑代码。经过Optimizer / Graph Builder&#xff08…

你还在用idea吗

从VIM、Emacs&#xff0c;到eclipse、Jetbrains, 再到VSCode&#xff0c;过去的三十年时间&#xff0c;出现了这三代IDE产品。现在属于AI的时代来了&#xff0c;最新一代的产品像Cursor、Windsurf&#xff0c;就在昨天&#xff0c;字节跳动发布了最新的IDE&#xff0c;就叫Trae…

Linux TCP 之 RTT 采集与 RTO 计算

我们来看看 Linux TCP 采集 RTT 的函数 tcp_rtt_estimator&#xff0c;看注释&#xff0c;充满了胶着。 但在那个谨慎的年代&#xff0c;这些意味着什么&#xff1f; RTT 最初仅用于 RTO 的计算而不是用于调速&#xff0c;RTO 的计算存在两个问题&#xff0c;如果过估&#x…

学习ASP.NET Core的身份认证(基于JwtBearer的身份认证9)

测试数据库中只有之前记录温湿度及烟雾值的表中数据较多&#xff0c;在该数据库中增加AppUser表&#xff0c;用于登录用户身份查询&#xff0c;数据库表如下所示&#xff1a;   项目中安装SqlSugarCore包&#xff0c;然后修改控制器类的登录函数及分页查询数据函数&#xff…

leetcode-75-颜色分类

文章目录 1. 归并排序2. 计数3. 按照题目要求&#xff0c;原地腾挪 给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums &#xff0c;原地 对它们进行排序&#xff0c;使得相同颜色的元素相邻&#xff0c;并按照红色、白色、蓝色顺序排列。 我们使用整数 0、 1 和 2 分别表…

html,css,js的粒子效果

这段代码实现了一个基于HTML5 Canvas的高级粒子效果&#xff0c;用户可以通过鼠标与粒子进行交互。下面是对代码的详细解析&#xff1a; HTML部分 使用<!DOCTYPE html>声明文档类型。<html>标签内包含了整个网页的内容。<head>部分定义了网页的标题&#x…

学习记录之原型,原型链

构造函数创建对象 Person和普通函数没有区别&#xff0c;之所以是构造函数在于它是通过new关键字调用的&#xff0c;p就是通过构造函数Person创建的实列对象 function Person(age, name) {this.age age;this.name name;}let p new Person(18, 张三);prototype prototype n…

go语言zero框架通过chromedp实现网页在线截图的设计与功能实现

在 GoZero 框架中实现网页在线截图的功能&#xff0c;可以通过集成 chromedp 库来控制 Chrome 浏览器进行截图。chromedp 是一个基于 Chrome DevTools 协议的 Go 包&#xff0c;可以用来在 Go 程序中模拟浏览器操作&#xff0c;如页面截图、DOM 操作、表单提交等。 下面是一个…

以 RFID 为钥,开启民兵装备管理的科技之门

民兵配备的武器及装备涵盖了各式武器、弹药及军事技术设备&#xff0c;其管理的优良直接决定了民兵的作战效能。鉴于民兵装备普遍面临老化、维护支援不充分等问题&#xff0c;迫切需要迅速建立完善的民兵装备管理新体系。这一转变将推动民兵装备由数量扩张转向质量提升&#xf…

电脑办公技巧之如何在 Word 文档中添加文字或图片水印

Microsoft Word是全球最广泛使用的文字处理软件之一&#xff0c;它为用户提供了丰富的编辑功能来美化和保护文档。其中&#xff0c;“水印”是一种特别有用的功能&#xff0c;它可以用于标识文档状态&#xff08;如“草稿”或“机密”&#xff09;、公司标志或是版权信息等。本…

llama-factory实战: 基于qwen2.5-7b 手把手实战 自定义数据集清洗 微调

基于qwen2.5 手把手实战 自定义数据集 微调&#xff08;llama-factory&#xff09; 准备工作1.数据集准备&#xff08;例:民法典.txt&#xff09;2.服务器准备&#xff08;阿里云 DSW 白嫖&#xff09;3.环境配置pip 升级模型下载微调助手 4.数据集处理脚本文件4.1文本分割(ber…

微透镜阵列精准全检,白光干涉3D自动量测方案提效70%

广泛应用的微透镜阵列 微透镜是一种常见的微光学元件&#xff0c;通过设计微透镜&#xff0c;可对入射光进行扩散、光束整形、光线均分、光学聚焦、集成成像等调制&#xff0c;进而实现许多传统光学元器件难以实现的特殊功能。 微透镜阵列&#xff08;Microlens Array&#x…

详解单片机学的是什么?(电子硬件)

大家好&#xff0c;我是山羊君Goat。 单片机&#xff0c;对于每一个硬件行业的从业者或者在校电子类专业的学生&#xff0c;相信对于这个名词都不陌生&#xff0c;但是掌没掌握就另说了。 那单片机到底学的是什么呢&#xff1f; 其实单片机在生活中就非常常见&#xff0c;目前…

基于Docker的Spark分布式集群

目录 1. 说明 2. 服务器规划 3. 步骤 3.1 要点 3.2 配置文件 3.2 访问Spark Master 4. 使用测试 5. 参考 1. 说明 以docker容器方式实现apache spark计算集群&#xff0c;能灵活的增减配置与worker数目。 2. 服务器规划 服务器 (1master, 3workers) ip开放端口备注ce…