Flutter 之 HTTP3/QUIC 和 Cronet 你了解过吗?

虽然 HTTP3/QUIC 和 cronet 跟 Flutter 没太大关系,只是最近在整理 Flutter 相关资料时发现还挺多人不了解,就放到一起聊聊。

本篇也是主要将现有资料做一些简化整合理解。

前言

其实为什么会有 HTTP3/QUIC ?核心原因还是现有协议已经无法满足需求,说个最简单又不严谨的例子:

当你在家里拿着手机用 Wi-Fi 下片,这时候觉得饿了要下楼吃饭,然后你带着手机离开了家里,期间一直没有退出 App 的打算,这个过程手机流量会从 Wi-Fi 变成 5G 网络,那么网络链路就会变成了一个全新的网络环境,从 Wi-Fi 到 5G 会是全新的 IP 地址,那么作为新的链接, TCP 就无法复用之前的数据和状态,也就是之前链路就断了,那么下载行为可能就会被打断,而你直到温饱之后要用,才发现资源还没下载完成。

我们知道, HTTP/2 时代,每个网络请求我们都要经历多次 TCP 握手,特别现在基本都强制了 HTTPS ,所以 TLS 加密握手也不可或缺,但是在移动场景下,其实用户的网络环境极有可能在不停的发生变化,所以用户在移动过程中,TCP 链接极有可能被迫打断。

在 App 使用过程中,重启 TCP 连接会带来一些不好的体验,例如等待新的握手、重新开始下载、重建上下文等延迟,而 QUIC 其中就包括解决这一问题的实现,通过 connection migration 实现链路复用,后续我们会详细聊到。

QUIC

其实只要说到 HTTP/3 就离不开 QUIC (Quick UDP Internet Connections),因为 QUIC 是一个通用传输协议,它是 HTTP/3 的灵魂所在,而神奇之处也在于,它是运行在 UDP 的协议的基础上

大家对于 UDP 应该不陌生,因为相较于 TCP ,它相对不可靠,因为 UDP 不提供任何特性,例如它不会通过握手建立连接,如果包丢失也不会获得自动重传,所以它一直以来都被冠以「不可靠」的称号。

那么 UDP 有什么优点?那肯定是快~因为 UDP 不需要等待握手,也没有队头阻塞,所以它的性能一直很好,那 QUIC 建立在 UDP 之上就是为了性能吗

其实并不全是,或者是关键因素并不是,因为如果把 QUIC 作为一个直接运行在 IP 之上的全新独立协议,那么就意味着 HTTP/3 会无法兼容现有的许多硬件设备,这明显并不现实,但是如果构建在 UDP 上,那么 QUIC 就拥有更好的兼容和部署支持

所以最终落地的结果就是: QUIC 在 UDP 之上重新实现了一套「更高效的 “new TCP”」 的通用协议

当然,如果你硬要简单说 HTTP/3 是将 TCP 换成了 UDP 也说得通,只是并不是因为 UDP 更快,而是为了 QUIC 能更好兼容部署,并且 QUIC 本身就是一套基于 UDP 的全新的高级的 “TCP”

那么 QUIC 有哪些优秀的地方呢?其中就包括前面说的在移动环境下让连接可以保持更长时间

QUIC 支持连接迁移( connection migration )

我们前面知道了,当用户手机在 Wi-Fi 和 5G 网络进行切换时,TCP 链接会出现中断,如果我们定义 App 和服务器之间的链接是通过 「App IP + App 端口 + 服务器 IP + 服务器端口」 这样四个元素来表示一个链接,那么 Wi-Fi 和 5G 网络的时候,App 端的 IP 变了,那么对于服务端而言,这就是一个全新的链接,所以旧的 TCP 链接就无法被复用。

为了解决这个问题,QUIC 提出了连接标识符(CID, connection identifier),每个连接都在前面提到的四个元素之上分配了另一个 CID 编号,可以在 App-服务器端点之间来唯一标识它。

