websocket的工作原理

WebSocket 是一种在 Web 应用程序中实现全双工通信的协议。它允许客户端和服务器之间建立一个持久的连接,双方可以在这个连接上相互发送数据,而不需要通过传统的 HTTP 请求/响应模式。这使得 WebSocket 特别适用于实时应用,如聊天应用、在线游戏、实时数据推送等。以下是 WebSocket 的工作原理的详细说明。

WebSocket 的工作原理

1. 建立连接

WebSocket 连接的建立从一个 HTTP 请求开始。客户端通过一个 HTTP 请求(通常称为 "握手" 请求)请求升级协议,从 HTTP 升级到 WebSocket。

客户端请求:

 

http复制代码

GET /chat HTTP/1.1 Host: example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw== Sec-WebSocket-Protocol: chat, superchat Sec-WebSocket-Version: 13 Origin: http://example.com

  • Upgrade: websocket 和 Connection: Upgrade 标头表示客户端请求升级到 WebSocket 协议。
  • Sec-WebSocket-Key 是一个 Base64 编码的随机密钥,用于安全验证。

服务器响应:

 

http复制代码

HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk= Sec-WebSocket-Protocol: chat

  • 状态码 101 Switching Protocols 表示服务器同意协议升级。
  • Sec-WebSocket-Accept 是服务器基于 Sec-WebSocket-Key 计算的一个值,确保握手请求的合法性。
2. 数据传输

一旦连接建立,客户端和服务器之间的通信使用 WebSocket 帧(frame)。WebSocket 帧有不同的类型,包括文本帧、二进制帧、关闭帧、Ping 帧和 Pong 帧。

  • 文本帧(Text Frame):用于传输文本数据(UTF-8 编码字符串)。
  • 二进制帧(Binary Frame):用于传输二进制数据。
  • 关闭帧(Close Frame):用于关闭连接。
  • Ping 帧和 Pong 帧:用于连接的心跳检测,维持连接的活跃状态。

每个 WebSocket 帧都有一个固定的头部格式,用于控制帧的类型和传输的负载数据。

3. 关闭连接

WebSocket 连接可以由客户端或服务器任意一方关闭。关闭连接的过程通过发送一个关闭帧来实现,另一方收到关闭帧后会响应一个关闭帧并关闭连接。

 

http复制代码

// 客户端或服务器发送关闭帧 0x88 0x00

关闭帧的第一个字节 0x88 表示帧的类型为关闭帧,第二个字节 0x00 表示负载长度为 0。

WebSocket 的优点

  1. 全双工通信:客户端和服务器可以在同一个连接上同时发送和接收消息,减少延迟。
  2. 持久连接:连接一旦建立,可以持续存在,避免了 HTTP 请求/响应的开销。
  3. 减少带宽消耗:由于减少了 HTTP 头部的开销,WebSocket 比传统的轮询和长轮询更高效。

WebSocket 的使用

客户端代码示例(JavaScript)
 

javascript复制代码

// 创建 WebSocket 连接 var socket = new WebSocket("ws://example.com/socket"); // 连接打开事件 socket.onopen = function(event) { console.log("WebSocket is open now."); // 发送数据 socket.send("Hello Server!"); }; // 接收消息事件 socket.onmessage = function(event) { console.log("Received message from server:", event.data); }; // 连接关闭事件 socket.onclose = function(event) { console.log("WebSocket is closed now."); }; // 连接错误事件 socket.onerror = function(error) { console.log("WebSocket error:", error); };

服务器代码示例(Node.js + ws 库)
 

javascript复制代码

const WebSocket = require('ws'); // 创建 WebSocket 服务器 const wss = new WebSocket.Server({ port: 8080 }); wss.on('connection', function connection(ws) { console.log('A new client connected'); // 接收消息事件 ws.on('message', function incoming(message) { console.log('Received message:', message); // 发送消息给客户端 ws.send('Hello from server'); }); // 连接关闭事件 ws.on('close', function close() { console.log('Client disconnected'); }); });

WebSocket 协议的详细解析

WebSocket 帧格式

WebSocket 帧头部格式如下:

 

复制代码

