搜2022安卓版clash

clash2天前clash节点订阅8

全网最佳IP代理服务商- 9.9元开通-稳定的代理服务
如果您从事外贸、海外视频博主、海外推广、海外广告投放,欢迎选择我们。
让您轻易使用国外主流的聊天软件、视频网站以及社交网络等等

  得物商家客服采用的是桌面端应用表现形式,而桌面端应用主要架构形式就是一套和操作系统交互的“后端” + 一套呈现界面的“前端(渲染层)”。而桌面端技术又可以根据渲染层的不同核心划分为以下几类:

  在2022年5月份左右,得物商家客服开始投入桌面端应用业务,其目标是一个可以适配多操作系统(MacOS、Windows)、快速迭代、富交互的产品。

  考虑到以上前提,我们当时可以选择的框架是Chromium家族或者Webview家族。但是当时对于Webview来说,Tauri 还并不成熟(在 2022年6月才发布了1.0版本)生态也不够丰富。

  对于pywebview和webview_java相对于前端来说,一方面门槛较高,另一方面生态也非常少。

  所以,在当时,我们选择了Chromium家族中的Electron框架。这是因为对于CEF、Electron、NW来说,Electron有着对前端开发非常友好的技术栈,仅使用JavaScript就可以完成和操作系统的交互以及交互视觉的编写,另外,Electron的社区活跃度和生态相对于其他两者也有非常大的优势。最重要的是:真的很快!

  但是,随着时间的推移,直到2024年的今天,商家客服的入驻量和使用用户越来越多,用户的电脑配置也是参差不齐,Electron的弊端开始显现:

  性能方面:随着商家客服入驻数量的快速增加,现有Electron桌面应用在多账户+多会话高并发场景下,占用内存特别大,存在性能瓶颈;

  安全方面:Electron在内存安全性、跨平台攻击、不受限制的上下文和依赖管理等方面存在一些潜在的弱点;

  信息集成方面:商家客服目前需要在商家后台、商家客服后台、商家客服工作台3个系统来回切换操作,使用成本很高。

  我们也发现,之前调研过的Tauri作为后起之秀,其生态和稳定性在今天已经变得非常出色,我们熟知的以下应用都是基于Tauri开发,涵盖:游戏、工具、聊天、金融等等领域:

  除此之外,因为Tauri是基于操作系统自带的Webview + Rust的框架。首先,因为不用打包一个Chromium,所以包体积非常的小:

  内存安全:Rust通过所有权和借用机制,在编译时检查内存访问的安全性,避免了常见的内存安全问题,如空指针引用、数据竞争等;

  零成本抽象:Rust提供了丰富的抽象机制,如结构体、枚举、泛型等,但不引入运行时开销。这意味着开发者可以享受高级语言的便利性,同时保持接近底层语言的性能;

  并发性能:Rust内置支持并发和异步编程,通过轻量级的线程(称为任务)和异步函数(称为异步任务)来实现高效的并发处理。Rust的并发模型保证了线程安全和数据竞争的检查,以及高性能的任务调度和通信机制;

  可靠性和可维护性:Rust强调代码的可读性、可维护性和可靠性。它鼓励使用清晰的命名和良好的代码结构,以及提供丰富的工具和生态系统来支持代码质量和测试覆盖率;

  要实现Electron迁移到Tauri,得先分别了解Electron和Tauri的核心功能和架构模型,只有了解了这些,才能对整体的迁移成本做一个把控。

  首先来看看Electron的基础架构模型:Electron继承了来自Chromium的多进程架构,Chromium始于其主进程。从主进程可以派生出渲染进程。渲染进程与浏览器窗口是一个意思。主进程保存着对渲染进程的引用,并且可以根据需要创建/删除渲染器进程。

  每个Electron的应用程序都有一个主入口文件,它所在的进程被称为 主进程(Main Process)。而主进程中创建的窗体都有自己运行的进程,称为渲染进程(Renderer Process)。每个Electron的应用程序有且仅有一个主进程,但可以有多个渲染进程。

  打包一个Electron应用程序简单来说就是通过构建工具创建一个桌面安装程序(.dmg、.exe、.deb 等)。在Electron早期作为 Atom 编辑器的一部分时,应用程序开发者通常通过手动编辑Electron二进制文件来为应用程序做分发准备。随着时间的推移,Electron社区构建了丰富的工具生态系统,用于处理Electron应用程序的各种分发任务,其中包括:

  这样,应用程序开发者在开发Electron应用时,为了构建出跨平台的桌面端应用,不得不去了解每个包的功能并需要将这些功能进行组合构建,这对新手而言过于复杂,无疑是劝退的。

  所以,基于以上背景,目前使用的比较多的是社区提供的Electron Builder()一体化打包解决方案。得物商家客服也是采用的上述方案。

  现在绝大多数的应用签名都采用了签名狗的应用签名方式,而我们的商家客服桌面端应用也是类似,Electron Builder提供了一个sign的钩子配置,可以帮助我们来实现对应用代码的签名:

  那么,Tauri的基础架构模型是什么样的?其实官网对这块的介绍比较有限,但是我们可以通过其源码仓库和代码结构管中窥豹的了解Tauri的核心架构模型,为了方便大家理解,我们以得物商家客服桌面端应用为模型,简单的画了一个草图:

  由于Web技术具有表现力强和开发成本低的特点,与 Electron 和NW等框架类似,Tauri应用程序的前端实现是使用Web技术栈编写的。那么Tauri是如何解决Electron/CEF等框架遇到的Chromium内核体积过大的问题呢?

  也许你会想,如果每个应用程序都需要打包浏览器内核以实现Web页面的渲染,那么只要所有应用程序共享相同的内核,这样在分发应用程序时就无需打包浏览器内核,只需打包Web页面资源。

  跨平台应用窗口创建库,使用Rust编写,支持Windows、MacOS、Linux、iOS和Android等所有主要平台。该库是winit的一个分支,Tauri根据自己的需求进行了扩展,如菜单栏和系统托盘功能。

  这个API是一个JS库,提供调用Tauri Rust后端的一些API能力,利用这个库可以很方便的完成和Tauri Rust后端的交互以及通信。

  Tauri的主进程使用Rust编写,Tauri在主进程中提供了一些常用的Rust API比如窗口创建、消息提醒... 如果我们觉得主进程提供的API不够,那么我们可以通过Tauri的插件体系自行扩展。

  Tauri的渲染进程则是运行在操作系统的Webview当中的,我们可以直接通过JS + HTML + CSS来编写,同时,Tauri会为渲染进程注入一些全局的JS API函数。比如fs、path、shell等等。

  Tauri提供了一个CLI工具:,通过这个CLI工具的一个命令,我们可以直接将应用程序打包成目标产物:

  第一次运行此命令需要一些时间来收集Rust包并构建所有内容,但在随后的运行中,它只需要重新构建您的应用程序代码,速度要快得多。

  Tauri的签名和Electron类似,如果需要自定义签名钩子方法,在Tauri中现在也是支持的:

  通过上面的架构模型对比,我们可以很直观的感受到如果要将我们的Electron应用迁移到Tauri上,整体的迁移改造工作可以总结成以下图所示:

  渲染进程的迁移:渲染进程改造相对而言就少很多了,因为Tauri和Electron都可以直接使用前端框架来编写渲染层代码,所以几乎可以将之前的前端代码直接平移过来。但是还是有一些小细节需要注意,比如IPC通信、JS API的改变、兼容性... 这部分后面也会详细介绍。

  应用构建打包:从之前的Electron构建模式改成Tauri构建模式,并自动化整个构建流程和链路。

  应用签名&更新:签名形式不用改,主要需要调整签名的配置,实现对Tauri应用的自动签名和自动更新能力。

  在聊如何调整Tauri目录结构之前,我们需要先来了解一下之前的Electron应用目录结构设置,一个最简单的Electron应用的目录结构大致如下:

  有的时候你可能需要划分目录来编写不同功能的代码,但是,不管功能目录怎么改,最终的渲染进程和主进程的构建产物都是期望符合类似于上面的结构。

  对于Tauri来说,Tauri打包依托于两个部分,首先是对前端页面的构建,这块可以根据业务需要和框架选择(Vue、 React)进行构建脚本的执行。一般前端构建的产物都是一个dist文件包。

  然后是Tauri后端程序部分的构建,这块主要是对Rust代码进行编译成binary crate。

  (Tauri后端的编译在很大程度上依赖于操作系统原生库和工具链,因此当前无法进行有意义的交叉编译。所以,在本地编译我们通常需要准备一台mac和一台Windows电脑,以满足在这两个平台上的构建。)

  整体来看,和Electron是差不多的,这里,我们就直接使用了官方提供的create-tauri-app()脚手架来创建项目,其目录结构大致如下:

  所以,这里对渲染进程的目录调整就很清晰了,直接将我们之前Electron中的renderer-process目录中的代码迁移到src目录中即可。

  商家客服中会有一些接口请求,这些接口请求有的是从业务中发起的,有的使用依赖的npm库中发起的请求。但因为是客户端引用,当从客户端环境发起请求时,请求所携带的origin是这样的:

  那么,就会遇到一个我们熟知的一个前端跨域问题。这会导致如果不在access-ctron-allow-origin中的域名会被block掉。

  如果有小伙伴对Electron比较熟悉,可能会知道在Electron实现跨域的方案之一是可以关闭浏览器的跨域安全检测:

  或者在请求返回给浏览器之前进行拦截,手动修改access-ctron-allow-origin让其支持跨域:

  虽然Tauri虽然和Electron进程模型很类似,但是本质上还是有区别的,最大的区别就是Electron中的渲染进程是基于Chromium魔改的,他可以在Chromium中植入一些控制器来修改Chromium的一些默认行为。但Tauri完全是基于不同平台的内置Webview封装,考虑的兼容性问题,并没有对Webview进行改造(虽然Windows的Webview2支持 --disable-web-security,但是其他平台不行)。所以他的跨域策略是Webview默认的行为,无法调整。

  既然浏览器会因为跨域问题block掉请求,那么就绕过浏览器呗,没错,这也是Tauri官方提供的http模块设计的初衷和原理:,其设计方案就是通过JavaScript前端调用Rust后端来发请求,当请求完成后再返回给前端结果。

  问题:Tauri http有一套自己的API设计和请求规范,我们必须按照他定义的格式进行请求的发送和接收。对于新项目来说问题不是很大,但对商家客服来说,这样最大的问题是之前的所有的接口请求都得改造成Tauri http的格式,我们很多请求是基于Axios的封装,改造成本非常大,回归验证也很困难,而且有很多三方npm包也依赖axios发请求,这就又增加了改造的成本和后期维护的成本。

  既然使用axios改造成本大,那么就写一个axios的适配器(adapter)在数据请求的时候不使用浏览器原生的xhr发请求而是使用tauri http来发请求,顺便对axios的请求参数进行格式化,处理成Tauri http要求的那种各种。在请求响应后也进行类似的处理。

  问题:假设项目中依赖一个npm库,这个库中发起了一个axios请求,那么也需要对这个库的axios进行适配器改造。这样还是解决不了三方依赖使用axios的问题。我们还是需要侵入npm包进行axios改造。另外,如果其他库使用的是xhr或者fetch来直接发请求或者,那就又无解了。

  最后,不管使用方案1还是2,都有个通病,那就是请求都是走的Tauri后端来发起的,这也意味着我们将在Webview的devtools中的network看不到任何请求的信息和响应的结果,这对开发调试来说无疑是非常难以接受的。

  为了让请求日志能出现在浏览器的webview devtools network中,我们可能需要开发一个类似于chrome plugin的方式来支持。但是很可惜,在Tauri中,webview是不支持插件开发的:

  所以我们只能采用新的方式来支持,那就是外接devtools。啥意思呢?就是在操作系统网络层代理掉网络请求,然后输出到另一个控制台中进行展示,原理类似于Charles。

  这里需要注意的是,Tauri使用的是系统自带的Webview,而Electron则是直接内置了Chromium,这里有个非常大的误区在于想当然的把Webview类比Chromium以为浏览器的API都可以直接使用。这其实是不对的,举个例子:我们在发送一些消息通知的时候,可能会使用HTML5的 Notification Web API:

  但是,这个API是浏览器自行实现的,也就是说,你在 Electron 中可以这么用,但是,如果你在Tauri中,你会发现一个bug:,这个bug的大概含义就是Tauri中的Notification不会触发click点击事件。这个bug至今还未解决。究其原因:

  差异化操作系统原生窗口的拖拽和最大化事件:在Windows和Linux上,当鼠标按下时拖动,双击时最大化;而在MacOS上,最大化应该在鼠标抬起时发生,如果双击后鼠标移动,应该取消最大化。

  所以,我们在对商家客服从Electron迁移到Tauri的过程中,还需要对这些关键性API进行兼容性测试和回归。一旦发现相关API不符合预期,我们需要及时调整业务策略或者给尝试进行hack。

  (这里卖个关子,虽然Tauri不支持对Notification的点击事件回调,那么我们是怎么让他支持的呢?在下一节主进程代码迁移中我们会详细介绍。)

  对于样式兼容性来说,因为Electron在不同操作系统内都集成了Chromium所以我们完全不用担心样式兼容性的问题。但是对于Tauri来说,因为不同操作系统使用了不同的Webview,所以在样式上,我们还是需要注意不同操作系统下的差异性,比如:以下分别是Linux和Windows渲染Element-Plus的界面:

  除了上述问题,如果你需要兼容Linux系统,那么还有webkitgtk在非整数倍缩放下的bug,应该是陈年老问题了。当然,这些问题都是上游webkitgtk的“锅”。

  所以,社区也有关于讨论Tauri是否有可能在不同平台上使用同一个webview的可能性的讨论:。官方是期待能有Mac版本的Webview发布,不过大概率来看不太现实,一方面是因为:微软决定不开源 Webview2的Mac和Linux版本(),另一方面是如果要使用统一的webview那就又回到了Electron。

  除了样式兼容性外,对于JS代码的兼容性也需要留意Tauri在Windows上使用的是Webview2而Webview2本身就是基于Chromium的,所以代码兼容性倒还好,但是在MacOS 上使用的就是WebKit.WKWebview,Safari就是基于他,所以到这里,我想你也明白了,这就又回到了前端处理不同浏览器兼容性的问题上来了。所以这里温馨提示一下:构建时前端代码需要进行polyfill。

  对于Electron应用的用户来说,可能没有这样的烦恼,最新的API只要Chrome支持,那就可以用。

  在有些情况下,操作系统的原生窗口并不能符合我们的一些视觉和交互需求搜2022安卓版clash。所以,在创建桌面应用的时候,有时候我们希望能完全掌控窗口的样式,而隐藏掉系统提供的窗口边框和标题栏等。这个时候就需要用到自定义操作栏窗口。比如在Windows中,我们希望在右上角有一排自定义的操作栏,就像是这样:

  商家客服桌面端的窗口就是一个无边框的自定义操作栏的窗口,在Electron中,我们可以这样操作快速创建一个无边框窗口:

  但是在Tauri中,要实现自定窗口首先需要在窗口创建的时候设置decoration无装饰样式,比如这样:(也可以在tauri.config.json中设置,道理是一样的)

  通过使用窗口单例模式,可以确保应用程序在用户尝试多次打开时只会有一个主窗口实例,从而提高用户体验并避免不必要的资源占用。在Electron中可以很容易做到这一点:

  其在Windows下判断单例的核心原理是借助了windows_sys这个Crate中的CreateMutexW API来创建一个互斥体,确保只有一个实例可以运行,并在用户尝试启动多个实例时,聚焦于已经存在的实例并传递数据,简化后的代码大致如下:

  (注意:这里有坑,如果你的应用需要实现一个重新启动功能,那么在单例模式下将不会生效,核心原因是因为应用重启的逻辑是先打开一个新的实例再关闭旧的运行实例。而打开新的实例在单例模式下就被阻止了,这块的详细原因和解决方案我们已经给Tauri提了PR:)

  前面我们有提到,在Electron中,我们需要显示来自渲染进程的通知,那么可以直接使用HTML5的Web API来发送一条系统消息通知:

  当然,Electron也提供了主进程使用的API,更多的能力可以直接参考Electron的官方文档:。

  然而,对于Tauri来说,只实现了第1个能力,也就是消息触达。Tauri本身不支持点击回调的功能,这就导致了用户发来了一个消息,但是业务无法感知客服点击消息的事件。而且原生的Web API也是Tauri自己写的,原理还是调用了Rust的通知能力。接下来,我也会详细介绍一下我们是如何扩展消息点击回调能力的。

  所以我们需要自定义一个Notification的Tauri插件,实现对点击回调的能力。(因为篇幅原因,这里只介绍一些核心的实现逻辑)

  windows::UI::Notifications::ToastNotification::CreateToastNotification:这个函数的作用是根据指定的参数创建一个Toast通知对象,可以设置通知的标题、文本内容、图标、音频等属性,并可以指定通知被点击时的响应行为。通过调用这个函数,可以在Windows应用程序中创建并显示自定义的Toast通知,向用户展示相关信息。

  windows::UI::Notifications::ToastNotificationManager::CreateToastNotifierWithId:通过调用CreateToastNotifierWithId函数,可以创建一个Toast通知管理器对象,并指定一个唯一的标识符。这个标识符通常用于标识应用程序或者特定的通知渠道,以确保通知的正确分发和管理。创建了Toast通知管理器之后,就可以使用它来生成和发送Toast通知,向用户展示相关信息,并且可以根据标识符进行个性化的通知管理。

  但是winrt_notification这个库,只完成了1-3步骤,所以我们需要手动实现步骤4。核心代码如下:

  在Windows 7中,Tauri调用的是win7_notifications这个库,这个库本身也没有实现对消息点击的回调处理,我们需要扩展win7_notifications的能力来实现对消息通知的回调事件。我们希望这个库可以这样调用:

  而我们要做的,就是为win7_notify这个库中的Notification结构体增加一个click_event函数,这个函数支持传入一个闭包,这个闭包在点击消息通知的时候执行。

  MacOS mac_notification_sys库本来就有点击回调,只是Tauri没有捕获处理,需要自定义捕获处理逻辑就好了。

  Windows 7中,消息通知其实是通过绘制窗口和监听鼠标点击来触发的,但是win7_notify本身也没有支持用户对点击回调的捕获,也需要扩展这个库的点击捕获能力。

  Tauri CLI默认情况下使用当前编译机器的体系结构来编译可执行文件。假设当前是在64位计算机上开发,CLI将生成64位应用程序。如果需要支持32位计算机,可以使用--target标志使用不同的Rust目标编译应用程序:

  其次,需要为构建增加不同的环境变量,以便为了在不同的环境进行代码测试,对应到package.json中的构建代码:

  综合比较下来,embedBootstrapper目前是比较好的方案,一方面可以减少安装包体积,一方面减少不必要的静态资源下载。

  MacOS操作系统也有M1和Intel的区分,所以为了可以构建出兼容两个版本的产物,我们需要使用universal-apple-darwin模式来编译:

  对于Tauri来说,应用更新的详细配置步骤可以直接看官网的介绍:。这里为了方便大家理解,简单画了个更新流程图:

  quiet:安静模式表示无需用户交互。如果安装程序需要管理员权限(WiX),则需要管理员权限。

  需要注意的是:如果以为更新是增量更新,不会卸载之前已经安装好的应用程序只更新需要变更的部分。其实是不对的,整个安装过程可以理解为Tauri在后台帮你重新下载了一个最新的安装包,然后帮你重新安装了一下。

  总结:更新的核心原理就是通过使用Windows的PowerShell来对下载后的安装包进行open。然后由安装包进行安装。

  通过cmd调用PowerShell来安装时,会在安装过程中出现一个蓝色的PowerShell控制台一闪而过:

  在部分开启了病毒防护的Windows电脑上,使用PowerShell来执行对安装包的打开,会报错:Permission Denied,导致安装更新失败:

  这些都是因为Tauri直接使用Powershell的问题,那需要怎么改呢?很简单,那就是使用Windows操作系统提供的ShellExecuteW来运行安装程序,核心代码如下:

  但是这块是Tauri的源码,我们没法直接修改,但这个问题的解决方法我们已经给Tauri提了PR并已合入到官方的1.6.8正式版本当中:

  Tauri应用程序签名可以分成2个部分,第一部分是应用程序签名,第二部分是安装包程序签名,官网上介绍的签名方法需要配置tauri.config.json中如下字段:

  如果你按照官方的步骤来进行签名:,很快就会发现问题所在:官网中签名有一个重要的步骤就是导出一个.pfx文件,但是现在业界签名工具基本上都是采用签名狗的方式进行的,这是一个类似于U盾签名工具,需要插入电脑中才可以进行签名,不支持直接导出.pfx格式的文件:

  然后需要插入我们在签名机构购买的USB key。这样,在构建的时候,就会提示让我们输入密码:

  不过对于我们而言,USB key签名狗是整个公司共享的,通常不在前端开发手里(尤其是异地办公)。一种做法是在Tauri构建的过程中,对于需要签名的软件提供一个signCommand命令钩子,并为这个命令传入文件的路径,然后交由开发者对文件进行自行签名(比如上传到拥有签名工具的电脑,上传上去后,远程进行签名,签名完成再下载)。所以这就需要让Tauri将签名功能暴露出来,让我们自行进行签名,比如这样:

  该命令中包含一个%1,它只是二进制路径的占位符,Tauri在构建的时候会将需要签名的文件路径替换掉%1。

  这个功能官网上还没有更新相关的介绍,所以你可能看不到这块的使用方式,因为也是我们最近提交的PR:。不过目前,这个PR已经被合入Tauri的主版本中,你要做的就是就是升级Tauri到1.7.0升级@tauri-apps/cli到1.6.0。

  经过我们的不懈努力(不断地填坑)到目前,得物商家客服Tauri版本终于如期上线,基于Tauri迁移带来的收益如下:

  直到2024年的今天,Tauri依然还不是特别完美,目前官方主要精力是放在了2.0的开发上,对于1.x的版本维护显得力不从心,主要原因也是因为官方人少。

  除此之外,Electron实现了对Chromium的高级定制,因此在Electron中,我们可以使用BrowserView这样的功能,相对于Electron来说,Tauri目前所做的仅仅是对Webview的封装,Webview不支持的功能暂时都不行。另外,系统性的API确实少的可怜。如果要实现一些其他的功能,比如自动更新显示进度条等能力,就不得不使用Rust来扩展API。然后Rust语言学习成本是有一点的,所以,也给我们日常开发带来了不少挑战。

  因为Tauri在Windows系统上比较依托于Webview2作为渲染的容器,虽然Tauri提供了检测本地电脑是否有安装Webview2以及提供联网下载的能力,但是因为Windows电脑千奇百怪,经常会出现未内置Webview2的Windows电脑下载不成功而导致程序无法启动的情况:

  对于这种情况,我们虽然可以将Webview2内置到安装包里面,在用户安装的时候进行内置解压安装,但是这样包体积就跟Electron相差不大。

  我们在将得物商家客服迁移到Tauri的过程中,就遇到了非常多的问题,有些问题是Tauri的bug。有些问题是Tauri的feature不够,有的是Rust社区的问题。单纯这一个迁移工作,我们就为Tauri社区共享了7个左右的PR:

  在遇到这些问题时,真的特别让人头大,因为社区几乎没有这些问题的答案,需要我们自己去翻Tauri的源码实现,有些是涉及到操作系统底层的一些API,因此我们必须要去看一些操作系统的API介绍和出入参说明,才能更好的理解Tauri的代码实现意图,才能解决我们碰到的这些问题。

  另外,Tauri和操作系统系统相关的源码都是基于Rust来编写的,也为我们的排查和解决增加了不少难度。最后一句名言和读者共勉:纸上得来终觉浅,绝知此事要躬行。

全网最佳IP代理服务商- 9.9元开通-稳定的代理服务
如果您从事外贸、海外视频博主、海外推广、海外广告投放,欢迎选择我们。
让您轻易使用国外主流的聊天软件、视频网站以及社交网络等等

相关文章

clash安卓全局代理怎么开

clash安卓全局代理怎么开

  我们平时在开发项目的时候或多或少都会发生一些 Crash 问题。 过多的 Crash 会影响我们 APP 的用户体验,甚至留存率,收益等。 Crashlytics 是一个能帮我们更好的...

什么路由器可以用clash

什么路由器可以用clash

  问有多少传奇,是懂 非懂,问传奇有几个绝对出众,南北西东,不去鼎拜也不去跟红,传奇到此还是不是传奇,男儿到此一游,管他青天白日满地红。会当凌绝顶,一览众山小『末代冲杯之传奇之路』...

clash 2.0 安卓下载

  有一句是是这么说的:大千世界,无奇不有。仅仅是一个地球,就让人类觉得无奇不有。那么试问整个宇宙呢?宇宙有多大,我们至今仍然探索不清楚,人类只是瀚海之中渺小的一个颗粒,怎么能看清楚这个庞...