【学习心得】websocket协议简介并与http协议对比
一、轮询和长轮询
在websocket协议出现之前,要想实现服务器和客户端的双向持久通信采取的是Ajax轮询。它的原理是每隔一段时间客户端就给服务器发送请求找服务器要数据。
让我们通过一个生活化的比喻来解释轮询和长轮询假设你正在与一位不怎么主动说话的老大爷(服务器)聊天,你想要知道他是否有新的故事或者信息分享给你。
(1)轮询
就像每隔几分钟你就跑到老大爷家门前敲门,问他:“大爷,您有新消息吗?”每次老大爷如果没有新内容,就会回答:“没有呢,孩子。”然后你失望地离开,过一会儿再回来重复同样的问题。这种方式下,你消耗了大量的精力(客户端资源),而且由于间隔时间的存在,获取新消息的延迟较高,并且无论是否获得新消息,每次询问都会给老大爷带来打扰(服务器负担)。
为了改善这种需要反复请求浪费带宽资源的情况,人们发明了长轮询,顾名思义长轮询是只客户端只需要发起一个HTTP请求,服务器一直保持连接打开,直到有消息时才返回响应;客户端在收到响应后立刻发起下一个请求,以此实现近似实时推送的效果。
(2)长轮询
现在改为采用长轮询的方式。你来到老大爷家,站在门口问:“大爷,如果有新消息,请随时告诉我。”然后你就耐心地等待在那儿,老大爷如果没消息就不回应,一旦有了新消息,就立即告诉你。这样,你不再频繁地往返于老大爷家门口,而是保持一个“半开放”的聊天状态。尽管你在门口等待的时间可能较长(长连接维持期间消耗资源),但比起频繁询问,减少了无效交互,提高了发现新消息的速度,同时降低了对老大爷的打扰频率(减轻了服务器负载)。然而,这个过程中你仍然不能做其他事情(浏览器线程被占用),直到老大爷给出答复或超时为止。
二、websocket协议
websocket是一个在单个 TCP 连接上进行全双工通讯的协议。 websocket允许服务端主动向客户端推送数据。客户端和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
在实际的网络通信中,轮询和长轮询分别对应着客户端周期性地向服务器发送请求查询更新,以及客户端发起请求后保持连接打开等待服务器响应的机制。而websocket则更像是建立了一个实时通讯通道,你和老大爷之间架设了一部电话,只要有新消息,老大爷就能直接拨通你的电话进行通知,无需反复敲门询问。

三、websocket通信
(1)握手(第一次请求服务器)
在实际的websocket通信过程中,存在一个从HTTP协议升级到websocket协议的过程。这个过程通常称为WebSocket握手,它是通过一次特殊的HTTP请求来实现的。
当握手完成后,HTTP连接即被转换为WebSocket连接,之后双方就可以进行全双工、低延迟的数据传输了,不再使用HTTP报文格式,而是采用WebSocket帧结构进行数据封装和解封装。
(2)websocket的握手数据包长什么样的?

我们来看看数据包里面的请求头和响应头信息都是什么意思吧!重点关注红色的字段就行。
| 字段 | 解释 |
| GET wss://live-ws-group10.kuaishou.com/websocket HTTP/1.1 | HTTP GET方法的请求,请求的目标资源是wss://live-ws-group10.kuaishou.com/websocket。wss表示这是一个安全的WebSocket连接(基于TLS加密)。 |
| Host | 指定服务器的主机名和端口,用于确定目标服务地址。 |
| Connection: Upgrade | 表明客户端希望升级当前的HTTP连接为另一个协议,这里是指WebSocket协议。 |
| Pragma: no-cache | 告诉服务器不使用缓存机制,确保请求获取最新的数据。 |
| Cache-Control: no-cache | 同样用于控制缓存策略,禁止缓存此请求的响应内容。 |
| User-Agent | 描述客户端软件信息,这里是Chrome或Edge浏览器在Windows 10系统上的版本号。 |
| Upgrade: websocket | 明确指出要将连接升级到WebSocket协议。 |
| Origin | 标识本次WebSocket连接发起的源站点,这是同源策略中的一部分,用来说明请求是从哪个页面或者应用发起的。 |
| Sec-WebSocket-Version | 客户端支持的WebSocket协议版本号,13是RFC 6455定义的最新版本。 |
| Accept-Encoding | 客户端支持的编码压缩方式,包括gzip、deflate和br(Brotli)算法。 |
| Accept-Language | 客户端偏好使用的语言顺序,首先是简体中文,然后是其他英文变种。 |
| Sec-WebSocket-Key | 一个Base64编码的随机字符串,由客户端生成并发送给服务器,服务器需要根据这个值计算出一个回应摘要来完成WebSocket握手验证。 |
| Sec-WebSocket-Extensions | 客户端提议启用WebSocket扩展 |
(3)wss数据包对比https数据包
- http对应于ws,https对应于wss
- http包有Headers、preview、Response、Cookies

