图解WebSocket

csdntup

👏作者简介:大家好,我是爱写博客的嗯哼,爱好Java的小菜鸟
🔥如果感觉博主的文章还不错的话,请👍三连支持👍一下博主哦
📝个人博客:敬请期待

文章目录

  • 前言
  • 一、关于HTTP
    • 1. HTTP请求
    • 2. 传统轮询
    • 3. 长轮询
  • 二、关于WebSocket
    • 1.WebSocket基础
    • 2. WebSocket请求流程
    • 3. Websocket总结
  • 三、总结
  • 结语

前言

相信大家都对HTTP协议比较熟悉,因为它是我们接触最多的一个协议。但Websocket跟它又有什么关系,有什么作用呢?这篇文章我们通过HTTP来引出Webscoket这个协议。


一、关于HTTP

1. HTTP请求

  • OSI七层架构:

在这里插入图片描述

大家都知道,HTTP协议是基于TCP协议开发的一款应用层协议,它主要针对的就是网站的一些请求

  • 请求图:

在这里插入图片描述

像这种可以算的上HTTP最简单的请求了,客户端向服务器请求数据,此时服务器响应数据,根据客户端请求的数据来返回对应的信息,可以进行一些基本的获取信息、请求数据一类的请求。

当然根据REST规范,还有POST请求、PUT请求、HEAD请求,这里就不一一列举了,大家有兴趣可以自己查一下。

因为HTTP这种协议只能客户端发送请求,服务器不能主动发送请求。大家看到这或许会有疑惑,为什么还要要求服务器主动推送呢。

  • 普通请求:

在这里插入图片描述

普通请求结合Ajax代码示例:

setInterval(function() {
  $.get("/to/hong", function(data, status) {
      console.log(data);
  });
}, 10000);

大家看这个图就知道了,此时小明想向小红炫耀一下自家的猫多么厉害(或许这就是孩童的乐趣吧),可是服务器并不能主动推送信息,小红永远也收不到,也就无法看到能后空翻的小猫了。

那么该如何解决这个问题呢?乐于助人的攻城狮想出了办法:可以让客户端频繁的去请求服务器不就行了,只要我请求的频率到一定程度,不就和服务器主动推送没区别了吗。

2. 传统轮询

  • 轮询方式:

在这里插入图片描述

传统轮询请求结合Ajax代码示例:

function poll() {
  setTimeout(function() {
      $.get("/path/to/server", function(data, status) {
          console.log(data);
          // 发起下一次请求
          poll();
      });
  }, 10000);
}

因为HTTP请求是请求响应类型的,所以每次HTTP请求之后都会返回数据,即使没有信息,也会返回一个空值。

这样对于聊天的话就会做很多无用的请求,让服务器遭受“凌迟之痛”,并且消耗大量带宽。

小明也很苦恼,明明就发一个消息,为什么消耗这么多流量呢?刚充的花费就没了。乐于助人的攻城狮肯定不会眼睁睁的看着小明因为约会把自己的金钱全部掏空,于是就做了一个违背祖宗的决定。

3. 长轮询

在上面的传统轮询中,巨量的请求都涌向服务器,占据大量网络资源。那么如何才能改进,避免大量资源的占用呢?

长轮询意味着浏览器只需启动一个HTTP请求,其连接的服务器会“hold”住此次连接,直到有新消息才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的HTTP请求,以此类推。

  • 轮询示例:

在这里插入图片描述

跟上面的短轮询对比,从图片上就感觉到不是那么密密麻麻的了。网络也是如此,减少了大量不必要的请求。

轮询可能在以下3种情况时终止:

  • 有新数据推送 。当服务器向浏览器推送信息后,应该主动结束程序运行从而让连接断开,这样浏览器才能及时收到数据。
  • 没有新数据推送 。应该设定一个最长时限,避免WEB服务器超时(Timeout),若一直没有新信息,服务器应主动向浏览器发送本次轮询无新信息的正常响应,并断开连接,这也被称为“心跳”信息。
  • 网络故障或异常 。由于网络故障等因素造成的请求超时或出错也可能导致轮询的意外中断,此时浏览器将收到错误信息。

这时候小明才长长叹拉口气,终于不会把自己的小金库花光了,还准备跟小红约会的时候用呢。

  • 注意:长轮询和长连接是有区别的。长连接是基于TCP的,在协议上的修改,而长轮询是编程挂起手动修改的

