Random Thoughts

Recent content on Random Thoughts

马上订阅 Random Thoughts RSS 更新: https://blog.joway.io/index.xml

即刻多端实时通信实践

2018年9月18日 08:00

背景

jike-io 是即刻基于 socket.io 构建的一个实时通信基础设施。目前客户端上的所有实时通信服务都是建立在其基础上,涵盖了私信、消息通知、用户反馈、活动页小游戏等诸多组件。

在目前即刻的实时通信设计里,我们的实时通信只是为了让服务端主动推送消息给客户端,客户端不会主动通过 websocket 发送消息。由于几乎我们所有需要发送消息的请求都会有一定业务逻辑在,而这个业务逻辑我们并不希望 websocket 连接层(jike-io)去处理,所以我们仍旧采用传统 HTTP 请求的方式去发送请求。至于之后是否需要推送消息给用户,由服务端调用 jike-io 的接口进行实现。

在客户端层面,每一个在线用户都会向服务端建立一个 websocekt 连接,后端会为每一个用户建立一个单独的 room 。所有需要通知到该用户的消息都会使用该 websocket 连接进行推送。这种设计相较于针对不同场景建立不同的room的方案,带来的好处是无论需求如何变化,我们的 room 数目永远是和在线用户数一致了,避免个别复杂需求导致 room 数目暴涨。而具体消息类型我们通过自己定义数据格式来进行鉴别。

我们的整套方案是完全依赖于 socket.io 的,期间也遇到了不少大大小小的坑。有些其实是我们自己的场景与其设计初衷不是非常吻合导致的,还有一些算是它的设计缺陷。

在讨论上述问题之前,我们需要去弄明白的一个事情是,socket.io 到底背后做了哪些事情。

socket.io 的设计与实现细节

socket.io 是什么

socket.io 是一个非常流行的实时通信框架, 在 Github 上已经积累了 43574 个 star 。它在开源软件里可以算是一个非常产品化了的软件。拥有相对良好的生态,对于许多功能的封装也很体贴,从移动端到 Web 再到服务端都有比较完整的实现。

socket.io 并不等同于 websocket 框架,它在运行平台不支持 websocket 的时候能够自动回退到 long poll 的方式建立实时通信。同时也实现了断线重连机制。还封装了一套 namespace && room 的代码层概念。在分布式方面,socket.io 支持多种 adapter 作为 backend 。话虽这么说,但目前看上去可以用的且被人广泛使用的也只有 redis 作为 backend 的 adapter 。所以以下讨论建立在 socket.io-redis 基础之上。