简单说,因为这里 CID 在 QUIC 中的传输层定义,所以它不会因为切换网络时发生改变,比如下图所示,一般情况下 CID 是包含在每个 QUIC 数据包的前端,而 CID 也是 QUIC header 中少数几个没有加密的数据。

通过 CID ,前面提到的四个元素里,就算 App IP 发生变化,QUIC 服务器和 App 只需要看下 CID,就能知道这其实还是之前的同一个连接,不需要重新握手,可以继续复用之前的下载状态,这也是前面提到过的 connection migration 。

当然,前面这个介绍相对简化,如何考虑到安全问题,CID 不会被直接使用,而是使用映射。

假设 App 和服务器都知道有 CID A、B 、C 都是映射到连接 X, 然后 App 可能会在 Wi-Fi 上会使用 A 标记数据包,而在 5G 上使用 B 标记 ,而映射的列表在 QUIC 中是完全加密,从而让黑客只知道 A、B、C,但是不知道 X 的存在。

当然,这也还是简化后的逻辑,只是为了更好理解,现实中 CID 的相关逻辑更加复杂,只是通过这些,大家应该就可以更快速理解 QUIC 为什么可以做到 connection migration 和其关键实现理念。

就这样,有了 QUIC 支持,在移动场景中,当网络切换时,可以看到如下图右侧使用 QUIC 手机很快便响应了请求,而左侧手机因为需要建立新的链路,所以需要等待超时后,重新握手成功再请求的效率对比。

TLS 集成

其实通过一开始的架构图,大家应该也可以看出来,和 HTTP/2 不同的是,QUCI 他直接集成了 TLS ,其目的就是加快和减少 HTTPS 请求是所需的时间。

因为在以前使用 HTTPS 请求时, HTTP 数据需要先由 TLS 加密,再由 TCP 传输,虽然 TLS 随着版本发展所需的加密握手次数已经得到优化,但是相比较起来,加密所带来的开销还是客观存在。

而在 QUIC 里就不一样了,QUIC 将 TLS 进行了封装,所以,对于 TCP 模式下 TLS 和 TCP 协议都需要单独握手, QUIC 将传输和加密握手合并为一次握手,节省了往返时间,但这也表明了 QUIC 必须使用 TLS, HTTP/3 下会是始终完全加密的状态,同时 QUIC 还加密它的(除了前面的 CID 等)数据包头字段,甚至传输层信息一般情况下都不能再被中间件读取。

所以,QUIC 默认深度加密,与之前的 TCP 相比,他也可以在一定程度节省 TLS 的开销,当然,QUIC 使用 TLS 单独加密每个数据包,而 TLS-TCP 可以同时加密多个数据包,所以 QUIC 也可能在高吞吐量的场景中变慢。

优化多路复用字节流

简单说,多路复用字节流就是单一 TCP 连接下载不同的资源,在传输时将不同文件的数据混合,比如 ABC 三种数据混合在一起传输。

而在 TCP 时代,TCP 是不知道多路复用字节流里数据的混合情况,也即是 TCP 不知道数据是 ABC,它直管传输数据,如果这时候 C 出现数据丢失, TCP 会认为整个数据传输出现丢失,从而导致整个链路里其他 AB 因为这个等待而变慢,这就是传说中的队头阻塞问题。

而 QUIC 的在某种意义上解决了传输层的队头阻塞问题,因为 QUIC 会知道有多路复用的多字节流存在,是真正意义上“理解了”多路复用,所以它可以在每个流的基础上执行丢包监测和恢复逻辑。

当然,这也造成了 TCP 和 QUIC 出现了本质的不兼容区别,QUIC 「理论上」来说是不兼容 HTTP/2 运行,因为 HTTP/2 还包括在单一 TCP 连接上运行多个流的概念。

