WebSocket:实现实时互动、数据推送的利器,你了解多少

news2024/11/20 10:28:00

WebSocket技术是一种基于TCP协议的全双工通信协议,它允许浏览器和服务器之间进行实时、双向的通信。相比传统的HTTP请求-响应模式,WebSocket提供了持久连接,可以实时地推送数据,减少了通信的延迟。

WebSocket的工作原理是通过建立一条持久连接来实现实时通信。首先,浏览器和服务器进行一次标准的HTTP握手,建立连接。随后,连接升级为WebSocket协议,之后就可以在连接上发送和接收消息,实现双向通信。

WebSocket的应用非常广泛。以下是几个典型的应用场景:

即时通讯:WebSocket可用于实现聊天应用、在线客服系统等,用户可以实时地发送和接收消息。

实时数据展示:通过WebSocket可以实时地推送数据给前端,比如实时股票行情、实时天气更新等。

多人游戏:WebSocket可以实现多人在线游戏,玩家可以实时地进行交互、通信。

实时协作:比如实时协同编辑器,多个用户可以同时编辑一个文档,并实时地看到其他用户的操作。

数据监控:WebSocket可以用于实时监控系统的运行状态、日志更新等,便于及时发现和解决问题。

使用WebSocket技术也需要考虑一些方面:

浏览器和服务器的兼容性:不是所有浏览器都完全支持WebSocket,需要进行兼容性测试和处理,可能需要对不支持的浏览器使用其他技术(如轮询或长轮询)来进行实时通信。

负载均衡和扩展性:如果应用需要处理大量的并发连接,需要考虑负载均衡和扩展性,可以使用多个WebSocket服务器配合负载均衡器来实现。

总结起来,WebSocket技术提供了一种实时、双向通信的方式,适用于各种需要实时交互和实时数据推送的应用场景。它使得Web应用能够更加实时、高效地进行通信,提供了更好的用户体验。

虽然WebSocket只需要建立一次就可以让客户端和服务端建立起连接,但是因为是基于TCP协议构建的,所以本质上还是要进行三次握手。

TCP本身是持久连接,三次握手和四次挥手就不老调重弹了。而HTTP之所以是单向的,是因为规范规定了服务器只能响应请求,而不能主动发送数据。所以说WebSocket可以看做是HTTP的一个补丁

协议概览

WebSocket协议在游览器中的显示是这样的:

1942b58ae280ba6c58a73722971faef5.jpeg

我们可以看到不同于一般的请求,WebSocket URL前缀为ws,它告诉游览器自己不是HTTP请求,而是WebSocket请求,此时游览器便会自动对协议进行升级。

默认ws端口是80,wss端口是443。

wss就是通过TLS加密后的ws。

不同于一般的HTTP请求,WebSocket请求添加了几个字段来作为应用,主要的有:

Sec-WebSocket-Accept和Sec-WebSocket-Key:只有当Sec-WebSocket-Key的值经过固定算法加密后的数据和响应头里的Sec-WebSocket-Accept的值保持一致,该连接才会被认可建立,避免跨协议攻击。 Sec-WebSocket-Version:这个header字段的值必须为13,因为在它之前有很多测试的版本,比如9、10、11、12,这些版本现在都不被认为是有效的Sec-WebSocket-Version。 Sec-WebSocket-Extensions:该属性存储客户端的扩展,在连接建立时服务端可以针对该扩展进行处理。 Upgrade:告诉游览器该HTTP协议已经升级到了WebSocket。

当客户端对服务端发起WebSocket请求时,只有在当前连接已经建立的情况下才能再次建立连接(客户端会对剩下的连接进行排序)。因为WebSocket是长连接,所以客户端需要注意限制同一个主机的连接数量,避免脚本通过创建大量的WebSocket连接来进行DDOS攻击。如果客户端是通过代理访问服务的,那么客户端应该连接到那个代理并且通过这个代理去和服务端建立一个TCP连接。

