本文由融云技术团队分享,有修订和改动。

1、引言

Electron 凭借其相对更低的研发成本投入、强大的跨平台支持、拥有基数庞大的 Javascript 开发者受众等优势,在 PC 端跨平台桌面开发领域异军突起,大受欢迎。

本文分享的是融云基于Electron的IM跨平台PC端SDK改造过程中所总结的一些实践经验,希望对你有用。

* 友情提示:如果您对Electron的基础概念还不太了解,建议您先从本系列文章的首篇《快速了解新一代跨平台桌面技术——Electron》和第2篇《Electron初体验(快速开始、跨进程通信、打包、踩坑等)》开始阅读,否则可能难以理解本文的有关内容。

学习交流:

(本文已同步发布于:http://www.52im.net/thread-4060-1-1.html

2、系列文章

本文是系列文章中的第5篇,本系列总目录如下:

3、本次改造的技术目标

针对本次改造,我们需要达到以下4个技术目标:

  • 1)需提供与传统桌面通讯软件相匹配的能力支持;
  • 2)需实现浏览器与Electron不同运行时代码的高度复用;
  • 3)便于开发者构建多窗口、多进程的复杂桌面端应用;
  • 4)需同步适配同一IM端SDK的多个版本。

以下,我们将逐条讨论这4个目标所有实现的具体技术内容。

4、技术目标1:需提供与传统桌面通讯软件相匹配的能力支持

相较于 B/S 架构的 Web 网页应用,我们期望能够在 Electron 环境下向开发者提供更为丰富的本地化能力,以及比 Websocket(或Comet)更高效的Socket实时双工通信通道。

借助这些原本在浏览器环境下不便实现的技术能力,来整体提高用户对于桌面端产品的使用体验,将 Electron 作为一个 C/S 架构软件运行平台的潜力发挥到最大。(白话就是,我们希望借助Electron这个框架,将原本Web端的一些鸡肋能力,做到像原生富客户端一样)

5、技术目标2:浏览器与Electron不同运行时代码的高度复用

由于 Electron 与标准 Web 应用拥有几乎相同的技术生态,因此多数产品会要求前端代码工程兼顾浏览器与 Electron。

也就是说,一套代码既要打包为传统桌面端应用(利用Electron),又可发布为浏览器中运行的 Web 网页应用。

基于此,我们提供的 IM SDK 需要在两种不同的运行时环境下做到差异最小化,避免开发者编写冗余的平台兼容代码。(白话就是,尽可能在基于Electron的桌面端和纯Web网页端之间重用更多的代码,不然又得多撸一个全新的Electron端,这得多费劲)

6、技术目标3:便于开发者构建多窗口、多进程的复杂桌面端应用

Electron 通过对 IPC 能力的封装为桌面端应用开发提供了较完善的跨进程通讯方案,借助此能力,开发者构建的桌面端应用也逐渐趋于复杂。

比较典型的如桌面端IM产品:通常用一个独立窗口做基础的 IM 聊天业务,一个窗口做历史聊天记录查询业务。

当有音视频会议业务场景时,还需要再开一个窗口做会议业务。

甚至有开发者提出了与每个聊天对象都保持一个独立聊天窗口的需求(产品形态如 QQ)。

在这类需求下,长连接状态维持、消息同步变得异常复杂,原因在于以下3个方面。

  • 1)若每个进程窗口都维持独立长连接,难免会出现某一进程连接与其他进程连接状态不同步。且开发者需在各进程同时维护连接状态,复杂度较高。同时还会造成服务的并发能力下降。
  • 2)若仅有单一主窗口进行连接维持,其他窗口通过 IPC 能力将主窗口作为连接代理,则需要在主进程、各渲染进程中维护复杂的跨进程通讯业务代码,从而推高项目整体的复杂度。
  • 3)目前的 Electron 开发者绝大多数来自于 Web 开发者,既有编程思维是建立在浏览器页面内单进程单线程的应用模型下构建起来的,对于处理此类多进程模型的产品开发缺乏相关的经验积累。

为降低类似需求场景的业务实现复杂度,我们需要在 PaaS 能力层面上解决多进程连接共享、多进程消息同步问题,让开发者在既有编程思维模式下将每个业务实现的更为顺畅。

7、技术目标4:需同步适配同一IM端SDK的多个版本

我们的既有Web端 IM SDK 存在一个端多个不同版本的情况(主要是为了兼容老用户,旧版本很难一刀切直接扔掉,只能新老版末同时并存)。