其实 TCP 的设计目的从来不是在单一 TCP 上传输多个独立的文件,只是因为现实场景用到了,所以才有这样奇怪的兼容方式,而 QUIC 通过在传输层传输多个字节流以及在每个流基础上处理丢包问题,来解决 TCP 上一直存在的问题。

总的来说,QUIC 算是 TCP 的不兼容升级,而又由于它基于 UDP 实现,所以可以兼容已有的设备运行,并且集成了 TLS,默认全加密,支持 connection migration 等,在不可靠的网络场景下也可以实现更可靠的网络运行

QUIC 下的 Flutter :Cronet

既然我们知道 HTTP/3 和 QUIC 可以得到更好的体验,那就不得不说 Cronet,因为 Cronet 是 Chromium 网络堆栈,所以才被称为 Cronet ,它和 Chromium 使用相同的网络引擎。

使用 Cronet 最重要的意义是,它能够同时支持 TCP 协议和 QUIC 协议,一般情况下 App 发送请求时会说明“我支持 QUIC” ,然后服务端收到请求后,根据自身情况确实是否使用 QUIC 。

目前的说法是,只要 Cronet 知道了服务端支持 QUIC ,那么 Cronet 后续请求就会开始使用 QUIC , QUIC 的协议发现过程是通过识别响应头中的特殊字段来实现

而 Cronet 核心网络引擎完全基于C/C++,所以它除了可以在 Android 中使用之外,也可以通过 FFI 的方式被 Dart 使用,在 Google 产品里, YouTube、 Google App、 Google Photos、 Maps 等都是用 Cronet 来处理网络请求,所以总的来说,Cronet 还是相对可靠的

所以其实对于 Cronet 而言, Flutter 和 Android 都是大差不差的情况。

Cronet 在 Flutter 得推进主要是依赖 Dart 语言的发展进程,例如:

  • Dart 2.18 提供了对两个对于 package:http 特定于平台的 http 库的实验性支持:

    • cupertino_http 基于 NSURLSession 的 macOS/iOS 支持。

    • cronet_http 基于 Cronet,Android 上的网络库支持。

  • Dart 3.2

    • 改进 package:jnigen 实现 Java 和 Kotlin 的直接调用支持,现在可以将 package:cronet_http(Android Cronet HTTP 客户端的包装器)从手写绑定代码迁移到自动生成的包装器

目前 Flutter 使用 Cronet 可以通过引入 cronet_http 包,新版的 dio 内也实现了对应的 cronet_adapter ,如果你使用了 dio ,基本就可以直接使用 Cronet。

对于 Cronet 的使用,也可以分为 使用Google Play 支持版本和使用嵌入式 Cronet 支持版本

  • 如果你的 App 使用 GP 服务,那么其实可以不额外植入 Cronet 依赖,这样的好处就是 Cronet 的更新迭代完全和你的 App 没有关系,升级维护完全交给 GP 负责,相对体积也会小很多。

  • 如果你不使用或者没条件使用 GP 服务,那么也可以使用嵌入式的运行方式,例如 flutter run --dart-define=cronetHttpNoPlay=true

而如果你使用 Dio,那么使用 Cronet 则非常“简单”,只需要一行配置即可完成,不过目前来说,Cronet 只会在 Android 生效,在 iOS 上 NativeAdapter 使用的是基于 NSURLSessioncupertino_http

final dioClient = Dio();
dioClient.httpClientAdapter = NativeAdapter();

为什么 iOS 使用 NSURLSession ?因为 iOS 15 和 macOS Monterey 默认就启用适配了 HTTP/3

最后

本篇主要还是基于科普性质居多,核心还是简单的告诉大家,什么是 HTTP/3 和 QUIC ,QUIC 和 TCP 的区别和优势,最后是 Cronet 的介绍已经如何在 Flutter 里使用 QUIC。

目前基本云厂商都已经支持了 QUIC 配置,所以如果你还没开始接触 HTTP/3 ,现在也许是时候可以试试了,不过我认为,其实也许你的项目已经在使用 HTTP/3 ,只是你还没发现而已。