二、关于WebSocket

在上面你会发现,就算是HTTP的长轮询也是基于请求-应答的这种半双工通信模式,虽然可以双向的收发数据,但一个时刻只能一个方向有动作,传输效率低。

最终要的一点就是,它是一种被动的通信模式,服务器只能被动的响应客户端请求,无法主动发送数据。

做人不能总是主动,你越主动就越廉价。当然攻城狮也明白这个道理,为了让小明的爱情更加美好,就开始想办法做一个全双工的通信模型,不用像HTTP一样回合制类型那么客套了。于是,服务器就可以变得更加主动,一旦服务器有新的数据,就可以推送给小明,不需要再轮询了,通讯效率也变高了。

1.WebSocket基础

WebSocket采用了二进制帧结构,语法、语义跟HTTP完全不兼容,但现在的龙头老大还是HTTP,于是就尽量的往HTTP靠拢。

服务发现方面,WebSocket没有使用TCP的”IP地址+端口号",而是沿用了HTTP的URL格式,但开头协议名不是http,而是ws和wss,默认端口也选择了80和443。

ws://www.baidu.com:8080/server

这便是websocket的请求路径,唯一不同的就是协议名

2. WebSocket请求流程

作为一个新星协议,它是如何建立连接的呢

  • 建立连接:

从上面这个图可以看出来,Websocket竟然和HTTP有关系,最上面的是HTTP1.1版本,使用的GET请求,其中请求头一个字段很重要Upgrade,看这个意思大家应该都知道,是升级的意思。

这个请求就是使用HTTP请求向服务器传达一个信息,我要开始转换为WebSocket协议。

如果用啦HTTP请求那肯定会有一个响应,因为HTTP就是请求应答模型的,当然这次也肯定不例外。

  • 连接响应:

上面这个就是服务端产生的应答,告诉客户端,已经转换成功,以后我们就可以用Websocket交流信息了(HTTP:就没人管我的死活吗?T﹏T)

那么websocket是如何工作的呢?

在这里插入图片描述

首先就是上面提到的建立连接,建立连接成功之后,就开始进行全双工通信,这时服务端和客户端就可以自由发送请求了。

websocket聊天示例:
在这里插入图片描述

小明:程序猿太厉害了吧,我以后也要成为一名程序猿

3. Websocket总结

WebSocket 是一种基于 TCP 协议的通信协议,它提供了全双工的实时通信能力,使服务器和
客户端之间可以进行双向的、实时的数据传输。

以下是 WebSocket 的一些重要特点和用法:

  • 双向通信:WebSocket 允许服务器和客户端之间进行双向通信,无需依赖于客户端发起请求。服务器可以主动向客户端推送消息或数据,而不需要等待客户端发送请求。

  • 实时性:WebSocket 提供了低延迟的实时通信能力,适用于需要及时推送数据的场景,如即时聊天、实时消息更新等。

  • 长连接:与传统的 HTTP 请求-响应模式不同,WebSocket 在握手阶段建立连接后,连接会保持打开,双方可以长时间保持通信状态,避免了频繁建立和关闭连接的开销。

  • 二进制支持:WebSocket 不仅可以传输文本数据,还支持传输二进制数据,这使得它能够处理多媒体数据、文件传输等更复杂的场景。

  • 适用于 Web 应用和移动应用:WebSocket 可以被广泛应用于 Web 应用和移动应用中,为实时通信提供了强大的支持。

在使用 WebSocket 进行通信时,开发者可以借助相应的 WebSocket 客户端库或者浏览器提
供的 WebSocket API 来实现与服务器的连接和数据传输。同时,服务器端也需要支持
WebSocket 协议来处理客户端的连接和消息。

三、总结

关于HTTP请求和WebSocket的对比:

  • 连接方式:HTTP 是一种无状态的请求-响应协议,每次请求都需要重新建立连接。而 WebSocket 则是一种全双工通信协议,通过一次握手后,客户端和服务器之间可以保持长时间的连接,实现双向通信。

  • 通信效率:由于 HTTP 协议的特性,每次请求-响应的过程会带来较大的开销。而 WebSocket 的长连接可以减少频繁的握手和头部信息传输,从而提高通信效率,特别适合实时性要求高的场景。

  • 数据格式:HTTP 使用文本形式的请求和响应,通常以 JSON 或 XML 格式进行数据传输。而 WebSocket 可以传输二进制数据,可以更高效地处理多媒体数据或其他复杂的格式。

  • 支持性:WebSocket 是一种相对较新的协议,不是所有的浏览器和服务器都完全支持它。而 HTTP 是通用的协议,几乎所有的浏览器和服务器都能良好支持。