各版本都有不同数量的客户积累,且各版本 API 接口设计迥异,跨版本升级成本较高。

考虑到使用不同版本的客户未来将业务向 Electron 迁移的可能性,我们期望通过架构设计的改进来避免既有客户做过多的集成代码修改,在确保既有客户不因版本升级而流失的前提下降低 Web 研发团队自身的多版本 SDK 维护成本。

8、本次改造的落地实践

针对上面章节中确定的技术目标,我们将从以下3个方向着手落地实践:

  • 1)剥离各版本的共同业务与对外差异性 API 定义;
  • 2)Electron 与浏览器平台下 IM SDK 的区分;
  • 3)解决多进程消息同步、多进程连接共享问题。
  • 以下,我们将逐条分享这3个方面的具体实践内容。

9、落地实践1:剥离各版本的共同业务与对外差异性API定义

我们的 IM SDK 各版本分别为不同的代码仓库独立维护,互无干系。(白话就是,所有端的IM SDK都是独立开发,从头造轮子)

这导致所有的功能(包括即将开发的 Electron 桌面解决方案)都可能要在各个版本仓库上单独实现,不仅开发成本高,还会导致实现质量无法保证、或代码实现不统一,同时也推高了产研后续流程的测试、上线等环节的成本。

▲ IM SDK 不同版本独立维护

基于前述技术目标4的要求,在既有现状下继续开发,就意味着需要在两个版本的基础上做不同实现,既不符合程序员的代码审美,也影响团队整体的研发效率。(白话就是,如果又要从头造轮子实在太难受)

为更好地达成技术目标4,团队决定优先通过重构将既有业务分层,即各个版本所必须的业务代码抽象下沉为 IM Engine 包,并为各个版本 IM SDK 分别实现不同的API Layer以便与既有线上版本接口对齐,这样既可以降低团队的研发成本,也可以满足既有线上客户后续的升级需求。

▲ 重构代码实现业务分层

完成业务分层后,对于 IM SDK 有依赖的其他产品如 RTC SDK,也都可以摆脱对 IM SDK 接口的依赖而直接调用 Engine 层接口,业务层在拓展 RTC 业务时,也就无需再考虑 IM SDK 的版本问题。

▲ 业务分层后的结构将保证拓展性

做分层的另一个考虑还为了达成技术目标2,将与业务层的交互限制在 API 层,在 Engine 中处理 Electron 与浏览器两种运行时下的代码差异,业务层只需关心 IM SDK 的接口调用而无需关心底层差异,确保业务层在两种运行时下只需要维护极少甚至无需维护兼容代码,便于业务层更专注于业务开发。

10、落地实践2:Electron 与浏览器平台下 IM SDK 的区分

在将 Engine 与业务层隔离后(见上一节),需要考虑 Engine 在不同的运行时下的关键能力差异,并依据能力差异落实 Engine 的底层设计。

Electron 环境下的连接、消息存储等能力由 c++ 模块编写提供(即后面提到的 CppProto.node):

在浏览器与 Electron 平台下,从连接管理、到消息收发等实现方式迥异,团队需要对 Engine 包继续分层,通过 AEngine 抽象类来定义 IM Engine 的能力接口,并抽象 APIContext 类用来管理 AEngine 的能力调用。

考虑到纯 Web 应用构建尺寸问题,Electron 的能力实现代码不应被打包到标准 Web 页面内,因此还需要将 Electron 平台下的实现代码单独抽离出来作为一个独立包(即ElectronSolution),作为可选模块由开发者选择安装使用。

▲ Electron相关的代码抽离为可选模块

如上图所示,CppEngine 在 ElectronSolution 包中定义,其需要由开发者在 Electron 应用创建 BrowserWindow 实例时通过 webPreferences.preload 配置属性向渲染进程窗口预挂载。

APIContext 在初始化 AEngine 实例时,优先检测 CppEngine 是否已定义。当发现有 CppEngine 定义时,则初始化 CppEngine 提供更丰富的本地化能力,否则初始化 JSEngine。

就像下面的代码的展现的逻辑:

const engine: AEngine = typeofCppEngine !== 'undefined'

? newCppEngine()

: newJSEngine()

11、落地实践3:解决多进程消息同步、多进程连接共享问题

ElectronSolution 包截止目前的设计中,所有代码都运行在渲染进程内。

这意味着每个进程彼此独立,都在维护独立的进程状态,无法满足目标 3 中多进程状态同步、连接共享的需求。

