Web & Electron 平台即时通讯产品的技术选型
(点击报名融云 2022 社交泛文娱出海嘉年华)

8 月底,“IM 进阶实战高手课第二讲”围绕“Web & Electron 渠道即时通讯产品的技能选型”进行了详细拆解。重视【融云全球互联网通讯云】了解更多

融云讲师巧用比方等方法,生动而又逻辑明晰地对 IM 场景前端技能计划进行了剖析比照,并共享了融云的最佳实践。下期聚集 IM 全才干 ,就在 9 月 20 日重视【融云全球互联网通讯云】了解更多


IM 常见事务形状及中心功用

即时通讯产品常见的事务形状有以下几种:聊天室、单群聊、超级群、实时告诉、在线播送。而底层功用就像根底零件,能够用不同的方法拼接出上层的不同事务形状。

Web & Electron 平台即时通讯产品的技术选型

根底功用单元模块,大约就分为三类:
最根底的是衔接管理类的需求,这是即时通讯事务的根底。接着是两头根据衔接的数据传输,这儿咱们要重视的是前后端通讯时的数据传输协议,也便是关于数据的序列化和反序列化的进程管理。

终究便是根据既有数据的查询功用,咱们主要共享前端的耐久化存储技能
即时通讯场景下,关于这三个技能点的一些技能要求各不相同。

  • 衔接管理– 持续、安稳、及时的双向网络衔接
  • 数据传输– 安全、高效、易拓宽的前后端数据传输协议
  • 记载查询– 前端数据耐久化存储计划

网络衔接计划比照

咱们经过五个目标来横向比照衔接计划,分别是:衔接速度、传输功率、即时性、安全性、兼容性

WebSocket 是前端的首选计划,它也是 Web 渠道上构建长衔接事务的原生技能计划。

由于浏览器安全沙箱的存在,咱们不能在 Web 浏览器内直接拜访传输层协议,可是 Electron 主进程内是百无禁忌的,咱们能够在 Electron 场景下选用 TCP根据 HTTP 的模仿双工协议处理计划,并不是单纯的 HTTP 协议自身,由于在长衔接事务中,短衔接特性的 HTTP 协议并不匹配需求场景。

衔接速度

衔接速度是从建议衔接到衔接树立的耗时。
TCP 的衔接需求进行三次握手,关于建议端是发两次收一次,关于应答端便是发一次收两次。

Web & Electron 平台即时通讯产品的技术选型

为什么要做三次握手?其实这也是一个很常见的面试题。打个比方来说,两个人要达到一次有用对话,就需求承认两个信息:一是自己的耳朵和嘴巴没有问题;二是对方的耳朵和嘴巴没有问题。只要在这个根底之上,两者之间的对话才是有用的。三次握手便是要完结这么一个才干承认进程。嘴巴=发送才干,耳朵=接纳才干。

当然这个比方也不谨慎,两边语言不通时也沟通不来。这是第二个技能方向数据封装协议要处理的问题,也便是对对端意图理解问题。

WebSocket 衔接要树立在 TCP 衔接根底之上,由于 WebSocket 是一个使用层协议,也便是运维们常常说的 7 层协议,而 TCP 是一个传输层协议,是 4 层协议。

Web & Electron 平台即时通讯产品的技术选型

TCP 握手完结之后,经过 HTTP 报文向服务器协议提出晋级恳求,服务经过 HTTP response 报文来呼应恳求,至此 WebSocket 洽谈完结。比 TCP 多了两个动作,所以 WebSocket 的衔接速度是慢于 TCP 的。HTTP 是短衔接协议,衔接无法安稳坚持,每次通讯要重建衔接,所以衔接速度对它没有意义。

传输功率

咱们把传输功率界说为同一块数据在传输进程中发生的流量耗费、时间耗费、算力耗费,以辅助横向比照不同网络协议,耗费越大,功率越低。

