「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);
  • 原生支持: 无需编码转换,直接传输二进制数据

  • 高效传输: 适合音视频流、文件传输等场景

  • 类型灵活: 支持 ArrayBufferBlob、字符串等多种格式


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 的比较

特性WebSocketSSE
通信方式双向通信服务器到客户端单向推送
适用场景聊天、游戏、实时协作实时通知、日志更新、股票行情
连接管理需手动管理重连浏览器自动重连
数据格式支持二进制和文本仅支持文本
浏览器支持现代浏览器均支持现代浏览器均支持

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 是最佳选择!

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

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

相关文章

ABAP 长文本编辑器

加个屏幕 *&---------------------------------------------------------------------* *& Report YDEMO2 *&---------------------------------------------------------------------* *& *&---------------------------------------------------------…

postman小白教程(从入门到实战,详细教学)

目录 1. postman介绍 2. 下载地址 3. 安装流程 4. 注册postman账号 ① 打开postman&#xff0c;点击【创建账号】或【登录】&#xff0c;会跳转到浏览器 ② 若已有账号可以直接登录&#xff1b;若无账号&#xff0c;则创建新账号 ③ 若登录成功会弹出提示框&#xff0c;…

Qt 实现波浪填充的圆形进度显示

话不多说&#xff0c;先上效果图 代码示例&#xff1a; #include <QApplication> #include <QWidget> #include <QPainter> #include <QPropertyAnimation> #include <QTimer> #include <cmath>class WaveProgressBar : public QWidget {…

Linux vim mode | raw / cooked

注&#xff1a;机翻&#xff0c;未校。 vim terminal “raw” mode Vim 终端 “raw” 模式 1. 原始模式与已处理模式的区别 We know vim puts the terminal in “raw” mode where it receives keystrokes as they are typed, opposed to “cooked” mode where the command…

docker部署dify

1.安装docker 参考链接 https://ascendking.blog.csdn.net/article/details/136407383 设置docker源 vim /etc/docker/daemon.json {"registry-mirrors": ["https://docker.registry.cyou", "https://docker-cf.registry.cyou", "http…

Python Seaborn面试题及参考答案

目录 如何用 stripplot () 绘制带随机偏移的分类散点图?如何控制 jitter 参数? swarmplot () 如何避免散点重叠?适用场景与数据量限制是什么? 使用 catplot () 绘制箱线图时,如何通过 kind 参数切换图表类型? 如何通过 hue 参数在分类图中添加第三个维度(如性别)? …

Linux应用:Linux的信号

什么是信号 信号是一种软件中断&#xff0c;用于通知进程系统中发生了某种特定事件。它是操作系统与进程之间&#xff0c;以及进程与进程之间进行异步通信的一种方式。在 Linux 系统中&#xff0c;信号是一种比较简单的进程间通信机制。当一个信号产生时&#xff0c;内核会通过…

实时监控、数据分析!Web-Check构建你的网站健康检测系统实操方案

文章目录 前言1.关于Web-Check2.功能特点3.安装Docker4.创建并启动Web-Check容器5.本地访问测试6.公网远程访问本地Web-Check7.内网穿透工具安装8.创建远程连接公网地址9.使用固定公网地址远程访问 前言 在数字化运维领域&#xff0c;网站稳定性保障始终是开发者和运维团队的核…

win32汇编环境,网络编程入门之八

;在上一教程里&#xff0c;我们学习了简单的处理服务器返回的数据 ;在这一教程里&#xff0c;我们了解一下&#xff0c;当连接上网站后&#xff0c;应该发送什么数据过去的问题 ;这里有个简单的方式学习&#xff0c;以下是一个示例 ;我们上网的时候可以用谷歌浏览器&#xff0c…

windows 平台编译openssl

文章目录 准备环境安装perl安装NASM获取源码 源码编译配置编译 准备环境 安装perl 下载Perl 5.40.0.1 Portable zip strawberryperl 解压后设置系统环境变量 测试安装是否成功 perl --versionThis is perl 5, version 40, subversion 0 (v5.40.0) built for MSWin32-x64-m…

一文了解ThreadLocal