综上所述,WebSocket 相对于 HTTP 具有更低的通信延迟、更高的效率和更强大的功能,特别适用于实时通信、推送和实时更新的场景。但在一些简单的请求-响应交互中,仍然可以使用 HTTP。选择使用哪种协议取决于具体的需求和场景。


结语

每个人都有自己独特的才华和潜能,在这个广袤的世界上,你的存在是有意义的。无论你是谁,你的背景如何,你所处的环境怎样,只要你敢于跨出舒适区,付出努力,追求卓越,你就能够开创属于自己的辉煌。

我们下期见。

每一次努力都是一次进步,即使进展缓慢,也要坚持不懈。

往期文章推荐

  • 关于redis的读写一致问题
  • springsecurity加入第三方授权认证
  • Java连接mysql常遇时间问题

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【量化课程】02_4.数理统计的基本概念

2.4_数理统计的基本概念 数理统计思维导图 更多详细内容见notebook 1.基本概念 总体:研究对象的全体,它是一个随机变量,用 X X X表示。 个体:组成总体的每个基本元素。 简单随机样本:来自总体 X X X的 n n n个相互…

asp.net core webapi如何执行周期性任务

使用Api执行周期性任务 第一种,无图形化界面1.新建类,继承IJob,在实现的方法种书写需要周期性执行的事件。2.编写方法类,定义事件执行方式3.在启动方法中,进行设置,.net 6中在program.cs的Main方法中&#…

c51单片机串行通信示例代码(单片机--单片机通信)(附带proteus线路图)

//这个发送端代码 #include "reg51.h" #include "myheader.h" #define uchar unsigned char long int sleep_i0; long int main_i0; void main() {uchar sendx[6]{2,0,2,3,8,1};sleep(2000);TMOD0x20;TH10XF4;//根据波特率计算公式这里需要设置为这么多才能…

对自定义表格数据设计自定义查询/汇总

目录 1 前言 2 生成数据 3 设计一个汇总 4 试一下效果 5 导出为excel文件的源代码 6 后记 1 前言 对自定义表格中录入或者导入的数据,必须能定义查询和汇总,否则程序基本没什么用。就是说,程序应该具备对任意表格进行方便的查询汇总公式…

DatawhaleAI夏令营第三期机器学习用户新增预测挑战赛baseline新手教程

本教程会带领大家项目制学习,由浅入深,逐渐进阶。从竞赛通用流程与跑通最简的Baseline,到深入各个竞赛环节,精读Baseline与进阶实践技巧的学习。 千里之行,始于足下,从这里,开启你的 AI 学习之旅…

预训练GNN:GPT-GNN Generative Pre-Training of Graph Neural Networks

一.文章概述 本文提出了一种自监督属性图生成任务来预训练GNN,使得其能捕图的结构和语义属性。作者将图的生成分为两个部分:属性生成和边生成,即给定观测到的边,生成节点属性;给定观测到的边和生成的节点属性&#xf…

01:STM32点灯大师和蜂鸣器

目录 一:点亮1个LED 1:连接图 2:函数介绍 3:点灯代码 二:LED闪烁 1:函数介绍 2:闪烁代码 三:LED流水灯 1:连接图 2:函数介绍 3:流水灯代码 四:按键控制LED 1:电路图 2:连接图 3:函数介绍 4:按键控制LED代码 五:蜂鸣器 1:连接图 2:蜂鸣器代码 六:光敏电阻控制…

pywinauto结合selenium实现文件上传

简介 PC端-Windows上的元素识别可用viewWizard工具 PC端-Windows上的元素操作可用pywinauto库 浏览器上网页的元素识别可用selenium 安装 pip installer pywinauto 使用须知 pywinauto官方文档 确定app的可访问技术 1、win32 API(backend“win32”) 一般是MFC、VB6、VCL…

07_Hudi案例实战、Flink CDC 实时数据采集、Presto、FineBI 报表可视化等

