Reqable项目技术栈全方面总结

本文详尽总结了Reqable项目的技术栈,涵盖客户端、前端、后端和服务端。客户端基于Flutter和C++,使用Dart进行大部分开发,采用C++实现网络流量分析模块。前端使用Docusaurus框架,许可证管理中心运用Flutter。服务端选择了shelf网络框架和SQLite数据库,部署使用Docker。文章还讨论了跨域、字体、CanvasKit等问题的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

大家好,最近有知乎网友问我Reqable技术选型的问题,恰好Reqable也刚刚发布了非常重要的1.3版本更新,所以此次写一篇关于Reqable项目技术栈的全方面总结。

本篇文章的目的,是向大家分享我关于Reqable项目的一些技术思考、细节和填坑概要等。希望能够对大家有所帮助、避坑、少走一些弯路、更快交付。有必要说明的是,Reqable项目完全由我个人独立完成,受限于本人经验和能力,肯定有非常多的不足。如果你对本篇总结中提到的技术选型、处理方式等有不同的见解,欢迎提交评论,一起讨论,共同学习。
请添加图片描述
如果有不了解Reqable的,可以看上面这张图,官网首页:https://reqable.com

下面,话不多说,正文开始。

1. 客户端

Reqable客户端是基于Flutter和C++开发的,由于整体不涉及非常复杂的层次架构,所以我就不放Arch图了。其实简而言之,除了网络流量分析框架和API请求框架,这两个模块是使用C++语言开发外,其他几乎都是使用Dart语言开发。下面,我们来依次进行介绍。

1.1 网络流量分析模块