这儿咱们主要看流量耗费和时间耗费,算力耗费在 Web 和 Electron 简直能够忽略不计。先看一下 OSI 参阅模型,TCP 是 4 层协议,WebSocekt 是 7 层协议,这些其实便是 OSI 参阅模型里的层级概念。

Web & Electron 平台即时通讯产品的技术选型

OSI 参阅模型里,数据从两个网络节点之间传递,是一个 U 型传递进程:发送端从上到下传递,每层需求在数据包中添加不同的协议头信息,以确保接纳端同层能够解析;接纳端从下往上传递,传递进程逐层剥离数据中的头信息,并将数据向上传递。所以数据包从上到下的传递进程中,数据体积是不断加码的。同一段数据,直接经过 TCP 发送,流量耗费低于 WebSocket 协议。

咱们看一下经过 WebSocket 协议传递数据的额定流量有哪些。
首要 WebSocket 数据传递的最小单元是数据帧。一段数据会被切割组装为最少一个数据帧写入到 TCP 的缓冲区,假如数据比较大,就会被分拆为多个数据帧,然后对端接纳到之后再进行数据帧还原。

下图的二进制序列结构便是数据帧中的数据组成。

Web & Electron 平台即时通讯产品的技术选型

HTTP 是文本型协议,没有最小发送单元,或者说 HTTP 的报文数据的最小发送单元,便是 TCP 协议的最小发送单元。它不像 WebSocket 会将数据分装为 N 个数据帧,每个数据帧添加 WebSocket 头信息后再交给 TCP。它不自动切割数据,只在数据首部添加首行和 Headers 信息,并终究把完整报文信息写入 TCP 缓冲区,交由 TCP 去管理传输进程。

那么,HTTP 的传输功率是否就优于 WebSocket 呢?并不一定。
首要,一个 WebSocket 数据帧最多额定添加 2 – 14 个字节的头信息,可是 HTTP 协议自身的首行和 Headers 信息耗费的空间是远大于 14 字节的,这也是由于 HTTP 协议的特性导致的。它是文本型协议,一个字符最少需求一个字节的容量来存储。

其次,HTTP 协议的拓宽,会额定添加报文 Headers 信息,这些信息也是字符型的,且是键值对方式。另外,HTTP 自身是短衔接,意味着服务在收到恳求时首要要承认数据发送者的身份,所以报文数据中不可避免地在每次的恳求中带着鉴权信息,可是长衔接协议是不需求这些额定开销的。

所以,WebSocket 的总体传输功率是优于 HTTP 的,除非待传输的数据大到了使 WebSocket 数据帧数量的头信息空间总和超过了 HTTP 报文头的程度,可是这种状况一般发生在文件上传等低频场景。大部分事务数据来往中,单次发送的数据都不会很大。

即时性

即时性是数据准备完结,到被写入到 TCP 缓冲区或许阅历哪些等候时长。

关于即时通讯场景,数据的上下行是同时在发生的,这也意味着 HTTP 的短特性很吃亏,由于下行数据会受阻,服务器无法经过短衔接的 HTTP 协议完结数据的自动推送。

这儿咱们先普及一下网络协议的一些根底概念,由于它跟咱们要去比较的即时性是息息相关。

第一类概念,是关于衔接持续性的描绘。
长衔接,通俗点讲便是衔接在树立后是持续存在的,双端能够经过已存在的衔接互发数据,只要当一端自动终止衔接,衔接才会被封闭。TCP 和 WebSocket 都归于长衔接协议。(关于长衔接的更多共享,点此了解)

短衔接,是说当我需求与对端通讯时树立衔接,通讯结束后当即封闭衔接。HTTP 便是一个短衔接协议。建议恳求的时分树立衔接,收到呼应之后衔接就会封闭。当然,也能够利用 KeepAlive 去坚持 TCP 衔接复用,不过它仍是不能确保衔接不能被封闭。由于衔接的持续有用,长衔接的即时性是优于短衔接的。由于它避免了数据发送时要树立衔接的等候进程。

