本文由得物技术团队 Uni 分享,即时通讯网收录时有内容订正和排版优化。
一、引言
本文要分享的是得物技术团队基于 Electron 开发客服 IM 桌面端的技术实际过程,内容包含桌面技术选型、Electron 的根底概念、具体的施行技术计划、遇到的辣手问题等。
Electron 社区尽管很沉闷,然而不一样的场景遇到的技术问题,简直找不到对应的解决方案,咱们很多都是在摸索过程中一直的去欠缺,心愿本文能带给你一些启发。
学习交换:
- 挪动端 IM 开发入门文章:《新手入门一篇就够:从零开发挪动端 IM》
- 开源 IM 框架源码:https://github.com/JackJiang2011/MobileIMSDK(备用地址点此)
(本文已同步公布于:http://www.52im.net/thread-4159-1-1.html)
二、系列文章
本文是系列文章中的第 7 篇,本系列总目录如下:
《IM 跨平台技术学习(一):疾速理解新一代跨平台桌面技术——Electron》
《IM 跨平台技术学习(二):Electron 初体验(疾速开始、跨过程通信、打包、踩坑等)》
《IM 跨平台技术学习(三):vivo 的 Electron 技术栈选型、全方位实际总结》
《IM 跨平台技术学习(四):蘑菇街基于 Electron 开发 IM 客户端的技术实际》
《IM 跨平台技术学习(五):融云基于 Electron 的 IM 跨平台 SDK 革新实际总结》
《IM 跨平台技术学习(六):网易云信基于 Electron 的 IM 音讯全文检索技术实际》
《IM 跨平台技术学习(七):得物基于 Electron 开发客服 IM 桌面端的技术实际》(* 本文)
三、业务背景
随着公司业务的疾速倒退,商家客服也纳入了咱们的服务范畴,商家客服工作台的定位是通过工具和数据服务商家,一站式解决用户购买征询诉求。通过工具和经营策略帮助商家晋升服务品质,让品牌商家有能源经营好潜在的客户,从而达到晋升用户服务的指标。已有 web 端聊天零碎的前提下,商家客服为什么要迁徙桌面利用?首先咱们收到局部商家客服反馈:
用户是上帝,咱们是很器重用户的反馈的,所以首先咱们想的是如何在 web 端解决这些问题,
上面咱们逐个剖析下以上问题咱们能不能在网页端解决呢?
1)针对客服 A 同学问题:大多数客服职场的台式机是不会装置音频设备,如果人家没音频,没外音,咱们能强制他买个播放器吗,那必定是不能.,如果是自营客服还有点解决计划,真须要,公司能够对立洽购,然而 ToC 的显然不能强制做什么事件,所以此问题无解.
2)针对客服 B 同学问题:这句话怎么了解呢?是这样的,在一屏既有 web 浏览器,又有其余利用如飞书之类的 PC 利用叠着放,web notification 告诉因为是浏览器级别的,揭示不到最上层,浏览器的揭示的确有点弱(看不到揭示会影响到客服的首响,首响会影响客服的绩效,咱公司对于用户的服务效率是比拟严格的),所以此问题无解。
3)针对客服 C 同学问题:em。。。好的,您说的对,web 网页给商家客服的感觉就是咱们平台有点赶不上局势。
基于下面的一些场景,想必大家曾经对为何做桌面利用有个初步的理解。上面以一张图来看下 Web 利用跟桌面利用的区别。
四、技术选型
为什么会抉择 Electron 而不是其余利用开发框架?
4.1、Electron 架构简介
Electron 的形成次要是下面的 3 个大模块,每个模块各司其职,让 Electron 有了桌面利用的能力。
一一了解 Electron 的 3 个大模块:
1)Chromium:能够为 Electron 提供 UI 渲染能力,再加上 Chromium 自身就是跨平台的,所以也不必思考代码的兼容性(只有有 Chromium,就能用 JavaScript,HTML,CSS 这些前端开发工程师所熟知的三剑客来开发页面);
2)Node.js:Chromium 并不具备原生 GUI 操作的能力,所以 Node.js 正好补足了这个能力(可能调用操作系统的底层 API,比方 path、fs、crypto 这些模块,甚至能集成 C ++);
3)Native APIs:Native API 让 Electron 有了跨平台和桌面端的原生能力(比如说它有对立的原生界面,窗口、托盘这些)。
4.2、Electron 与其余框架的区别
如上图所示:
1)Native(C++/C#/Objective-C)不论从原生体验、包的体积、性能方面来说都是最佳的抉择,然而开发门槛高、迭代速度慢;
2)QT 是基于 C ++ 的跨平台开发框架,跨平台利用非常宽泛 (Mac、Windows、ios、Android、Linux、嵌入式),家喻户晓的 WPS 就是用 QT 开发的。性能很好,甚至于能够媲美原生的体验,然而整体门槛还是比拟高的;
3)Web 技术的代表 Electron 和 NW.js,相比之前抉择 Electron,Electron 有十分沉闷的社区(有 102k star),有 Atom、vscode 这样的大型利用都是基于 Electron 开发的,性能相比于 natvie 是必定要差一些,但综合来看,Electron 是作为开发桌面利用的目前首选;
4)值得一提的是 Flutter desktop,从渲染原理看 flutter 是 skia 自绘性能优于 Electron,但问题还是稳定性和生态。Electron 因为是 nodejs+chromium,前端的生态能够间接用,所以 Flutter desktop 就不纳入思考范畴的,但值得关注。
除了以上这些,最次要的一点:Electron 能疾速交付,业务层复用 web 零碎的代码,只须要关注主过程就好了,并且也能满足业务须要的零碎级别的一些性能。
五、技术实现
5.1、我的项目架构
首先介绍下 Electron 框架外面两个重要的概念主过程和渲染过程。
1)主过程:次要负责创立和治理 BrowserWindow 实例以及应用程序事件。它能够执行注册全局快捷方式,创立零碎菜单和对话框,响应自动更新事件等操作(主过程以及所有 Node.js 模块中都提供了一部分 Electron API);
2)渲染过程:渲染过程负责运行应用程序的用户界面,渲染过程中提供了所有 DOM API、Node.js API 和 Electron API 的子集。
如下面截图:关上 Electron 我的项目之后会有多个过程,一个我的项目有且只有一个主过程,创立窗口等无关零碎事件写在主过程中进行,然而渲染过程可能有多个。
那为什么会有多个渲染过程呢?
Electron 利用是 Chromium 内核,所以多过程的架构也来源于 Chromium,Chromium 会独自运行每个标签,任何一个标签页解体了都不会影响到其余标签。因而,每个过程在本人的空间中运行,由操作系统调度。如果某个过程触发了有限循环,也不会导致整个利用 down 掉。
在上文说到两个字“迁徙”:是的,咱们在开发桌面利用之前有十分成熟的 web 端商家客服聊天零碎了,所以咱们在开发桌面利用的时候大多数时候是关怀主过程的,渲染过程并不太须要关怀。
5.2、主过程功能模块
5.2.1 通信模块
次要是调用 Electron 框架自身的 API 以及通用办法的封装:
5.2.1.1)主过程到渲染过程的通信:
5.2.1.2)渲染过程到主过程的通信:
有两种计划。
计划一:是在主过程开启了 nodeIntegration: true 之后在渲染过程外面能够应用 window.require(‘Electron’)来引入写通信相干代码:
计划二:是须要在主过程编写 preload.js(在初始化窗口的时候引入):
5.2.1.3)通信的同步和异步问题:
异步:渲染过程 -> 发送 -> 主过程
同步:渲染过程 -> 发送 -> 主过程
5.2.2 菜单模块
次要是调用 Electron 框架自身的 API,满足疾速扩大菜单性能以及自定义菜单性能:
然而商家客服我的项目没用到原生菜单,而是用了自定义的菜单。
没有应用原生菜单的次要起因是:
1)原生菜单款式较死板,不能调整;
2)自定义编写菜单能有各种本人想要的性能,可管制其展现。
5.2.3 托盘模块
托盘属于零碎级的操作,所以是在主过程中设置的。在开始之前须要留神的中央,设置托盘必须在程序 ready 之后。
实现较简略,代码如下:
5.2.4 异样解决模块
次要调用 Electron 框架自身 API,联合 Node.js API,检测零碎异样后主动刷新并上报,渲染过程的异样曾经应用 sls&arms 解决,主过程的异样次要是通过 Electron 的 crashReporter API 来记录日志。
下面提交参数有两个须要留神的点:
1)submitURL 是以 post 形式上传;
2)extra 一个你能够定义的对象,附带在解体报告上一起发送(只有字符串属性能够被正确发送,不反对嵌套对象)。
5.3、渲染过程功能模块
渲染过程的代码大部分跟商家客服 IM web 端统一,很多只是迁徙即可。
5.3.1 登录革新
登录信息本地化,在登录胜利的时候,把账号信息缓存,下次关上利用的时候客服无需再从新输出,间接从缓存获取即可。
逻辑如下图所示:
5.3.2 动态资源
传统 Web 利用,将我的项目代码部署服务器,我的项目运行时,拜访的是服务器动态资源,当初版本公布流程,走的是 cdn 资源,总而言之都是通过网络获取。
Electron 提供将动态资源打包到安装程序,在装置时,将我的项目文件同步装置到用户电脑,使其具备拜访本地文件,缩小了申请占用资源。肯定水平上也能改善因网速问题导致的动态资源不能实时获取,页面白屏问题。
5.3.3 数据存储
Electron 利用外面的数据存储是通过 Electron-store 第三方库来实现的。实现比较简单,如下:
5.3.4 渲染过程打包
这块为什么要单拎进去讲渲染过程打包呢,是因为 web 我的项目迁徙变成利用渲染过程的时候不能像 web 利用一样间接打包,须要调整申请 API 代码,API 前缀须要辨别本地调试和应用环境。
代码如下:
应用 Electron, 将我的项目打包成离线利用。应用 file 协定,在本地读取动态资源。然而 ajax 申请如果用相对路径,打包之后,会间接找到根目录。如下截图。
所以打包的时候须要给 ajax 提供残缺的 url 门路。
六、技术挑战
6.1、概述
咱们在从 0 到 1 搭建商家客服 IM 桌面端的过程中,遇到了很多的问题。
起因是 Electron 社区尽管很沉闷,然而不一样场景遇到的问题,简直找不到对应的解决方案,所以很多都是在摸索过程中一直的去欠缺。
这里次要围绕公布构建流程和安全性来讲下,咱们是怎么解决的。
6.2、安全性问题
Electron 客户端的平安问题也是十分重要的,那都遇到了哪些平安问题以及咱们又是如何解决的呢?
具体如下:
1)渲染过程 XSS:Electron 实现的桌面端软件渲染层的原理理论是通过 chrome 内核渲染的,同样存在 XSS 注入的危险(举个例子:在 html 页面中能够执行命令:,就能够关上以后操作系统的计算器。接入了公司对立的 XSS 治理计划,该问题即失去解决);
2)用户认证信息透露问题:商家客服桌面端登录调用商家的受权接口,APP 网关有校验,能够确保登陆没有问题;
3)本地缓存明文读取问题:本地数据透露(例如:indexDB、localStorage、sessionStorage 等),咱们次要用加密和解密算法对本地缓存信息进行解决。
没有相对的平安,咱们能做的就是尽可能的进步平安门槛,过程中咱们也踊跃同公司的安全部门进行沟通,让他们排查桌面端公布之后的安全漏洞,最终验证都是满足平安规范,合乎公布的条件。
6.3、公布构建流程
利用公布波及到渲染过程和主过程,渲染过程次要是负责给主过程提供渲染包,主过程应用 Electron-builder 库来打包部署所公布的包。
后面曾经说过:Electron 的益处是能够无缝集成 web 端的业务逻辑代码,这里上图右边红色的是 web 端构建出的产物,咱们会把这部分构建产物同步到主过程的 app/render 目录下(即渲染过程目录),这样在打包利用包的时候,就能集成渲染过程的业务逻辑,而不须要保护两份 web 端的代码。
此计划还存在不少的缺点:因为生产构建环境须要 window 环境,所以临时不反对在近程打包,目前都是在本地 window 机器上打出残缺的包之后再上传到 CDN,商家客服通过加载 CDN 的更新包来替换本地安装文件,实现软件的本地装置。
6.4、利用更新问题
利用开发离不开“更新”这个话题,比方飞书利用会时不时弹出一个更新窗口,让你抉择是否更新。咱们的商家客服 IM 在推广桌面利用之后,也存在更新这个问题。
在业务疾速倒退的同时,如何将业务需要更好的同步给商家应用,这是商家客服桌面利用面临的最大的挑战。
6.4.1 全量更新:手动下载安装
这是最根底的更新模式,次要思路是在关上 app(其余时候也行,咱们业务次要是关上 app 的时候)的时候拜访近程的 json 文件,文件内容蕴含版本号,更新内容等等最新版本的信息,拿到近程版本号会跟本地利用版本号做比拟,如果版本号不统一,就询问用户是否更新,须要更新的话会下载到本地,用户手动点击装置即可。
这个更新形式不举荐应用,如果你的利用一年更新一次,ok,是能够这么做的。
6.4.2 增量更新
在网速快的状况下,全量更新跟增量更新简直是没有区别的。然而网速慢的状况下它俩之间的差距会被放大,用户体验不是很好。
咱们不能想当然的认为所有用户网速都很好,这是不事实的,所以不论是 PC 利用还是挪动端利用,大多数状况下是须要做增量更新。
上面表格是网速不一样状况下的下载耗时比照:
6.4.3 增量更新计划 1:electron-updater
当初就开始介绍咱们在商家客服 IM 利用(windows 利用)中是怎么实现增量更新性能的。
更新在大的分类上辨别全量以及增量更新,在每个小分类外面也辨别强更新、弱更新(业务上的辨别,底层实现没区别)。
简略来说:
1)强更新指的是用户必须更新,不更新将无奈应用零碎性能;
2)弱更新指的是用户想要的时候再去触发利用的更新,齐全由用户自主抉择。
更新流程:
其中 electron-updater 作用于“更新利用”这个节点,次要是依赖新旧版本 blockmap 文件的比照来实现增量更新。下图为 electron-builder 打包进去的 release 包,每次打包都会有对应的 blockmap 文件。
electron-updater 更新实现次要流程分两大步。
生产的 blockmap 文件:
1)应用 7z 压缩安装包;
2)读取安装包的 header;
3)计算出每个 file 的 offset 和 end 失去相应的 hash 生产 blockmap。
应用 blockmap 文件:
1)下载云上的 blockmap 文件跟本地 blockmap 文件比照(从下面截图能够看出 blockmap 文件很小,所以下载并不会对利用性能产生影响);
2)应用 range,request(范畴申请)申请更新内容的局部。
6.4.4 增量更新计划 2:文件替换
还有一种增量更新形式就是文件替换,只更新须要更新的模块。
这种形式只更新须要渲染过程的资源,大部分状况下主过程的资源不必更改,所以下载的资源会比拟小,更新较快。因为是在线热更新,更新实现后不必重新启动软件,只须要刷新页面从新加载资源即可。
其实之前我觉的这样的思路挺好的,看上面的流程图也是能够实现的,也很合乎商家客服桌面利用产品需要。
可是起初发现其实疏忽了以下两个点:
1)替换用户本地文件这个自身有权限问题(比方 windows 用户装置到了 C 盘,写入文件是有管理员权限限度的);
2)文件被占用问题(家喻户晓,当文件夹中存在正在被占用的文件时,删除会失败)。
所以在笼罩原文件同时须要退出利用防止占用,所以这个形式也不是很牢靠。
七、遇到的问题
咱们在基于 Electron 开发客服 IM 桌面端的过程无疑遇到了很多问题,我拣次要的几个问题分享一下。
问题一:Electron 的硬件加速性能,在 win7 或者 Linux 零碎上,容易呈现黑屏或者卡死:
解决方案:判断是不是 win7 及以下零碎,如果是 app.disableHardwareAcceleration(),禁用以后应用程序的硬件加速。
问题二:“Uncaught ReferenceError: require is not defined”:
这个报错是试图在渲染过程应用 node 的时候呈现的,不是不能用,只有开启 主过程的 nodeIntegration: true 就好了,但不倡议(有平安问题)。
解决方案:
问题三:“Note:you may have one or two (large) stale temporary file(s) left in your temporary directory (Generally this only happens on Windows 9x)”:
这个是打包了半天都打不进去一个残缺的包的状况下呈现的。
解决方案:过后是因为我没删除原来的包导致我放打包文件的 C 盘满了。所以删除一些缓存就好了,nsis 打包大概率都是跟磁盘无关。
问题四:下载 npm 包特地慢:
解决方案:yarn 装置、Electron 相干的包优先应用淘宝镜像装置、应用公司镜像安装公司外部包。
八、本文小结
一路开发下来,感叹很多。
作为公司第一个 Electron 利用,不论是在开发上,打包上,或者说在部署上,都遇到了一些挑战。
在网上也没有比拟具体的文档,里面做的好的也不会把具体计划分享进去。然而即便遇到了这些问题,也不能否定 Electron 是目前最适配于咱们业务指标以及适配于开发资源的一个框架。
目前咱们已有线上稳固版本,也逐渐在推广到全副商家客服。
接下来须要欠缺的开发流程,克服的技术难点有很多,商家客服工作台利用也会越来越欠缺。
九、参考资料
[1] Electron 官网开发者手册
[2] 疾速理解新一代跨平台桌面技术——Electron
[3] Electron 初体验(疾速开始、跨过程通信、打包、踩坑等)
[4] Electron 根底入门 简单明了,看完啥都懂了
[5] vivo 的 Electron 技术栈选型、全方位实际总结
[6] 融云基于 Electron 的 IM 跨平台 SDK 革新实际总结
[7] 闲鱼 IM 基于 Flutter 的挪动端跨端革新实际
[8] 网易云信基于 Electron 的 IM 音讯全文检索技术实际
(本文已同步公布于:http://www.52im.net/thread-4159-1-1.html)