这个模块内部的代号是Netbare,如果你查看Reqable解压的运行库,应该能看到这个。Netbare从项目初始就确定了使用C++语言进行开发,最核心的考量标准就是性能。Netbare的职责包含下面几个:

  • 建立代理服务器
  • 分析入流量,解析代理协议
  • SSL证书重签和握手(MITM
  • 中间人客户端
  • 中间人服务器
  • HTTP协议解析和封包
  • 插件和拦截器处理

从上面的职责可以看到,Netbare既承担了服务器的角色,又承担了客户端的角色。这对性能其实是有一定要求的,也就是说多线程是非常有必要的。又由于Reqable是跨平台的项目,C和C++成了首要选择语言,Java、Javascript、Dart、C#、Python等基本可以不考虑,Dart又是单线程机制,Rust也是一个可选项,但是这个语言我完全不熟悉。在我的技术栈里面,C++以绝对的优势胜出,恰好最近几年内我写了大量C++的代码,手还热乎着。

确定C++作为Netbare开发语言后,网络框架库就非常自然地选择了asio。但是我并不想引入Boost这个庞大的库,所以选择了独立版本的asio,然后SSL选择了openssl,最后是格式化io库fmt。除此之外,虽然HTTP2协议规范是由Netbare自己实现的,但还是引入了nghttp2作为辅助。这几个开源项目都是作为git submodule引入的,非常稳定,我没有修改过任何源码,在此向这些伟大的开源项目致敬。

Netbare采用和我曾经开源的NetBare-Android项目类似的架构设计,支持拦截器机制,但是简化和优化了非常多。C++同样是面向对象的语言,我保留了HTTP3(QUIC)的扩展接口,方便我后面可以很快地接入。Netbare提供了一套非常简单的API,简单接入便可以单独编译出可执行文件直接运行,具备完整的抓包功能。事实上,大多数网络协议相关的调试分析我都是直接在Netbare项目中进行的。

Netbare使用C++ 11标准,Cmake作为编译组织脚本,目前支持在Windows、Mac和Linux平台下ARM和x86编译。目前还没有支持Android和iOS两个平台的编译,但后面很快会支持。

光有Netbare库还无法直接在Reqable客户端中使用,还需要考虑接入的问题。尽管Netbare提供了一套C的API接口,但由于客户端主体使用Flutter框架(Dart语言)开发,这里就涉及到跨语言调用的问题。为了给客户端业务逻辑提供更好的支持,我又额外提供了一套Dart的接口:
请添加图片描述
换句话说,就是另外创建了一个Dart模块项目,接入了Netbare的C++库,并提供了纯Dart语言的接口供客户端调用,在客户端项目中只需要关注Dart的API即可。从上面的图可以看出,无论是C++接口还是Dart接口的调用方式都是基本一致的。

1.2 Rest API请求模块

由于Reqable确定要支持HTTP3(QUIC)协议,根据我之前的项目经验,当时可靠的方案有两个:curl vs Cronet,最终我选择了Cronet ,下面分别来说下两个方案的优劣。

curl是一个非常老牌的网络库了,其已经内置到大部分系统中,例如MacOS、Linux等。非常多常用的软件也都是基于curl发送网络请求,例如GitUnity等等。另外,curl很早就开始支持HTTP3的草案版本了,但是至今仍然处于实验功能阶段,详见这里。我曾经在2021年,编译并测试过curl的HTTP3协议版本,测试结果让我迅速放弃了它。

Cronetchromium项目的一个子模块,源码详见这里。Cronet本身并不是HTTP众多版本协议的实现者(真正的实现在这个net目录),只是对net目录代码封装,而net才是整个chromium的网络核心。当然,Cronet的好处是作为一个模块,可以编译出单独的模块制品,另外API设计得也更加地简单。据我之前了解,B站、字节系等相关产品都采用了Cronet的方案,但大多数是移动端。也许是因为Google本身的大量移动端产品使用了此方案,另外,Cronet还提供了Java等移动端语言的接口和成品库。

更多的实现细节,我都在这篇中详细地讲解了,有兴趣可以看看:https://juejin.cn/post/7254076875780620325

1.3 Dart & Flutter

Reqable客户端超过80%的代码都是通过Dart编写的,包含UI、UX以及业务逻辑,另外还有一些Flutter插件,用于与Native平台进行相互调用。

我为什么选用Flutter呢?

很多小伙伴会觉得Electron更成熟、生态更完善、开发效率更高,而在2022年初,Flutter桌面端正式版本都没有发布呢!当然,这些都毫无疑问是正确的、无懈可击的。但是,我还是有一些不同角度的看法。

首先,Reqable的目标是支持桌面端+移动端,覆盖全部的终端设备平台。Electron能够很好地解决桌面端的需求,但是解决不了移动端,这是一个致命的影响决策的因素。QT也是一样还要收费,而像Tauri等又小众了一些。

其次,性能考虑。Electron的性能声名(狼藉)在外,大多数技术员可能都知道这个,不是所有基于Electron的应用都能够像VS Code那样去做特定优化,Postman就是一个反面例子。另一个糟心的就是安装包大小和存储空间,以Mac为例,如果一个应用安装包体积超过了100M,十有八九是基于Electron,安装后更大,像企x微x能够占用用到上G的空间,而Flutter安装包只有20M左右、甚至更低。Reqable是面向技术人员的产品,我相信没有多少技术人员喜欢在自己电脑里面安装一堆浏览器内核。猜一猜下图里面(本人开发机器)装有多少个浏览器?
请添加图片描述
当然,完全从性能考虑,QT应该是最优项,但是C++的开发效率又太低了,此外在没有设计伙伴支持的情况下UI/UX也很难做出赏心悦目的效果。

Flutter是一个非常新的框架,至少在桌面端如是,不过基本功能都是相对齐全的,此外大多数不支持的特性都可以通过插件机制来解决。Flutter的插件机制是一个非常好的设计,支持与Native语言交互从而可以调用系统的API接口,这个几乎可以解决所有的问题。

另外,作为一个技术人员,我相信新的技术是驱动这个社会进步的动力,相比于沉湎在旧技术的舒适区,拥抱一个全新的技术会带来更大的乐趣,挑战与机遇并存。

选择Flutter就意味着我选择了Dart,在语言层面,这并没有太大的障碍。在我当时已有的技术栈里面,Java、C/C++、C#、Python、JavaScript、Kotlin和Groovy等我都比较熟悉,也都有过项目实践。所以,在看了几天Dart的官方文档后,便正式开始Flutter之旅了。

1.3.1 Flutter状态管理

熟悉Flutter的同学,应该都能够理解状态管理这个概念。Flutter并不像Android、iOS、Unity或者前端等支持分离式布局,无论是布局、数据还是逻辑都是在Dart源文件中直接编写,这也是目前非常多UI框架的采用的方式。众所周知,布局、数据还是逻辑肯定不应该写在同一个Dart源文件中。MVC也好,MVVM也罢,在Flutter中肯定也是需要一种类似的分离布局、数据和逻辑的框架,在Flutter中这个叫做状态管理框架,大概是因为Widget分为有状态和无状态两种。

Reqable的定位是中大型Flutter项目,选择合适的状态管理框架非常地重要。项目稳定后,推翻这个框架的成本是绝对无法承受的。当时可选的大概就是下面这些:

  • GetX
  • Provider
  • BLoC
  • Riverpod

我的需求是找一个轻量级的状态管理框架,适合大型项目、利于维护、方便定制扩展。结论是Reqable选择了BLoC

首先我排除掉了GetX,当时简单看了下,第一感觉这是一个非常重的框架,什么都有,像一个杂货店;无法想象在Flutter频繁更新的状态下这个框架的稳定性会怎么样,如果停止维护了又是一番什么样的景象。Provider又太简单了些,无法应对复杂的场景。Riverpod很不错,成熟度差一些。BLoC的功能很完善,代码简单、稳定性和成熟度也很高,是一个非常契合Reqable项目的选择。

基于BLoC,Reqable主要业务逻辑主要分为了三个部分,实现了MVC的基本理念:

Reqable
   ├── bloc  // 逻辑层
   ├── ui    // UI层
   └── model // 数据层

当然BLoC并不是完美的,Provider + Builder的编写方式,需要写大量的模板代码,开发效率并不高。适当地基于BLoC再包装一层代码非常有必要,这也是Reqable实际的处理方式。

1.3.2 组件通信机制

除了状态管理,另一个非常重要的机制就是组件通信。例如当底部栏左下角点击侧边栏图标后,侧边栏状态需要展开&#x

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值