什么是ThreadLocal&#xff1f; ThreadLocal是每个线程私有的&#xff0c;线程可以把自己的私有数据放到ThreadLocal里面&#xff0c;不用担心其他线程访问到自己ThreadLocal。 通过set()方法将值存入ThreadLocal或者修改值&#xff0c;get()方法取出值&#xff0c;remove()方…

OpenWrt开发第6篇:怎么添加OpenWrt的Package-基于Raspberry Pi 4B开发板

文/指尖动听知识库-谷谷 文章为付费内容,商业行为,禁止私自转载及抄袭,违者必究!!! 文章专栏:Openwrt开发-基于Raspberry Pi 4B开发板 1.如图1所示,首先创建软件包所在的目录,在openwrt根目录中执行mkdir -p package/mypackages/helloworld命令;

常⻅CMS漏洞之一:WordPress

WordPress是⼀个以PHP和MySQL为平台的⾃由开源的博客软件和内容管理系统。WordPress具有插件架构和模板系统。截⾄2018年4⽉&#xff0c;排名前1000万的⽹站中超过30.6%使⽤WordPress。 WordPress是最受欢迎的⽹站 内容管理系统。全球有⼤约30%的⽹站(7亿5000个)都是使⽤WordP…

【第17节】windows sdk编程:线程与线程调度

目录 一、线程 1.1 线程的基本概念 1.2 何时创建线程 二、线程控制 三、遍历线程 四、线程内核对象 4.1 线程上下文 4.2 暂停次数 4.3 信号 五、线程调度 5.1 什么是线程优先级 5.2 进程优先级与相对线程优先级 5.3 编程改变优先级 5.4 动态优先级的概念 一、线程…

Python数据可视化实战:从基础图表到高级分析

Python数据可视化实战&#xff1a;从基础图表到高级分析 数据可视化是数据分析的重要环节&#xff0c;通过直观的图表可以快速洞察数据规律。本文将通过5个实际案例&#xff0c;手把手教你使用Python的Matplotlib库完成各类数据可视化任务&#xff0c;涵盖条形图、堆积面积图、…

【机器学习-分类算法】

比如将一张图片按尺寸识别分类为横向或者纵向两类就是二分类问题 设x轴为图像的宽、y轴为图像的高&#xff0c;那么把训练数据展现在图上就是这样的: 若增加更多的数据集有: 如果只用一条线将图中白色的点和黑色的点分开,那么: 分类的目的就是找到这条线,就可以根据点在线…

Compose Indication:点击效果设置

Compose Indication&#xff1a;打造独特点击效果的秘密武器 在Compose开发中&#xff0c;大家可能都碰到过Indication&#xff0c;不少人第一次接触它&#xff0c;是在想去掉Material默认的点击水波纹效果的时候。要是在AI工具里搜“怎么去掉水波纹效果”&#xff0c;会得到这…

Docker build 会在本地产生巨大的文件

Docker build 会在本地产生巨大的文件&#xff0c; 比如 用 这个命令列出本地镜像 docker images 可见size都是很大的&#xff0c; 到docker目录下&#xff0c;看到ext4.vhdx的大小 80多G 那只能用这个命令把不用的镜像删掉了&#xff1a; &#xff08;rmi后面是镜像id&a…

台式机电脑组装---电脑机箱与主板接线

台式机电脑组装—电脑机箱与主板接线 1、机箱连接主板的跳线一般主要有USB 2.0、USB 3.0、前置音频接口(HD_AUDIO)以及POWER SW、RESET SW、POWER LED、HDD LED四个主板跳线&#xff0c;这些跳线分别的含义如下。 RESET SW&#xff1a;机箱重启按键&#xff1b;注&#xff1a…

【虚幻引擎UE5】SpawnActor生成Character实例不执行AI Move To,未初始化AIController的原因和解决方法

虚幻引擎版本&#xff1a;5.5.4 问题描述 刚创建的Third Person项目里&#xff0c;定义一个BP_Enemy蓝图&#xff0c;拖拽到场景中产生的实例会追随玩家&#xff0c;但SpawnActor产生的实例会固定不动。BP_Enemy蓝图具体设计如下&#xff1a; BP_Enemy的Event Graph ​​ 又定义…