参考资料:

  • https://unsuitable001.medium.com/package-cronet-an-http-dart-flutter-package-with-dart-ffi-84f9b69c8a24

  • https://www.smashingmagazine.com/2021/08/http3-core-concepts-part1/

  • https://calendar.perfplanet.com/2020/head-of-line-blocking-in-quic-and-http-3-the-details/

  • https://pub.dev/packages/cronet_http

  • https://www.youtube.com/watch?v=YWiRef3wOYY

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

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

相关文章

《Kubernetes部署篇:基于Kylin V10+ARM架构CPU+外部etcd使用containerd部署K8S 1.26.15容器版集群(一主多从)》

总结:整理不易,如果对你有帮助,可否点赞关注一下? 更多详细内容请参考:企业级K8s集群运维实战 1、在当前实验环境中安装K8S1.25.14版本,出现了一个问题,就是在pod中访问百度网站,大…

《2024最新Java面试题及答案(带完整目录)》

获取链接:《2024最新Java面试题及答案(带完整目录)》 更多技术书籍:技术书籍分享,前端、后端、大数据、AI、人工智能... ​ ​ ​ 4.1.9.8. 可重入锁(递归锁) ...........................…

十大开源机器人 智能体

1- Poppy 网址 https://www.poppy-project.org/en/ 2- Nao 网址:https://www.aldebaran.com/en/nao 3- iCub 网址: https://icub.iit.it/

vscode 配置go环境

https://www.zhihu.com/question/486786946/answer/2723663432 注意一定要安装最新版,否则不容易debug //main.go package main //说明hello.go这个文件在main这个包中import "fmt" //导入内置包,可以使用其中函数等func main() {fmt.Println("Hello…

机器视觉系统:电容表面瑕疵缺陷检测的精准“守望者”

在电子行业中,电容器作为关键元件,其质量和性能对于整个产品的稳定性和可靠性至关重要。电容器的表面质量直接影响其性能和寿命,因此,对电容表面瑕疵缺陷的精确检测显得尤为重要。近年来,随着机器视觉技术的飞速发展&a…

Linux设置真实IP

1.查看ens33网卡信息 vi /etc/sysconfig/network-scripts/ifcfg-ens33 #添加以下内容 BOOTPROTODHCP #协议类型 dhcp bootp none ONBOOTyes #启动时是否激活 yes | no#修改文件完成后,重启网络 service network restartping www.baidu.com #验证网络是否生效 ifco…

[卷积神经网络]YoloV8

一、YoloV8 1.网络详解 ①backbone部分:第一次卷积的卷积核缩小(由3变为6);CSP模块的预处理卷积从3次变为2次;借鉴了YoloV7的多分支堆叠结构(Multi_Concat_Block)。 所小第一次卷积的卷积核尺寸会损失部分感受野&#…

鸢尾花数据集分类(决策树,朴素贝叶斯,人工神经网络)

目录 一、决策树 二、朴素贝叶斯 三、人工神经网络 四、利用三种方法进行鸢尾花数据集分类 一、决策树 决策树是一种常用的机器学习算法,用于分类和回归任务。它是一种树形结构,其中每个内部节点表示一个特征或属性,每个分支代表这个特征…

特步赞助可能“惹乱子”,北京半马进入官方调查阶段

北京半马风波的发酵超乎想象,从4月14日事件发生到现在,舆论已经从对赛事本身的质疑,上升到一些其他的层面。 从最新的信息来看,北京体育局、北京半马组委会表态称事情还在调查,舆论则大多倾向于“特步幕后操盘、外籍选…

抖去推短视频矩阵系统----源头开发

为什么一直说让企业去做短视频矩阵?而好处就是有更多的流量入口,不同平台或账号之间可以进行资源互换,最终目的就是获客留咨,提单转化。你去看一些做得大的账号,你会发现他们在许多大的平台上,都有自己的账…