在服务端接收客户端的WebSocket请求后,需要对该请求进行解析,获取它的Sec-WebSocket-Key、Sec-WebSocket-Version、Sec-WebSocket-Extensions,还有客户端的源地址、请求的资源名称等。当解析完成后,如果能与服务端连接,那么服务端将会返回给客户端一个响应,响应里面包含Sec-WebSocket-Accept,这是与客户端对接的标识符。

当客户端与服务端建立好连接后,两者就可以通信了:

0e702e2a83142250fd4518fdeaff36c9.jpeg

协议结构

WebSocket协议的全局结构大概如下所示,我们来大概解析一下它各个字段的含义:

d676310ce799c5fa9a39e998fe68a15a.jpeg

FIN:表示这是消息的最后一个字段(设置为1,默认为0)。

RESV1/RESV2/RESV3:标识是否有扩展协议,如果为1,那么在EXTEND PAYLOAD为0的情况下,就会断开WebSocket连接。

OPCODE:标识操作码,这是一个操作帧,用来指示WebSocket的动作。默认的标识码有:

%x0 :一个连续的消息分片 %x1 :一个文本类型的消息分片 %x2 :一个二进制类型的消息分片 %x3-7:预留给以后的数据帧 %x8 :一个关闭连接的指令 %x9 :一个ping包 %xA :一个pong包 %xB-F:预留给以后的控制帧

ping包和pong包是用来做心跳检测的。

MASK:标识数据是否有加掩码,如果设置为1,掩码键必须放在MASKING KEY区域。

PAYED LENGTH:传输的数据的长度(不包括MASKING-KEY)。

MASKING-KEY:掩码键。

PAYLOAD DATA:传输的数据(扩展数据EXTEND PAYLOAD+应用数据APPLICATION PAYLOAD)。

扩展数据:自己定义的扩展协议。 应用数据:基础的数据帧。 前端处理

HTML5封装好了处理方法,只需要调用其API就可以了。

直接创建一个WebSocket对象,然后将onopen\onclose等方法绑定到对象。

相关API可以查看MDN WEB——API WebSocket。

后端处理

用Netty的WebSocketServerProtocolHandler举例,当我们创建WebSocket服务时,必然要加入一个WebSocket协议的处理器,将其协议内容封装为一个便于使用的包装类,在Netty中,我们可以这样定制WebSocket服务:

23c4d6f7a2bda8848944a720442dbbf0.jpeg

进入WebSocketServerProtocolHandler类,可以看到它定义的属性有:

ad28314002e97446f430f971d2d860df.jpeg它两个方法有:

一个是handlerAdded,它会在Channel连接后回调,每次都会插入WebSocketServerProtocolHandshakeHandler。

774f84f2c85c86182da2742a12162cb2.jpeg

一个是decode,它会针对进行的数据帧进行操作。

621a3805861d2d187e1775cc023ed514.jpeg

在close前要进行frame.retain();,是因为在关闭时需要用到frame,在Netty的所有操作都是异步的情况下,这样就可以防止frame在没有用完时就被释放掉了。

来看下WebSocketServerProtocolHandshakeHandler.channelRead方法:

b8c79a41e04aa05a9835943e83031032.jpeg

在WebSocketServerProtocolHandshakeHandler.channelRead绑定触发事件时,为了保持兼容性,所以设置了两个,第一个是过时的,下面那个是新的。

对于通过握手器工厂WebSocketServerHandshakerFactory创建的WebSocketServerHandshaker,我们需要注意它的handshake方法。该方法其实就是来发送响应数据的。

它先把跟HTTP聚合,压缩的处理器移除,然后看有没有HttpRequestDecoder,如果没有,那就在前面添加WebSocket的编解码器。如果有HTTP编解码器,就把编解码器替换成WebSocket编解码器,等发送响应成功了,就移除掉HttpServerCodec或HttpResponseEncoder。

e1a2e32617401ee5810a27e3f1357ef8.jpeg

这样处理完之后,就把和HTTP编解码器移除出去了,这样的话就可以保证使用者即使添加了错误的处理器,程序也可以正常执行WebSocket连接。

总结