为了解决该问题,需要将 CppProto.node 模块放到主进程,在主进程中实现连接管理、消息收发等能力,多个渲染进程通过 IPC 通信共享主进程状态。

▲ 多个渲染进程通过 IPC 通信共享主进程状态

为了达成技术目标3的要求,ElectronSolution 需要拆分为两个子包,即Main 与 Renderer。

具体就是:

  • 1)Main 包运行在主进程内,负责维持 CppProto.node 模块的调用,实现底层连接管理、消息管理等功能,同时通过 Electron 提供的 ipcMain 与各渲染进程维持通信;
  • 2)Renderer 包中定义 CppEngine 类,继承自 Engine 包内的 AEngine 抽象类,依然通过 webPreferences.preload 用来作为主进程的代理,通过 ipcRenderer 与主进程维持通信。

▲ 拆分为Main与Renderer两个子包

修改完成后,ElectronSolution 包的整体结构基本确定。

以下列出 ElectronSolution 包关键目录结构供参考:

node_modules/@rongcloud/electron-solution

├── index.js

├── main

│   ├── addon

│   │   ├── binding

│   │   │   └── electron-v{electron-version}-{platform}-{arch}.node

│   │   └── index.js

│   ├── dist

│   │   └── index.js

│   ├── index.js

│   └── package.json

└── renderer

│   ├── dist

│   │   └── index.js

│   ├── index.js

│   └── package.json

└── package.json

基于上述架构变动,当业务层需要在多个渲染进程中实现 IM 能力时,仅需要关注在各个进程中的 IM SDK 接口调用,由 ElectronSolution 处理多进程之间的状态同步问题。

当开发者期望由既有 Web 业务向 Electron 平台迁移时,开发者也无需修改既有的 Web 业务代码,仅需要增量编写主进程代码相关功能实现,将 ElectronSolution 安装并集成到 Electron 桌面端应用中即可。

最终,我们形成了以下这样的IM SDK整体结构:

12、未来的规划

除了上述IM相关业务,后续我们还打算在Electron平台下提升RTC的场景能力。

目前,Electron 平台下由 Chromium 原始提供的 WebRTC 能力对于开发桌面级音视频应用软件来说相对薄弱,我们有计划探索借助 node.js 的拓展能力,提供更为底层的 WebRTC 能力拓展如音效、音质、视频特效等。

13、参考资料

[1] 快速了解新一代跨平台桌面技术——Electron

[2] Electron初体验(快速开始、跨进程通信、打包、踩坑等)

[3] WebSocket从入门到精通,半小时就够!

[4] Comet技术详解:基于HTTP长连接的Web端实时通信技术

[5] 一套海量在线用户的移动端IM架构设计实践分享(含详细图文)

[6] Web端即时通讯技术盘点:短轮询、Comet、Websocket、SSE

[7] 搞懂现代Web端即时通讯技术一文就够:WebSocket、socket.io、SSE