Ubuntu 20.04 LTS 在3588安卓主板上测试yolov8-1.0版本的yolov8n-seg模型

0. 创建虚拟环境 #!< 创建虚拟环境yolov8 $ sudo pip install virtualenv $ sudo pip install virtualenvwrapper $ mkvirtualenv yolov8 -p /usr/bin/python3.81. 将yolov8n-seg.pt转换为yolov8n-seg.onnx文件 #!< 创建项目目录yolov8-rknn并下载yolov8n-seg.pt模型文…

MATLAB环境下基于随机期望最大化的多分量信号瞬时频率估计方法

相对于频率成分单一、周期性强的平稳信号来说&#xff0c;具有非平稳、非周期、非可积特性的非平稳信号更普遍地存在于自然界中。调频信号作为非平稳信号的一种&#xff0c;由于其频率时变、距离分辨率高、截获率低等特性&#xff0c;被广泛应用于雷达、地震勘测等领域。调频信…

.net反射(Reflection)

文章目录 一.概念&#xff1a;二.反射的作用&#xff1a;三.代码案例&#xff1a;四.运行结果&#xff1a; 一.概念&#xff1a; .NET 反射&#xff08;Reflection&#xff09;是指在运行时动态地检查、访问和修改程序集中的类型、成员和对象的能力。通过反射&#xff0c;你可…

SAP项目任务一览表

根据SAP Activate项目管理方法论的主要精神&#xff0c;浓缩到一些主要的团队和任务。 主要的团队有&#xff1a; 项目管理(办公室)Project Management(office)&#xff1a;项目经理团队&#xff0c;包括项目办公室。负责项目整体运行和监控&#xff0c;项目办公室负责项目的…

【MySQL 安装与配置】Window简单安装MySQL,并配置局域网连接

文章日期&#xff1a;2024.04.17 系统&#xff1a;Window10 || Window11 类型&#xff1a;安装与配置MySQL数据库 文章全程已做去敏处理&#xff01;&#xff01;&#xff01; 【需要做的可联系我】 AES解密处理&#xff08;直接解密即可&#xff09;&#xff08;crypto-js.js…

Stm32-hal库串口教程

工程是在上一节的LED的基础上修改的。 串口原理图 串口配置 led参考 CubelMX点灯-CSDN博客https://blog.csdn.net/anlog/article/details/137830323生成工程 编写包含文件 编写重定向代码 编写发送 编译下载 串口没有收到数据 查找原因 少配置了下图 再编译下载 收到数据…

【MySQL 数据宝典】【内存结构】- 002 Page管理机制

一、 Page 管理机制 Buffer Pool 的底层采用链表数据结构管理Page。在InnoDB访问表记录和索引时会在Page页中缓存&#xff0c;以后使用可以减少磁盘IO操作&#xff0c;提升效率。 1.1 Page 页的分类 free page &#xff1a; 空闲page&#xff0c;未被使用clean page&#xff…

Ubuntu 系统安装 VS Code 并配置 C++ 环境

Linux 系列教程&#xff1a; VMware 安装配置 Ubuntu&#xff08;最新版、超详细&#xff09;FinalShell 远程连接 Linux&#xff08;Ubuntu&#xff09;系统Ubuntu 系统安装 VS Code 并配置 C 环境 ➡️➡️ ➡️VS Code 官方教程&#xff1a;Using C on Linux in VS Code&…

Meta因露骨AI图片陷入困境

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

wsl安装与日常使用

文章目录 一、前向配置1、搜索功能2、勾选下面几个功能&#xff0c;进行安装二、安装WSL1、打开Windows PowerShell,查找你要安装的linux版本2、选择对应版本进行安装3、输入用户名以及密码 三、配置终端代理1、打开powershell,查看自己的IP把以下信息加入到~/.bashrc中 四、更…