「JavaScript深入」WebSocket:高效的双向实时通信技术
WebSocket
- WebSocket 的特点
- 1. 全双工通信
- 2. 持久连接
- 3. 低延迟
- 4. 二进制和文本支持
- 5. 连接管理
- 6. 二进制数据传输
- WebSocket 协议详解
- 1. 握手过程
- 2. 数据帧结构
- WebSocket 的实现
- 服务器端实现(Node.js + ws库)
- 1. 基础服务器
- 2. 广播功能实现
- 3. 心跳机制
- 客户端实现(HTML + JavaScript)
- 1. 基础用法
- 2. 断线重连
- 3. 二进制数据处理
- WebSocket 与 SSE 的比较
- WebSocket 的应用场景
- WebSocket优化实践
- 1. 性能优化
- 2. 安全防护
- 3. 监控与调试
- 未来发展趋势
- 总结
在现代 Web 开发中,实时通信是许多应用的核心需求,例如在线聊天、实时协作、游戏对战等。WebSocket 是一种基于 TCP 的全双工通信协议,它允许客户端和服务器之间建立持久连接,并在双方之间高效地传输数据。
上一节分享了 「Server-Sent Events (SSE):轻量级实时通信技术」
WebSocket 的特点
1. 全双工通信
WebSocket 允许客户端和服务器双向发送消息,适用于需要频繁交互的场景,如即时聊天、在线游戏等。
// 客户端发送消息
socket.send('Hello Server!');// 同时接收消息
socket.onmessage = (event) => {console.log('收到服务端消息:', event.data);
};
- 双向实时: 客户端和服务端可以同时发送和接收数据
2. 持久连接
WebSocket 连接一旦建立,将保持打开状态,避免了 HTTP 轮询带来的性能损耗。
3. 低延迟
由于 WebSocket 仅在初始握手时使用 HTTP,之后的数据传输采用轻量级的帧格式,减少了额外的 HTTP 请求开销,提高了实时性。
4. 二进制和文本支持
WebSocket 支持发送文本数据和二进制数据,使其适用于多种应用场景,如音视频流、文件传输等。
5. 连接管理
相比 SSE(Server-Sent Events)只能由服务器推送数据,WebSocket 允许双向通信,因此需要手动管理连接的建立、丢失和恢复。
6. 二进制数据传输
// 发送ArrayBuffer
const buffer = new ArrayBuffer(128);
socket.send(buffer);// 发送Blob数据
const blob = new Blob(['Hello']);
socket.send(blob);
-
原生支持: 无需编码转换,直接传输二进制数据
-
高效传输: 适合音视频流、文件传输等场景
-
类型灵活: 支持
ArrayBuffer、Blob、字符串等多种格式
WebSocket 协议详解
1. 握手过程
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Version: 13HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
-
协议升级: 通过
HTTP Upgrade机制切换到 WebSocket 协议 -
安全验证: 基于
Sec-WebSocket-Key的握手验证 -
状态码: 成功返回
101 Switching Protocols
2. 数据帧结构
-
帧类型: 文本帧(0x1)、二进制帧(0x2)、控制帧等
-
分片传输: 支持将大消息拆分为多个帧传输
-
掩码处理: 客户端到服务端的数据需进行掩码处理
WebSocket 的实现
服务器端实现(Node.js + ws库)
1. 基础服务器
const WebSocket = require('ws');
const server = new WebSocket.Server({ port: 8080 });server.on('connection', socket => {console.log('Client connected');// 监听客户端消息socket.on('message', message => {console.log('Received:', message);socket.send(`Echo: ${message}`); // 发送回执消息});// 监听连接关闭socket.on('close', () => {console.log('Client disconnected');});
});console.log('WebSocket server running on ws://localhost:8080');
2. 广播功能实现
// 向所有客户端广播消息
wss.clients.forEach((client) => {if (client.readyState === WebSocket.OPEN) {client.send('广播消息');}
});
3. 心跳机制
// 服务端心跳检测
setInterval(() => {wss.clients.forEach((ws) => {if (!ws.isAlive) return ws.terminate();ws.isAlive = false;ws.ping();});
}, 30000);ws.on('pong', () => {ws.isAlive = true;
});
客户端实现(HTML + JavaScript)
1. 基础用法
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>WebSocket Demo</title><script>document.addEventListener("DOMContentLoaded", function () {const socket = new WebSocket('ws://localhost:8080');// 连接成功socket.onopen = function() {console.log('WebSocket connection established');socket.send('Hello Server!');};// 收到消息socket.onmessage = function(event) {console.log('Received:', event.data);};// 连接关闭socket.onclose = function() {console.log('WebSocket connection closed');};});</script>
</head>
<body><h1>WebSocket Demo</h1><p>Check the console for messages.</p>
</body>
</html>
2. 断线重连
let reconnectAttempts = 0;
const maxReconnectAttempts = 5;function connect() {const socket = new WebSocket('wss://example.com/chat');socket.onclose = () => {if (reconnectAttempts < maxReconnectAttempts) {setTimeout(connect, Math.pow(2, reconnectAttempts) * 1000);reconnectAttempts++;}};
}
3. 二进制数据处理
// 接收ArrayBuffer
socket.binaryType = 'arraybuffer';
socket.onmessage = (event) => {const buffer = event.data;// 处理二进制数据
};// 发送二进制数据
const buffer = new ArrayBuffer(32);
socket.send(buffer);
WebSocket 与 SSE 的比较
| 特性 | WebSocket | SSE |
|---|---|---|
| 通信方式 | 双向通信 | 服务器到客户端单向推送 |
| 适用场景 | 聊天、游戏、实时协作 | 实时通知、日志更新、股票行情 |
| 连接管理 | 需手动管理重连 | 浏览器自动重连 |
| 数据格式 | 支持二进制和文本 | 仅支持文本 |
| 浏览器支持 | 现代浏览器均支持 | 现代浏览器均支持 |
WebSocket 的应用场景
- 即时通讯:WebSocket 非常适用于在线聊天、协作工具,如 Slack、微信 Web 版等【即时消息传递、在线状态更新、消息已读回执】。
- 在线游戏:多人在线游戏需要实时同步状态,WebSocket 由于其低延迟特性,是理想选择。
- 实时数据推送:股票、外汇等金融市场数据需要高频率推送,WebSocket 提供了高效的数据传输方式。
- 实时协作:如 Google Docs 这样的多人协作文档编辑工具,可使用 WebSocket 实现多个用户的实时同步【协同文档编辑、远程白板】。
- 物联网(IoT):WebSocket 可用于智能设备与服务器之间的通信,以实现远程监控和控制。
WebSocket优化实践
1. 性能优化
-
压缩扩展:启用
permessage-deflate压缩 -
连接池:合理管理 WebSocket 连接
-
负载均衡:使用支持 WebSocket 的负载均衡器
2. 安全防护
// 认证示例
wss.on('connection', (ws, req) => {const token = req.headers['sec-websocket-protocol'];if (!validateToken(token)) {ws.close(1008, '未授权访问');}
});
-
认证授权:通过子协议或自定义头进行身份验证
-
数据加密:强制使用wss(WebSocket Secure)
-
输入验证:严格校验客户端数据
3. 监控与调试
-
连接状态:实时监控连接数和消息吞吐量
-
错误日志:记录连接异常和错误信息
-
性能指标:跟踪消息延迟和资源使用情况
未来发展趋势
1. WebSocket over HTTP/3: 利用QUIC协议提升性能
2. WebTransport: 新一代实时通信协议
3. 边缘计算集成: 与CDN和边缘节点深度整合
4. 标准化扩展: 更丰富的子协议支持
总结
WebSocket 提供了一种高效、低延迟的双向通信方式,适用于各种需要实时交互的应用。相比于 SSE,它不仅支持服务器向客户端推送数据,还允许客户端主动发送数据,实现真正的实时双向通信。
如果你的应用涉及高频双向数据交换,如聊天、游戏或协作工具,WebSocket 是最佳选择!
相关文章:
「JavaScript深入」WebSocket:高效的双向实时通信技术
WebSocket WebSocket 的特点1. 全双工通信2. 持久连接3. 低延迟4. 二进制和文本支持5. 连接管理6. 二进制数据传输 WebSocket 协议详解1. 握手过程2. 数据帧结构 WebSocket 的实现服务器端实现(Node.js ws库)1. 基础服务器2. 广播功能实现3. 心跳机制客…...
C#从入门到精通(1)
目录 第一章 C#与VS介绍 第二章 第一个C#程序 (1)C#程序基本组成 1.命名空间 2.类 3.Main方法 4.注释 5.语句 6.标识符及关键字 (2)程序编写规范 1.代码编写规则 2.程序命名方法 3.元素命名规范 第三章 变量 &…...
配置阿里云yum源
配置阿里云yum源 修改默认的yum仓库,把原有的移动到创建的目录里(踢出国外的yum源) # 切换到/ect/yum.repos.d/目录下 cd /etc/yum.repos.d/ # 新建repo目录 mkdir repo # 把原有的移动到创建的目录里 mv ./*.repo ./repo/配置yum源 # 找到…...
头歌实训--Pandas合并数据集--第3关:案例:美国各州的统计数据
任务描述 本关为练习关卡,请按照编程要求完成任务,获取美国各州2010年的人口密度排名。 import pandas as pd import numpy as npdef task3():#********** Begin **********##读取三个csv文件pop pd.DataFrame(pd.read_csv("./step3/state-popula…...
仿“东方甄选”直播商城小程序运营平台
在公域直播流量红利趋于饱和、流量成本大幅攀升的当下,私域直播为企业开辟了新的流量聚集和转化渠道,特别是对于那些希望在私域流量领域取得突破的品牌商家来说,直播场景以其独特的高频互动氛围,相比其他运营方式,展现…...
CentOS 7.9 安装 Python 3.10 详细步骤及常见问题解决
一、环境准备与依赖安装 更新系统与开发工具 sudo yum update -y sudo yum groupinstall "Development Tools" -y sudo yum install -y zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel \ readline-devel tk-devel libffi-devel gdbm-devel db4-de…...
ORACLE 19.8版本数据库环境EXPDP导数据的报错处理
近期用户在做EXPDP导出时,报错异常termination终止;EXPDP本身是简单的功能并且这个环境也是经常做导出的,到底是什么原因导致了这个问题呢? 导出脚本报错: 分析导出日志,当时系统资源充足但是进程启动失败,…...
LabVIEW运动控制(二):EtherCAT运动控制器的多轴示教加工应用(下)
前面两节课程分别给大家介绍了“控制器连接、定时获取轴状态、轴坐标、控制器型号、轴参数设置、IO控制、Basic文件下载”(详情点击→LabVIEW运动控制(二):EtherCAT运动控制器的多轴示教加工应用(上)&#…...
Ubuntu Qt: no service found for - “org.qt-project.qt.mediaplayer“
1、前言 在一次项目过程中,因项目需求,需要将windows开发的Qt项目迁移到ubuntu系统中,且在某个功能项中需要播放音频,在windows系统中能够正常运行,但在ubuntu系统中却显示defaultServiceProvider::requestService(): …...
C++ 各种map对比
文章目录 特点比较1. std::map2. std::unordered_map3. std::multimap4. std::unordered_multimap5. hash_map(SGI STL 扩展) C 示例代码代码解释 特点比较 1. std::map 底层实现:基于红黑树(一种自平衡的二叉搜索树)…...
纯内网环境安装1Panel面板与商店应用
文章目录 前序准备开始联网机器配置1Panel配置安装所有离线需要的应用导出Docker镜像导出1Panel配置 离线机器配置安装1Panel覆盖配置导入容器镜像重建应用 关于Jar包的运行 前序 之前一篇文章讲解了如何在内网环境下安装1Panel并操作商店应用安装应用程序,但是在一…...
软件工程面试题(三)
1.简单介绍下java?Spring的AOP,IOC的讲述 对struts2的了解,1,2的比较 xml的了解 J2ee的webserviced的协议? Spring AOP:代理机制 Spring提供的自动代理机制 Spring的IoC来实组件之间的依赖关系注入, 使控制层及…...
【 C++】构造函数和成员函数
详细探讨 C 中的构造函数和成员函数(方法),并通过代码示例进行说明。 1. 构造函数 (Constructors) 目的: 构造函数是一种特殊的成员函数,其主要目的是在创建对象时初始化对象的数据成员。名称: 构造函数的…...
OpenCV计算摄影学(22)将输入的彩色图像转换为两种风格的铅笔素描效果函数pencilSketch()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 铅笔风格非写实线描图。 该函数通过图像处理技术将输入的彩色图像转换为两种风格的铅笔素描效果: dst1:炭笔效果的灰度图…...
Event driven agentic document workflows 笔记 - 1
1. 课程介绍 主题:与 LlamaIndex 合作构建的事件驱动代理文档工作流讲师:Laurie Voss(LlamaIndex 开发者关系副总裁) 2. 代理文档工作流简介 定义:基于代理的应用程序,用于自动化端到端文档处理工作流。…...
影响单模光纤耦合效率的分析
影响单模光纤耦合效率的因素 如果想使单模光纤的耦合效率最高,入射光束需要满足以下条件: (1)入射光束接近高斯光; (2)入射光束从光纤端面正入射; (3)入射…...
windows+ragflow+deepseek实战之一excel表查询
ragflows平台部署参考文章 Win10系统Docker+DeepSeek+ragflow搭建本地知识库 ragflow通过python实现参考这篇文章 ragflow通过python实现 文章目录 背景效果1、准备数据2、创建知识库3、上传数据并解析4、新建聊天助理5、测试会话背景 前面已经基于Win10系统Docker+DeepSeek+…...
从“不敢买大”到“按墙选屏”,海信电视如何凭百吋重构客厅?
电视买小了,成为茜茜新房入住后最大的遗憾。 新房装修的时候,茜茜担心电视买大了眼睛看着累,因此把尺寸选在了65吋。结果入住后,孩子看动画片嚷着“画面太小”,老公看球赛吐槽“看不清球员号码”,全家追剧…...
ABAP 长文本编辑器
加个屏幕 *&---------------------------------------------------------------------* *& Report YDEMO2 *&---------------------------------------------------------------------* *& *&---------------------------------------------------------…...
【K8S】ImagePullBackOff状态问题排查。
ImagePullBackOff 是在使用 Kubernetes(K8s)时经常遇到的一种错误状态,下面为你详细介绍其含义、可能的原因及解决办法。 含义 当你在 K8s 集群中创建一个 Pod 时,Kubelet 会尝试从指定的镜像仓库拉取所需的容器镜像。如果拉取镜…...
Logstash 使用指南
Logstash 是一个开源的数据收集引擎,能够从多种数据源收集数据,进行转换和过滤,并将数据发送到指定的目的地(如 Elasticsearch、文件、数据库等)。它是 Elastic Stack(ELK Stack)的重要组成部分…...
Python 位运算符大全
在 Python 中,位运算符用于对整数进行位级别的操作。位运算符直接操作二进制位,适用于处理二进制数据、位掩码、权限控制等场景。Python 提供了多种位运算符,包括按位与、按位或、按位异或、按位取反、左移和右移等。 1. 常见的位运算符 运算符描述示例&按位与a & b…...
MATLAB 调用arduino uno
为了授课,必须重新把arduino用上。 采用MATLAB编码,可以简化相关程序授课部分 1 安装包 MATLAB Support Package for Arduino Hardware - File Exchange - MATLAB Central (mathworks.com) 需要这个插件。 当然也可下载simulink的模块,但…...
Git——分布式版本控制工具使用教程
本文主要介绍两种版本控制工具——SVN和Git的概念,接着会讲到Git的安装,Git常用的命令,以及怎么在Vscode中使用Git。帮助新手小白快速上手Git。如果想直接上手用Vscode操作远程仓库则直接看7和9即可! 目录 1. SVN和Git介绍 1.1 …...
HarmonyOS 开发中条件渲染的选择:if/else 与取反操作的对比与实践
在HarmonyOS开发里,if/else 条件渲染和取反操作(常借助三元运算符)都能根据不同情况设置组件属性值。下面从多个维度分析如何选择,以及各自的利弊,并附上代码示例。 选择方法 简单二元条件:当条件只有两种…...
【数据分析】数据筛选与访问行列元素3
访问元素 .loc属性可以通过传入index的值访问行数据。 .loc属性允许传入两个参数,分别是index的值和columns的值,参数间用“逗号”隔开,这样便可以访问数据中的元素。 1. 访问单个元素 访问单个元素比较简单,只需要通过它的in…...
前沿技术一览科技改变生活新趋势
虚拟现实技术最近在教育里变得特别火。它能让人感觉像是真的到了另一个地方。比如学生戴上VR眼镜,就能“走进”历史事件的发生地或者深入细胞内部去了解生命科学。 这种学习方法能让知识更生动。学生不再只是看书听讲,而是可以亲手体验。比如在学习地理…...
Python连接数据库进行增删改查
更多优质文章 _>_>_>_>_>✍✈✉戳我 目录 1.导入相关库 2.创建连接 3.插入数据 4.删除数据 5.修改数据 6.查询数据 7.更多干货 1.导入相关库 import pymysql -----pip install pymysql #下载库 2.创建连接 conn pymysql.connect(hostlocalho…...
爬虫——playwright获取亚马逊数据
目录 playwright简介使用playwright初窥亚马逊安装playwright打开亚马逊页面 搞数据搜索修改bug数据获取翻页优化结构 简单保存 playwright简介 playwright是微软新出的一个测试工具,与selenium类似,不过与selenium比起来还是有其自身的优势的ÿ…...
大数据学习(77)-Hive详解
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言📝支持一…...