0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-------+-+-------------+-------------------------------+ |F|R|R|R| opcode|M| Payload len | Extended payload length | |I|S|S|S| (4) |A| (7) | (16/64) | |N|V|V|V| |S| | (if payload len==126/127) | | |1|2|3| |K| | | +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - + | Extended payload length continued, if payload len == 127 | + - - - - - - - - - - - - - - - +-------------------------------+ | |Masking-key, if MASK set to 1 | +-------------------------------+-------------------------------+ | Masking-key (continued) | Payload Data | +-------------------------------- - - - - - - - - - - - - - - - + : Payload Data continued ... : + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + | Payload Data continued ... | +---------------------------------------------------------------+

  • FIN (1 bit): 表示是否是消息的最后一帧。
  • RSV1, RSV2, RSV3 (1 bit each): 保留位,通常为 0。
  • Opcode (4 bits): 表示帧的类型(如文本帧、二进制帧、关闭帧等)。
  • MASK (1 bit): 表示是否掩码(客户端发送给服务器的数据必须使用掩码)。
  • Payload len (7 bits): 表示负载数据的长度,如果值为 126 或 127,则使用扩展的负载长度字段。
  • Extended payload length (16/64 bits): 当负载长度大于 125 时使用此字段。
  • Masking-key (32 bits): 如果 MASK 设置为 1,则此字段用于解码负载数据。
  • Payload Data: 实际传输的数据。

总结

WebSocket 提供了一种在客户端和服务器之间进行实时通信的高效方法。通过一次握手请求,WebSocket 可以建立一个持久的、全双工的通信连接,减少了频繁建立和关闭连接的开销。理解其工作原理和帧格式有助于在应用中更好地使用和调试 WebSocket,从而实现高效的实时通信。

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

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

相关文章

pytorch中的contiguous()

官方文档:https://pytorch.org/docs/stable/generated/torch.Tensor.contiguous.html 其描述contiguous为: Returns a contiguous in memory tensor containing the same data as self tensor. If self tensor is already in the specified memory forma…

自然语言处理与Transformer模型:革新语言理解的新时代

引言 自然语言处理(NLP)是人工智能和计算机科学的一个重要分支,旨在使计算机能够理解、生成和处理人类语言。随着互联网和数字化信息的爆炸性增长,NLP在许多领域中的应用变得越来越重要,包括: 搜索引擎&am…

domain 和 特征之间的关系

在计算机学术届,通常说的domain是什么意思? 例子1:在数学和函数的语境中,“domain” 通常指的是函数的定义域,即函数可以接受的输入值的集合。 假设这个时候定义域是{1,3,4,6,7,8,9,55},那么定义域里面的…

配置下载 docker镜像 playedu开源 最佳实践部署

下载docker-compose docker-ce https://github.com/docker/compose/tagswget https://github.com/docker/compose/releases/download/v2.28.0/docker-compose-linux-x86_64sudo chmod x /usr/local/bin/docker-compose下载docker镜像 国内加速地址 目前仍可用的镜像(随时可能失…

Python实现PowerPoint演示文稿到图片的批量转换

PowerPoint演示文稿作为展示创意、分享知识和表达观点的重要工具,被广泛应用于教育、商务汇报及个人项目展示等领域。 然而,面对不同的分享场景与接收者需求,有时需要我们将PPT内容以图片形式保存与传播。这样能够避免软件兼容性的限制&…

OpenEuler 22.03 LTS SP3 CVE-2024-6387 OpenSSH 漏洞修复指南

一、漏洞概括 漏洞名称OpenSSH Server远程代码执行漏洞漏洞编号CVE-2024-6387公开时间2024-7-1CVSS 3.1分数8.1威胁类型代码执行漏洞等级暂无技术细节状态已公开在野利用状态不明确PoC状态x86已公开EXP状态未公开 OpenSSH是SSH(Secure Shell)协议的开源…

腾讯课堂即将停止服务?来试试这款开源的知识付费系统

项目介绍 本系统基于ThinkPhp5.0layuiVue开发,功能包含在线直播、付费视频、付费音频、付费阅读、会员系统、分销系统、拼团活动、直播带货、直播打赏、商城系统等。能够快速积累客户、会员数据分析、智能转化客户、有效提高销售、吸引流量、网络营销、品牌推广的一款应用&…

客观分析-自己和本科学生之间的差距