WebSocket协议用于长连接传输数据,本质也不过是定义了一种协议格式,然后往里面放数据。从功能上来说唯一和HTTP的区别就是客户端和服务端是可以相互推送消息的,而非被动。

之前说过HTTP 1.1添加了一个keep-alive请求头属性,可以作用于长连接。但是这里的长连接和WebSocket的长连接不同。keep-alive的作用是保持连接,可以让其它的HTTP请求可以复用这个通道,每次HTTP请求还是要携带请求头的。而WebSocket的长连接的每一个连接对应一个客户端。

一个很明显的比方就是打电话给客服。keep-alive的表示是一方讲完之后就把电话给了自己身后的人,然后身后的人跟客服反映新的问题。WebSocket表示一方讲完之后,听完客服的反馈就挂掉了电话,两人就断了联系。

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

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

相关文章

视觉Slam面试题(不定时更新)

文章目录 0 引言1 单目、双目、深度相机和RGBD相机的区别2 特征点法与直接法的优缺点3 等距变换、相似变换、仿射变换、射影变换的区别4 单应矩阵、本质矩阵和基础矩阵的区别5 Slam中为什么用李群李代数6 解释Slam中的绑架问题7 ORB、SIFT和SURF特征点检测算法的区别8 什么是对…

QGIS如何给元素添加属性

选中图层,右键,属性

汽车上的A/C按键是做什么用的?

汽车上的A/C按键是做什么用的? 汽车上的a/c 键是空调制冷开关。A/C是空调的缩写,它的全称是air condition,理解为空气调节。它通过空调压缩机的不同运转方式来达到制冷或制暖的目的。 打开a/c 按键之后,因为空调压缩机是靠发动机工作的&…

【小白专用】安装Apache2.4+ 安装PHP8.2+ php与sql server 2008 r2连接测试教程

PHP安装 1、PHP下载 PHP For Windows: Binaries and sources Releases 注意: 1.要下载Thread Safe,否则没有php7apache2_4.dll这个文件 2.如果是64位系统要下载x64的,x86的不行 3.下载Zip 2、PHP解压安装 将Zip进行解压,里…

【六、docker中hyperf项目怎么进行跨域设置】

1、第一步就是新建跨域文件,即跨域中间件 跨域中间件的代码如下 <?phpdeclare(strict_types=1);namespace App\Middleware; namespace App\Middleware; namespace App\Middleware;use Hyperf\Context\Context; use Psr\Http\Message\ResponseInterface;

Linux文件管理与用户管理

一、查看文件内容 1、回顾之前的命令 cat命令、tac命令、head命令、tail命令、扩展&#xff1a;tail -f动态查看一个文件的内容 2、more分屏显示文件内容&#xff08;了解&#xff09; 基本语法&#xff1a; # more 文件名称 特别注意&#xff1a;more命令在加载文件时并不…

爆肝整理,性能测试-非GUI模式执行Jemter压测,看这篇就够了...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、上传脚本 把在…

如何利用vscode进行断点调试后端node开发的项目,如express或koa?

介绍 在我们平常开发中前端可以通过浏览器断点调试代码执行的过程&#xff0c;但是node项目后端通常用命令启动&#xff0c;但命令启动项目也只能打印日志信息&#xff0c;不能断点。所以这一章节教大家如何利用vscode进行断点调试。 步骤 配置launch.json文件 代码如下&…

matlab奇技淫巧——绘制三维地图

在数据处理工作中&#xff0c;常常会用到地图的绘制&#xff0c;最常用的自然是绘制平面的区域/全球地图&#xff0c;通过 worldmap(world) % 创建世界地图坐标区域 load coastlines % 导入海岸线数据 plotm(coastlat,coastlon)即可绘制&#xff0c;效果…

【eNSP】VLAN间通信

VLAN间通信 文章目录 一、使用路由器物理接口实现VLAN间通信实验拓扑图1、配置交换机Access接口和路由器IP地址LSW1AR1 2、验证 二、使用路由器子接口实验拓扑图1、路由器、交换机基本配置LSW1AR1 2、配置路由器子接口AR1 3、验证 三、使用VLANIF技术实现VLAN间通信原理图实验拓…