第二类概念,是关于字节省数据流向控制的界说。
全双工协议,是说字节省能够在衔接中双向自由活动,由于这种自由活动,所以这类协议的即时性是最好的,也通常是长衔接协议。只要缓冲区够大,就基本没有等候进程。TCP、WebSocket 都是归于全双工协议。

半双工协议,是说字节省能够在两个方向上活动,但同一时间只能存在一个方向上的活动数据。半双工协议就像一条路上只要一个车道,对向有来车时,本方向的车就不能进车道,不然路就堵死了。HTTP 协议便是一个典型的半双工协议,它实际上是允许数据双向活动的,可是它的呼应必须在恳求数据接纳完结之后,同一时间不存在双向活动的字节省。半双工协议的即时性要低于全双工,由于它有对衔接的运用等候进程,当有对向的数据流时,数据要推迟发送。

单工协议,便是数据只能单向活动,比方 HTTP 协议中的 SSE 功用。由于单工协议不能独立完结双向数据活动,不符合即时通讯的需求,所以咱们就不考虑了。

归类来看,WebScoekt 和 TCP 的即时性基本归于同一级别的,HTTP 则比他们要弱

当然,HTTP 独自拎出来一个恳求是不能和长衔接协议比的,咱们还要看一下经过 HTTP 协议的并发多衔接恳求能不能补偿它自身的不足。这儿,咱们再深入剖析一下根据 HTTP 协议的长衔接模仿计划。

咱们先想一下,根据 HTTP 协议构建的处理计划,要处理的中心问题是什么?
第一点,客户端发送数据时,等候衔接树立形成的发送推迟。 由于 HTTP 的短衔接性质,所以在上行数据传输进程中,需求等 TCP 衔接树立才干发送 HTTP 报文。针对这一点,就 HTTP 协议来说,现在是没有处理计划的,HTTP 的 KeepAlive 特性能够缓解,但不能彻底处理。

第二点,服务器数据无法自动推送到端形成的下行数据推迟。 这也是 HTTP 的短衔接特性形成的。当服务器有下行数据时,并没有一个持续的有用衔接能够让它把数据推下去,所以只能等候客户端来自动树立衔接,顺道把下行数据带下去。咱们要介绍的计划便是围绕处理第二点打开的。市面上比较盛行的前端根据 HTTP 协议构建的处理计划,主要有三种。

Comet 部分缓解了下行推迟问题。
HTTP + SSE 计划与 Comet 相似,仅仅把下行通道从 HTTP 恳求变成了 SSE 完结。

SSE 的特性是长衔接、单工协议,它的整体效果优于 Comet,由于没有额定的衔接等候时间。它作为下行数据的通道,单工协议也完全符合要求。能够说 HTTP + SSE 的下行即时性基本是与 WebSocekt 同等的,基本处理了下行推迟问题。

Long-Pulling,定时向服务器去发送恳求,以此来把下行数据带回来,基本归于常规操作,两个中心问题,基本一个也没有处理。
总结而言,HTTP + SSE > Comet > Long-Pulling
这个定论有一个条件,是抛开了兼容性的。

SSE 计划虽好,但仅限于浏览器,假如咱们想把 JS 代码复用到其他环境比方小程序,该计划就无法完结了。现在各小程序 Runtime 关于 SSE 的支撑简直是 0。

安全性

咱们看一下 OSI 参阅模型,侧重看一下使用层和传输层之间的部分,这儿是 SSL/TLS 所处的方位,也便是咱们常说的 HTTPS 中的那个 S。

Web & Electron 平台即时通讯产品的技术选型

OSI 模型中界说中,会话层担任两头的会话保持、身份鉴别等,表明层担任对数据的加解密。在此之上,使用层协议的安全性是同等的,HTTPS 和 WSS 协议便是安全版的 HTTP 和 WebSocket 协议。