(本文已同步发布于:http://www.52im.net/thread-4060-1-1.html

IM跨平台技术学习(五):融云基于Electron的IM跨平台SDK改造实践总结的更多相关文章

  1. 融云技术分享:融云安卓端IM产品的网络链路保活技术实践

    本文来自融云技术团队原创分享,原文发布于“ 融云全球互联网通信云”公众号,原题<IM 即时通讯之链路保活>,即时通讯网收录时有部分改动. 1.引言 众所周知,IM 即时通讯是一项对即时性要 ...

  2. QCon技术干货:个推基于Docker和Kubernetes的微服务实践

    2016年伊始,Docker无比兴盛,如今Kubernetes万人瞩目.在这个无比需要创新与速度的时代,由容器.微服务.DevOps构成的云原生席卷整个IT界.在近期举办的QCon全球软件开发大会上, ...

  3. 融云亮相GDG谷歌女性开发者大会 揭秘IMSDK网络优化策略

    4 月 20 日,冷雨阻碍不了天津GDG谷歌女性开发者大会的热烈召开,一众开发者.架构师和科技公司创业者云集一堂,就女性开发者的技术.职场.人生多方面话题展开深入探讨.活动由GDG (谷歌开发者社区) ...

  4. 对接融云即时通讯组件SDK,轻松实现App聊天室

    我好像特别喜欢做聊天室类的东东,刚折腾完微软的SignalR又折腾App.本来想研究研究XMPP的,由于服务器的搭建问题,先采用一个第三方的吧,看看效果如何.听到弟弟说他们公司用到了融云,我也下载个S ...

  5. 基于 Apache Hudi 极致查询优化的探索实践

    摘要:本文主要介绍 Presto 如何更好的利用 Hudi 的数据布局.索引信息来加速点查性能. 本文分享自华为云社区<华为云基于 Apache Hudi 极致查询优化的探索实践!>,作者 ...

  6. 融云技术分享:解密融云IM产品的聊天消息ID生成策略

    本文来自融云技术团队原创分享,原文发布于“融云全球互联网通信云”公众号,原题<如何实现分布式场景下唯一 ID 生成?>,即时通讯网收录时有部分改动. 1.引言 对于IM应用来说,消息ID( ...

  7. 阿里云基于OSS的云上统一数据保护方案2.0技术解析

    近年来,随着越来越多的企业从传统经济向数字经济转型,云已经渐渐成为数据经济IT新常态.核心业务系统上云,云上的业务创新,这些都产生了大量的业务数据,这些数据也成为了企业最重要的资产.资源. 阿里云基于 ...

  8. 基于融云的IM通讯

    一.业务场景 项目的发展需要吧原来自己的写的通讯换为第三方的,多家对比后选择了融云IM通讯,项目要实现的功能这要是单聊.群聊.聊天室.发送的内容为文字.图片.文件.语音通话与视频通话.听起来挺复杂的我 ...

  9. CS学习资料百度云链接

    CS学习资料百度云链接 [0]Springboot微服务开发天气预报系统视频教程https://pan.baidu.com/s/1joz7flyztCq8oklBlsz8dQ提取密码:cpz7 [1] ...

  10. 从零开始学习Java系列之Java运行机制与跨平台特性

    全文大约[4000]字,不说废话,只讲可以让你学到技术.明白原理的纯干货!并带有丰富的案例及配图,让你更好地理解和运用文中的技术概念,给你带来具有足够启迪的思考-- 在上一篇文章中,壹哥给大家介绍了J ...

随机推荐

  1. 什么是前后端分离应用(Full-stack Separation),想当然就会理解错

    前后端分离应用指的是将应用的前端部分(用户界面与交互逻辑)和后端部分(业务逻辑.数据处理.服务器响应)拆分成独立的模块,各自通过 API 进行通信.这种架构设计的目的是提高开发效率.增强可扩展性和灵活 ...

  2. Web渗透04_密码破解

    账号密码是任何一个系统都必备的要素. 弱密码 123456 654321 112233 admin 等等 默认密码 Tomcat控制台: tomcat/tomcat 明文传输 http的明文传输,可以 ...

  3. Linux利用scp命令上传下载文件

    scp是secure copy的简写,用于在 Linux 下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器. scp传输是加密的,可能会稍微影响一下速度.当你服务 ...

  4. jarvisoj_level2_x64 1 writeup and blog

    Here i finish the jarvisoj_level2_x64 1 challenge in buuctf and here is some writeup (i use English ...

  5. 推荐一个 ASP.NET Core 的轻量级插件框架

    前言 本文将介绍一个专为ASP.NET Core设计的轻量级插件框架--PluginCore,该框架不仅能够简化插件的开发与集成,还能大幅提高开发效率. 另外,还将简要介绍相关的前端技术和SDK支持, ...

  6. three.js+vue智慧社区web3d数字孪生三维地图

    案例效果截图如下: 具体案例场景和功能,详见b站视频: https://www.bilibili.com/video/BV1Bb421E7WL/?vd_source=7d4ec9c9275b9c7d1 ...

  7. Scala代码练习

    1.编程实现百分制转换成五级制,规则如下: 90~100分,返回优秀: 80~89分,返回良好: 70~79分,返回中等: 60~69分,返回及格: 60分以下,返回不及格. object grade ...

  8. Nuxt.js 应用中的 prepare:types 事件钩子详解

    title: Nuxt.js 应用中的 prepare:types 事件钩子详解 date: 2024/11/8 updated: 2024/11/8 author: cmdragon excerpt ...

  9. 干货分享:Air700ECQ的硬件设计,第三部分

    ​ 5. 电器特性,可靠性,射频特性 5.1. 绝对最大值 下表所示是模块数字.模拟管脚的电源供电电压电流最大耐受值. 表格 17:绝对最大值 参数 最小 最大 单位 VBAT -0.3 4.7 V ...

  10. 初步学习Nuxt3

    Nuxt3 用于制作ssr 网页 支持vue3 所有的语法,并且支持了TypeScript, vite+vue3+composition api + ts.SPA单页面应用不能进行SEO优化,SSR应 ...