图解WebSocket

news2024/10/6 4:11:33

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常遇时间问题

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

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

相关文章

使用phpstorm开发调试thinkphp

1.环境准备 1.开发工具下载:PhpStorm: PHP IDE and Code Editor from JetBrains 2.PHP下载:PHP: Downloads 3. PHP扩展:PECL :: Package search 4.用与调试的xdebug模块: Xdebug: Downloads xdebug模块,如果是php8以…

分类预测 | MATLAB实现GWO-BiLSTM-Attention多输入分类预测

分类预测 | MATLAB实现GWO-BiLSTM-Attention多输入分类预测 目录 分类预测 | MATLAB实现GWO-BiLSTM-Attention多输入分类预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.GWO-BiLSTM-Attention 数据分类预测程序 2.代码说明:基于灰狼优化算法&#xff08…

【JVM】对String::intern()方法深入详解(JDK7及以上)

文章目录 1、什么是intern?2、经典例题解释例1例2例3 1、什么是intern? String::intern()是一个本地方法,它的作用是如果字符串常量池中已经包含一个等于此String对象的字符串,则返回代表池中这个字符串的String对象的引用&#…

Redis缓存读写策略(三种)数据结构(5+3)

Redis缓存读写策略(三种) Cache Aside Pattern(旁路缓存模式) Cache Aside Pattern 是我们平时使用比较多的一个缓存读写模式,比较适合读请求比较多的场景。 写: 先更新 db然后直接删除 cache 。 读 : …

爆肝整理,性能测试方法与关键指标以及瓶颈定位思路,一篇贯通...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 性能测试方法 1、…

Mybatis 源码 ③ :SqlSession

一、前言 Mybatis 官网 以及 本系列文章地址: Mybatis 源码 ① :开篇Mybatis 源码 ② :流程分析Mybatis 源码 ③ :SqlSessionMybatis 源码 ④ :TypeHandlerMybatis 源码 ∞ :杂七杂八 在 Mybatis 源码 ②…

ubuntu 部署 ChatGLM-6B 完整流程 模型量化 Nvidia

ubuntu 部署 ChatGLM-6B 完整流程 模型量化 Nvidia 初环境与设备环境准备克隆模型代码部署 ChatGLM-6B完整代码 ChatGLM-6B 是一个开源的、支持中英双语的对话语言模型,基于 General Language Model (GLM) 架构,具有 62 亿参数。结合模型量化技术&#x…

Go学习-Day1

Go学习-Day1 个人博客:CSDN博客 打卡。 Go语言的核心开发团队: Ken Thompson (C语言,B语言,Unix的发明者,牛人)Rob Pike(UTF-8发明人)Robert Griesemer(协助HotSpot编译器,Js引擎V8) Go语言有静态语言的…

Sentinel使用实例

不说了,直接上官方文档 https://github.com/alibaba/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-examples/sentinel-example/sentinel-core-example/readme-zh.md Sentinel Example 项目说明 本项目演示如何使用 Sentinel starter 完成 Spring Clo…

推荐工具!使终端便于 DevOps 和 Kubernetes 使用

如果你熟悉 DevOps 和 Kubernetes 的使用,就会知道命令行界面(CLI)对于管理任务有多么重要。好在现在市面上有一些工具可以让终端在这些环境中更容易使用。在本文中,我们将探讨可以让工作流程简化的优秀工具,帮助你在 …

Intel汇编和ATT汇编的区别?

一、前缀不同 在 Intel 语法中,没有寄存器前缀或立即前缀。 然而,在 AT&T 中,寄存器的前缀是“%”,而 immed 的前缀是“$”。 Intel 语法十六进制或二进制即时数据分别带有“h”和“b”后缀。 此外,如果第一个十六…

最新AI系统ChatGPT网站程序源码+搭建教程/公众号/H5端/安装配置教程/完整知识库

1、前言 SparkAi系统是基于国外很火的ChatGPT进行开发的Ai智能问答系统。本期针对源码系统整体测试下来非常完美,可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。 那么如何搭建部署AI创作ChatGPT?小编这里写一个详细图文教程吧!…

nginx一般轮询、加权轮询、ip_hash等负载均衡模式配置介绍

一.负载均衡含义简介 二.nginx负载均衡配置方式 准备三台设备: 2.190均衡服务器,2.191web服务器1,2.160web服务器2,三台设备均安装nginx,两台web服务器均有网页内容 1.一般轮询负载均衡 (1&#xff09…

基于深度信念神经网络的矿石产量预测,基于DBN的矿石产量预测,DBN的详细原理

目录 背影 DBN神经网络的原理 DBN神经网络的定义 受限玻尔兹曼机(RBM) DBN的矿石产量预测 基本结构 主要参数 数据 MATALB代码 结果图 展望 背影 DBN是一种深度学习神经网络,拥有提取特征,非监督学习的能力,是一种非常好的分类算法,本文将DBN算法进行矿石产量预测 DB…

golang Cobra 快速使用

package mainimport("fmt""os""github.com/spf13/cobra" )func f1(){fmt.Printf("这是主命令的运行函数 ") } func f2(){fmt.Println("这是一个子命令的运行函数") }func main(){var rootCmd &cobra.Command{Use: &quo…

【果树农药喷洒机器人】Part8:果树对靶变量喷药实验

📢:博客主页 【https://blog.csdn.net/weixin_51244852】 📢:文章若有幸对你有帮助,可点赞 👍 收藏 ⭐不迷路🙉 📢:内容若有错误,敬请留言 📝指正…

Maven - 全面解析 Maven BOM (Bill of Materials):打造高效依赖管理与模块化开发

文章目录 Whats BOMWhy Bom常見的官方BOMSpring Maven BOM dependencySpringBoot SpringCloud Maven BOM dependencyJBOSS Maven BOM dependencyRESTEasy Maven BOM dependencyJersey Maven BOM dependency How Bom定义BOM其他工程使用的方法 BOM VS POM What’s BOM BOM&…

jmeter中用户参数和用户定义的变量的区别

如果使用jmeter做过参数化的人都知道,参数化的方式有多种,其中一种就是使用用户定义的变量,还有一种是使用用户参数。那么,这两个有什么异同呢? 一、先说相同的点: 1、都可以参数化,以供sample…

ArrayList浅拷贝clone,Kotlin

ArrayList浅拷贝clone&#xff0c;Kotlin import kotlin.collections.ArrayListfun main() {var list ArrayList<MyData>()for (i in 0..<3) {list.add(MyData(i, 0))}//浅拷贝list到copyListvar copyList list.clone()println(list)println(copyList)println("…

SSM整合(XML方式)

文章目录 SSM整合之后xml方式1 系统环境1.1 软件环境1.2 项目环境1.3 配置web.xml1.4 配置jdbc.properties文件1.5 配置SpringMVC核心文件1.6 配置Spring的核心文件1.7 配置MyBatis的核心文件1.8 配置数据库1.9 配置文件位置 2 编写后端代码2.1 编写实体类2.2 编写Dao接口2.3 编…