进入专科学校和与985、211等重点本科院校学生之间的差距可能由多种因素造成,这些因素可能包括但不限于: 1. **入学标准**: 985和211工程院校通常有更高的入学标准和更严格的选拔过程。 你得使你自己适应更高的入学标准和更严格的选拔过程&am…

python运行bat命令

python运行bat命令 1、在Python中运行BAT命令,可以使用内置的subprocess模块。以下是一个简单的例子,展示如何运行一个BAT文件。 import subprocess# 假设你有一个名为script.bat的BAT文件 bat_file script.bat# 使用subprocess.run来运行BAT文件 res…

7、实体和值对象:领域模型的基础单元

DDD战术设计中有两个重要的概念:实体(Entity)和值对象(Value Object)。二者是领域模型中非常重要的基础领域对象(Domain Object,DO)。 从DDD战略设计到战术设计会经历从业务建模到技…

【Git 学习笔记】gitk 命令与 git log 其他参数的使用

1.7 用 gitk 查看提交历史 # make sure you have gitk installed $ which gitk /usr/bin/gitk # Sync the commit ID $ git checkout master && git reset --hard 13dcad # bring up the gitk interface, --all to see everything $ gitk --all &实测结果&#xf…

为什么salesforce需要设置社区端,而不是使用和内部员工同样的环境

虽然企业可能希望为客户和合作伙伴提供与内部员工相同的环境,但实际上这样做有几个显著的缺点和风险。这些包括: 安全性和权限管理:内部员工的系统通常包含敏感和机密的信息,例如财务数据、内部策略和未发布的产品信息。将客户和合…

速速来get新妙招!苹果手机护眼模式在哪里开启

在日常生活中,我们经常长时间使用手机,无论是工作还是娱乐,屏幕的蓝光都会对眼睛造成一定的伤害。为了减轻眼睛疲劳,苹果手机推出了护眼模式,也叫“夜览”模式,通过调整屏幕色温,让显示效果更温…

MySQL 8.0 架构 之 中继日志(Relay log)

文章目录 MySQL 8.0 架构 之 中继日志(Relay log)中继日志(Relay log)概述相关参数参考 【声明】文章仅供学习交流,观点代表个人,与任何公司无关。 来源|WaltSQL和数据库技术(ID:SQLplusDB) MySQL 8.0 OCP …

PyTorch - 神经网络基础

神经网络的主要原理包括一组基本元素,即人工神经元或感知器。它包括几个基本输入,例如 x1、x2… xn ,如果总和大于激活电位,则会产生二进制输出。 样本神经元的示意图如下所述。 产生的输出可以被认为是具有激活电位或偏差的加权…

四、(3)补充beautifulsoup、re正则表达式、标签解析

四、(3)补充beautifulsoup、re正则表达式、标签解析 beautifulsoupre正则表达式正则提取标签解析 beautifulsoup 补充关于解析的知识 还需要看爬虫课件 如何定位文本或者标签,是整个爬虫中非常重要的能力 无论find_all(&#xff…

Spring启动时,将SpringContext设置到Util中(SpringContextUtil)

场景 在Spring应用开发中,为简化代码或者在静态方法中获取Spring应用的上下文,需要把SpringContext设置到类属性上。经过对源码的分析和实践,使用Spring的事件监听器监听ApplicationPreparedEvent事件是最佳的方式。 通过ApplicationPrepar…

matrixone集群搭建、启停、高可用扩缩容和连接数据库

1. 部署 Kubernetes 集群 由于 MatrixOne 的分布式部署依赖于 Kubernetes 集群,因此我们需要一个 Kubernetes 集群。本篇文章将指导你通过使用 Kuboard-Spray 的方式搭建一个 Kubernetes 集群。 准备集群环境 对于集群环境,需要做如下准备&#xff1a…

mysql在windows下的安装

一,软件安装 只修改开头的系统盘 二,环境变量配置 找到MySQL安装目录对应的bin目录复制路径粘贴过来 三,cmd

SSL/CA 证书及其相关证书文件解析

在当今数字化的时代,网络安全变得至关重要。SSL(Secure Socket Layer)证书和CA(Certificate Authority)证书作为保护网络通信安全的重要工具,发挥着关键作用。 一、SSL证书 SSL证书是数字证书的一种&…