最初方案

采用 webrtc + websocket 的 nodejs 架构,websocket 等长链接协议在不稳定的网络架构环境内,程序超长时间运行后出现无法重连、甚至连接情况下也无法通信的情况。往往必须要人为处理才能恢复视频电话的正常使用。比如:防火墙规则调整、网络故障等等情况。

原方案架构图

原方案架构图

此种架构下 websocket 只能客户端 主动发起连接, 由下而上逐级向机房服务器上的服务端建立连接,无法从服务端主动从机房服务器向客户端发起连接。

websocket连接示意图

websocket连接示意图

而且因为信息安全的要求,机房服务器和客户端设备之间至少有一层以上的防火墙隔离。当防火墙上设置了某些不利于长链接协议的优化配置或者其他一些位置原因会让客户端异常断开和机房服务器之间的通信,如果客户端没有及时触发websocket 重连甚至无法自动重连,那么在没有人为干预的情况下设备功能将无法自动恢复正常。

websocket 断开示意图

websocket 断开示意图

改进方案

安卓应用集成 GRPC 协议网关在局域网内所有设备的 IP 信息都是固定的情况下,采用可以双向通信的 GRPC 协议来实现设备间的相互通信**「客户端可以主动向服务端发起连接,服务端也可以主动向客户端发起连接」**,从而避免出现 websocket 等长链接协议断连之后必须等待客户端主动重连的问题。

虽然 websocket 是实现聊天室的常用方案,但是在需要主动双向通信的场景下 GRPC 是更好的选择。开发方面采用 gomoble 开发和生成安卓SDK的方式,虽然性能上会有部分损失,因为 golang 的跨平台特性可以更好的开发其他平台工具来负责监控、测试和后期的运维。同时简单的语法可以更方便的完成更高的单元测试覆盖,保证后续程序可以稳定的快速更新迭代。

改进方案架构图

改进方案架构图

改进后的方案将 GRPC 服务集成到客户端的APP中,这种架构下所有在线的设备都可以随意的两两相互之间由任意一方主动发起连接请求来建立通信。

GRPC连接示意图

GRPC连接示意图

一主多从网关架构简单介绍

<aside> 💡

局域网内场景虽然并发并不高,但是每次拨打需要多次的信令交互来完成 webrtcPEER 连接。为了短时间多次拨打或者同一时间多个设备拨打同一个设备时候,信令能够高效顺利的完成交互,主节点上每一次拨打的双方节点都创建了聊天室哈希表UID对应每一次通话。

</aside>

自动发现

<aside> 💡 自动发现可以避免每次新增、更换节点,都需要人工设置网关节点信息。

</aside>

图1

图1

发起通话

当某一网关节点发起通话申请到主节点的时候,主节点收到申请将会通知所有需要通话的节点打开APP接听界面,建立webrtc连接并发生音视频流到主节点。

  1. 节点 192.168.0.2 拨打节点 192.168.0.3 ,同时发送拨打申请信息到主节点 192.168.0.1

    图2

    图2

  2. 主节点 192.168.0.1 通知节点 192.168.0.2192.168.0.3分别打开视频电话拨打和接听界面,并初始化 webrtcPEER 连接并准备开始和主节点192.168.0.1 进行信令交互。

图3

图3