- websocket包有Headers、Messages


- http包是文本类型数据。
- websocket包是二进制数据。
- http包是我们客户端去触发,我们请求一个地址返回一个数据。
- websocket包是当我们客户端连接服务器后,一直接受服务器的数据并且要对不同的服务发送来的数据做出回应。
(4)服务器如何知道我们离开了?
服务器判断客户端是否还在保持通信有很多方式,这里重点讲一个方式——心跳包(Heartbeat)
为了保持WebSocket连接的活跃并确保客户端仍然在线,客户端和服务器之间会定期交换“心跳”消息。如果服务器在一段时间内没有收到客户端发送的心跳消息,则可以认为客户端已经离线或者连接已断开。反过来,服务器也可以主动向客户端发送心跳消息,等待客户端确认回复。如果没有收到回复,则视为客户端已断开连接。
还是拿上面我和老大也聊天的例子:在WebSocket通信场景中,我(客户端)和老大爷(服务器)之间建立了持久的聊天管道。为了防止因为网络波动、设备休眠或其他原因导致的连接无声无息地断开,我和大爷商定了一项规则:每过一定时间,比如15秒,我就向老大爷发送一个简短的消息,例如“我还在线呢”。
-
客户端发送心跳包: 就像我在规定的时间间隔内走到老大爷面前说一声:“嘿,大爷,我还在。”(在这个例子中,“嘿,大爷,我还在。”就相当于心跳包的内容,它有一个专门的名字叫ACK确认字符,表示发来的数据已确认接收无误)
-
服务器响应心跳包: 老大爷听到你的问候后,通常会回复你一个确认信息,如:“收到,孩子,我知道了。”这样,你就能知道老大爷还清醒着,并且你们的沟通渠道依然畅通。
如果某次或连续几次心跳周期过后,老大爷没有回应我的问候,那么我可以推断出可能是老大爷暂时走开了(服务器故障),或者我喊的声音太小他没听见(网络问题),于是我可以采取行动,比如重新建立连接或是通知用户连接已断开。
五、参考资料
(1)如果你想了解更多有关websocket和http协议的细节,我推荐你去mdn的官网学习:
MDN中文官网
https://developer.mozilla.org/zh-CN/docs/Learn
(2)如果你只是想快速入门websocket协议,那么看我这篇文章其实就够了,但除此之外菜鸟教程也是非常不错的新手必看网站:
菜鸟教程-websocket协议
https://www.runoob.com/html/html5-websocket.html
(3)还有关于websocket的属性、事件和方法后续会再出一篇文章结合Python来给大家介绍哦!
【学习心得】Python好库推荐——websocket-client
http://t.csdnimg.cn/Qdk1W
相关文章:
【学习心得】websocket协议简介并与http协议对比
一、轮询和长轮询 在websocket协议出现之前,要想实现服务器和客户端的双向持久通信采取的是Ajax轮询。它的原理是每隔一段时间客户端就给服务器发送请求找服务器要数据。 让我们通过一个生活化的比喻来解释轮询和长轮询假设你正在与一位不怎么主动说话的老大爷&…...
基于Token的身份验证:安全与效率的结合
🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…...
Electron程序如何在MacOS下获取相册访问权限
1.通过entitiment.plist,在electron-builder签名打包时,给app包打上签名。最后可以通过codesign命令进行验证。 TestPhotos.plist electron-builder配置文件中加上刚刚的plist文件。 通过codesign命令验证,若出现这个,则说明成…...
uniapp让输入框保持聚焦状态,不会失去焦点
使用场景:当输入框还有发送按钮的时候,点击发送希望软键盘不消失,还可以继续输入,或者避免因输入图片标签造成的屏闪问题 多次尝试后发现一个很实用的方法,适用input输入框和editor输入框 解决办法:把cli…...
面试中如何介绍mysql的B+树
B树是B树的变体,也是一颗多路搜索树。在MySQL中,B树是为磁盘或者其他直接辅助存储设备所设计的一种平衡的查找树结构。其具有以下特点: 每个节点最多有m个子女,m阶的B树深度最多为m。非根节点关键值个数范围是⌈m/2⌉-1<k<m…...
【Linux C | 网络编程】多播的概念、多播地址、UDP实现多播的C语言例子
😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀 🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C、数据结构、音视频🍭 🤣本文内容🤣&a…...
AIGC实战——GPT(Generative Pre-trained Transformer)
AIGC实战——GPT 0. 前言1. GPT 简介2. 葡萄酒评论数据集3. 注意力机制3.1 查询、键和值3.2 多头注意力3.3 因果掩码 4. Transformer4.1 Transformer 块4.2 位置编码 5. 训练GPT6. GPT 分析6.1 生成文本6.2 注意力分数 小结系列链接 0. 前言 注意力机制能够用于构建先进的文本…...
微信小程序-入门
一.通过 Npm方式下载构建 1.下载和安装Npm:Npm https://docs.npmjs.com/downloading-and-installing-node-js-and-npm 或者 https://nodejs.org/en/download/ 未安装npm 提示 以下以安装node安装包为例 按任意键继续 安装完成后 2. 下载和安装小程序开…...
0102全排列和对换-行列式-线性代数
把n个不同的数排成一列,叫做这n个数的全排列(排列)。 一般情况, 1 , 2 , ⋯ , n 1,2,\cdots,n 1,2,⋯,n是n个数排列的标准次序。 当n个数的任一排列中两个数的先后次序与标准次序不同时,有说有一个逆序。 一个排列中所…...
面向对象的编程语言是什么意思?——跟老吕学Python编程
面向对象的编程语言是什么意思?——跟老吕学Python编程 面向对象是什么意思?面向对象的定义面向对象的早期发展面向对象的背景1.审视问题域的视角2.抽象级别3.封装体4.可重用性 面向对象的特征面向对象的开发方法面向对象程序设计基本思想实现 面向对象的…...
Spring Boot整合MyBatis Plus配置多数据源
Spring Boot 专栏:https://blog.csdn.net/dkbnull/category_9278145.html Spring Cloud 专栏:https://blog.csdn.net/dkbnull/category_9287932.html GitHub:https://github.com/dkbnull/SpringBootDemo Gitee:https://gitee.com/…...
Unix Network Programming Episode 88
‘inetd’ Daemon On a typical Unix system, there could be many servers in existence, just waiting for a client request to arrive. Examples are FTP, Telnet, Rlogin, TFTP, and so on. With systems before 4.3BSD, each of these services had a process associate…...
Java面试题之11MySQL
你对MySQL执行计划怎么看 执行计划就是SQL的执行查询的顺序,以及如何使用索引查询,返回的结果集的行数 在MySQL中,我们可以通过explain命令来查看执行计划。其语法如下: EXPLAIN SELECT * FROM table_name WHERE conditions;在…...
R语言:多值提取到点
ArcGIS中有相关工具实现多值提取到点的功能,在这里,我将使用R语言进行操作: library(dplyr) library(readxl) library(sf) library(raster)setwd("D:/Datasets") Bio <- stack(paste0("D:/Datasets/Data/worldclim2_1km/…...
八股文打卡day27——数据库(4)
面试题:讲一下事务的隔离级别? 我的回答: 因为事务之间的隔离性,造成了一些问题,比如说:脏读、不可重复读和幻读(虚读)。 1.什么叫脏读? 就是一个事务读取到了另一个事…...
Java桥接模式源码剖析及使用场景
目录 一、介绍二、项目管理系统中使用桥接模式三、权限管理中使用桥接模式四、Java JDBC中使用桥接模式 一、介绍 它的主要目的是将抽象化与实现化分离,使得二者可以独立变化,就像一个桥,将两个变化维度连接起来。各个维度都可以独立的变化。…...
【异常处理】verilator安装时出现异常 make: *** [Makefile:195: verilator_gantt.1] Error 13
在ubuntu中安装verilator工具时执行make出现该报错。 当我出现这个报错的时候我一脸懵逼,因为网上找不到相关解决办法。 后来想到我的verilator是从github上下载zip,然后解压后传到ubuntu上的,windows上解压我记得会把-替换成_,这…...
测试一下 Anthropic 宣称超过 GPT-4 的 Claude 3 Opus
测试一下 Anthropic 宣称超过 GPT-4 的 Claude 3 Opus 0. 引言1. 测试 Claude 3 Opus3. 试用 api key 限制 0. 引言 今天测试一下 Anthropic 发布的 Claude 3 Opus。 3月4日,Anthropic 宣布推出 Claude 3 型号系列,该系列在广泛的认知任务中树立了新的…...
【题解】—— LeetCode一周小结10
【题解】—— 每日一道题目栏 上接:【题解】—— LeetCode一周小结9 4.用栈实现队列 题目链接:232. 用栈实现队列 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):…...
Android studio虚拟调试出现“我的APP keeps stopping”问题
问题如图: 遇到这种情况,一看代码,也没有报错呀,怎么不能运行呢?不要慌!我们一步一步来。 1、查看Logcat日志 在Android Studio中查看Logcat窗口,可以获取应用程序崩溃时的详细错误信息&…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...
基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...
c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...
HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...