TCP 是比 SSL/TLS 更底层的协议,所以直接经由 TCP 发送的数据是能够有更多的安全选择的,TLS 仅仅备选项之一。运用 HTTPS 或 WSS 协议时,由 Runtime 供给 TLS/SSL 支撑,开发者无需重视数据传输进程中的安全问题。

运用 TCP 协议时,需求由开发者自行确保数据传输进程中的安全性(对接 TLS/SSL 或其他自界说安全计划)。

Web & Electron 平台即时通讯产品的技术选型


数据传输协议计划 & 前端耐久化存储

数据传输协议计划

咱们经过信息密度、拓宽性、安全性、多端共同、兼容性五个目标来做比照数据传输协议。除了咱们并不推荐的自研计划,常用的数据传输协议有两种:Protocol Buffer(PB) ,TLV 格局二进制数据;JSON,纯文本键值对数据。

Web & Electron 平台即时通讯产品的技术选型

五个目标比照来看,信息密度指 A 向 B 传达信息需求耗费的流量,密度越高,耗费得越少,PB 的信息密度比 JSON 高。传输结构上,PB 是一个 TLV 格局二进制数据序列,JSON 是纯字符串系列键值对,JSON 描绘数据结构要远大于 PB 描绘数据结构。

安全性与可读性相反,咱们要读一个二进制的 PB 数据,需求知道它序列化进程中的 PB 数据界说的结构。咱们常说的 PB 文件界说的可读性文件,这是前后端的一个约定,根据这个文件咱们才干去序列化和反序列化这个二进制数据。而 JSON 是纯字符串,可读性良好,能够比较直观去了解数据里的信息。

兼容性方面,JSON 有很多原生语言库可选,PB 的兼容性在前端来看也便是 JS 对ArrayBuffer的支撑,现在也都是支撑的
拓宽性上,两边是同等的,PB 有一个长处,由于他传输的数据不包括键信息,所以两头的键信息能够不同。JSON 的传输信息包括键信息,意味着键信息是不能够随意变更的。
多端共同与兼容性共同,即时通讯场景涉及很多渠道,多端就要去对数据做多端传输,数据的序列化和反序列化的完结的进程要坚持共同,PB 跟 JSON 这方面都比较好,JSON 是原生支撑的,PB 能够运用 Google 供给的相应三方库。
总之,PB 比 JSON 更优。

前端耐久化存储比照

终究是前端的可耐久化存储技能:LocalStorage、IndexDB 和 Sqlite。耐久化存储自身可选计划不多,需求考虑容量、兼容性、数据共同性等方面。

  • LocalStorage,最常用的计划,容量比较低
  • IndexDB,浏览器器上仅有可用的耐久化大容量存储计划
  • Sqlite – Electron Only,常用前端数据库
  • Sqlite – WebAssembly,研发本钱比较高

除了 LocalStorage,其他三种容量适当。
数据共同性而言,除了 Electron 主进程内运用 Sqlite,其他三种计划都不太好处理数据竞争问题,很难确保数据共同性。在 Electron 渠道下,把数据库操作放到主进程去完结,当渲染进程需求控制本地数据库时,依赖 IPC 去跟主进程通讯,由主进程去处理真实的数据库事务。主进程是仅有一个数据库的拜访点,因此能够妥善完结对数据竞争和数据共同性的保证。


融云的落地实践共享

经过三大项的计划比照,融云在落地的时分按照前面所共享的原则,在可用的计划下尽或许选择最优解,比方,Electron 渠道上最优解便是 TCP+Sqlite ,数据封装用 PB。

Web 渠道上没有 TCP+Sqlite 可用,就用 WebSocket 作为处理计划,把 HTTP 作为次优解做相应的技能落地。

小程序上,PB、WebSocket 都用不了,则选用 HTTP 计划备选,选型用的是 Comet。这个降级进程关于集成的开发者来说是无感的,但在事务落地进程中是需求重视的,比方音讯查询,有没有数据库便是两种使用体会。