vue3弹窗中循环生成表单的校验和重置问题

应用场景&#xff1a; 1、弹框里的表单是根据后台返回的时段生成的&#xff0c;后台返回几个时段&#xff0c;就渲染几组表单。 -1- 重置&#xff1a;遍历每个表单&#xff0c;获取当前表单的引用&#xff0c;在resetFields() -2- 校验&#xff1a;创建一个数组来存储每个表单的…

MySQL学习(五)——索引

文章目录 1. 索引介绍2. 索引结构2.1 索引结构介绍2.2 二叉树2.3 B-Tree2.4 BTree2.5 Hash 3. 索引分类3.1 索引分类3.2 聚集索引和二级索引 4 索引语法4.1 语法介绍4.2 数据准备4.3 索引演示 5 SQL 性能优化5.1 执行频率查询5.2 慢查询日志5.3 profile详情5.4 explain 6 索引使…

谈谈 Redis 如何来实现分布式锁

谈谈 Redis 如何来实现分布式锁 基于 setnx 可以实现&#xff0c;但是不是可重入的。 基于 Hash 数据类型 Lua脚本 可以实现可重入的分布式锁。 获取锁的 Lua 脚本&#xff1a; 释放锁的 Lua 脚本&#xff1a; 但是还是存在分布式问题&#xff0c;比如说&#xff0c;一个客…

金融信息化研究所与YashanDB等单位启动金融多主数据库应用行动计划

10月13日&#xff0c;2023金融业 数据库技术大会在京成功召开。会上&#xff0c;金融信息化研究所与崖山数据库YashanDB、阿里巴巴、奥星贝斯、达梦、南大通用、华为、天翼云、万里数据库、优炫数据库共同启动金融多主数据库应用行动计划&#xff0c;并成立金融多主数据库应用…

基于SpringBoot的大学生体质测试管理系统

基于SpringBoot的大学生体质测试管理系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBootMyBatisVue工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 主页 管理员界面 教师界面 学生界面 摘要 大学生体质测试管理系统是一…

谁懂?这23个关于大数据的灵魂拷问!

在企业内训行业也深耕蛮多年了&#xff0c;每次做大数据培训&#xff0c;都会遇到一些发人深省的灵魂拷问。 在这些拷问的人群中&#xff0c;有一些是没有接触过大数据平台&#xff0c;有一些甚至已经是大数据老兵。 那趁着这次机会&#xff0c;让我们索性一次把这些问题言简意…

maven依赖冲突以及解决方法

什么是依赖冲突 依赖冲突是指项目依赖的某一个jar包&#xff0c;有多个不同的版本&#xff0c;因而造成类包版本冲突 依赖冲突的原因 依赖冲突很经常是类包之间的间接依赖引起的。每个显式声明的类包都会依赖于一些其它的隐式类包&#xff0c;这些隐式的类包会被maven间接引…

竞赛 深度学习YOLO抽烟行为检测 - python opencv

文章目录 1 前言1 课题背景2 实现效果3 Yolov5算法3.1 简介3.2 相关技术 4 数据集处理及实验5 部分核心代码6 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于深度学习YOLO抽烟行为检测 该项目较为新颖&#xff0c;适合作为竞赛课…

Yaml语法学习

SpringBoot使用一个全局的配置文件 &#xff0c; 配置文件名称是固定的 application.properties&#xff08;官方不推荐&#xff09; 语法结构 &#xff1a; keyvalue application.yml 语法结构 &#xff1a;key&#xff1a;空格 value server:port: 8081 配置文件的作用 &…

jvm 各个版本支持的参数

知道一些 jvm 调优参数&#xff0c;但是没有找到官网对应的文档&#xff0c;在网上的一些文章偶然发现&#xff0c;记录一下。 https://docs.oracle.com/en/java/javase/ 包含各个版本 jdk 8 分为 windows 和 unix 系统 https://docs.oracle.com/javase/8/docs/technotes/too…