7.第七章 Hudi案例实战 7.1 案例架构 7.2 业务数据 7.2.1 客户信息表 7.2.2 客户意向表 7.2.3 客户线索表 7.2.4 线索申诉表 7.2.5 客户访问咨询记录表 7.3 Flink CDC 实时数据采集 7.3.1 开启MySQL binlog 7.3.2 环境准备 7.3.3 实时采集数据 7.3.3.1 客户信息表 7.3.3.2 客户…

【Unity】ShaderGraph应用(模型膨胀流动)

【Unity】ShaderGraph应用(模型膨胀流动) 实现效果 ShaderGraph是 unity的图形化 Shader 编程工具。本文介绍使用ShaderGraph实现模型的膨胀流动效果。该效果可以由于模拟流体在管线中的流动等相关功能。 一、实现的方法 1.使用节点介绍 关键节点 UV…

【C#】静默安装、SQL SERVER静默安装等

可以通过cmd命令行来执行&#xff0c;也可以通过代码来执行&#xff0c;一般都需要管理员权限运行 代码 /// <summary>/// 静默安装/// </summary>/// <param name"fileName">安装文件路径</param>/// <param name"arguments"…

实录分享 | 使用Prometheus和Grafana监控Alluxio运行状况

欢迎来到【微直播间】&#xff0c;2min纵览大咖观点 本次分享主要包括三个方面&#xff1a; Prometheus&Grafana简介环境搭建手动调优 一、 Prometheus&Grafana简介关于Prometheus&#xff1a; Prometheus 是一个开源的完整监控解决方案&#xff0c;其对传统监控系…

【腾讯云 Cloud Studio 实战训练营】使用 Cloud Studio 快速构建 Vue + Vite 完成律师 H5 页面

【腾讯云 Cloud Studio 实战训练营】使用 Cloud Studio 快速构建 Vue Vite 完成律师 H5 页面 前言一、基本介绍1.应用场景2.产品优势 二、准备工作1.注册 Cloud Studio2.进入 Vue 预置开发环境 三、使用 Cloud Studio 快速构建 Vue Vite 完成律师 H5 页面1.安装相关依赖包2.主…

华为OD机试 - 最大N个数与最小N个数的和 - 数据结构Set与TreeSet(Java 2023 B卷 100分)

目录 一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 一、题目描述 给定一个数组&#xff0c;编写一个函数来计算它的最大N个数与最小N个数的和&#xff0c;需…

84. 柱状图中最大的矩形(单调栈)

题目链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 解题思路&#xff1a; 方法一&#xff1a;暴力解法 矩形的面积由宽和高决定&#xff0c;可以枚举所有的高度&#xff0c;也就是固定高度&#xff0c;然后从当前高度所在的位置向…

AD7151

AD7151采用ADI公司的电容-数字转换器&#xff08;CDC&#xff09;技术,这种技术汇集了与实际传感器接口过程中起着重要作用的众多特性于一身,如高输入灵敏度,较高的输入寄生接地电容和泄漏电流容限。 集成自适应式阈值算法可对因环境因素&#xff08;如湿度和温度&#xff09;…

Azure资源命名和标记决策指南

参考 azure创建虚拟机在虚拟机中选择编辑标签&#xff0c;并添加标记&#xff0c;点击应用 3.到主页中转到所有资源 4. 添加筛选器并应用 5.查看结果&#xff0c;筛选根据给服务器定义的标签筛选出结果。 参考链接: https://learn.microsoft.com/zh-cn/azure/cloud-adoption…

BBS项目day02、注册、登录(登录之随机验证码)、修改密码、退出登录、密码加密加盐

一、注册 1.注册之前端页面 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>注册页面</title><!--动态引入文件-->{% load static %}<script src"{% static js/jquery.min.js %…

hbase 报错 Master passed us a different hostname to use; was=

原因 wsl2的 /etc/hosts 配置的不兼容,我这里是ubuntu22 命令行输入hostname 看输出什么,比如输出 aaa 那么替换/etc/hosts 127.0.0.1 aaa

React源码解析18(5)------ 实现函数组件【修改beginWork和completeWork】

摘要 经过之前的几篇文章&#xff0c;我们实现了基本的jsx&#xff0c;在页面渲染的过程。但是如果是通过函数组件写出来的组件&#xff0c;还是不能渲染到页面上的。 所以这一篇&#xff0c;主要是对之前写得方法进行修改&#xff0c;从而能够显示函数组件&#xff0c;所以现…