常见问题

产品 / 插件
平台 / 框架

SDK 是否支持断线重连机制?

产品 / 插件:实时音视频 / 实时语音 / 低延迟直播 / 畅直播

平台 / 框架:iOS / Android / macOS / Windows / Flutter / Unity3d

更新时间:2022-07-12 17:26


ZEGO SDK 支持断线重连机制。本文将介绍房间重连、推流重连、拉流重连三种情况下的 SDK 的逻辑处理,以及应对常见异常断开的处理方法。

1 重连逻辑说明

1.1 房间重连

用户登录房间后,因网络信号问题/网络类型切换问题导致的与房间断开连接的情况,SDK 内部会进行自动重连。

用户可通过监听 onRoomStateChanged 回调实时监控自己在本房间内的连接状态。在登录房间时将参数 config 中的 isUserNotify 设置为 “true” 的前提下,房间内的其他用户可通过 onRoomUserUpdate 回调获取到某用户连接状态变化的通知。

房间状态回调

状态 枚举值 含义
ZegoRoomStateChangedReason.LOGINING
0
正在登录房间。当调用 [loginRoom] 登录房间或 [switchRoom] 切换到目标房间时,进入该状态,表示正在请求连接服务器。通常通过该状态进行应用界面的展示。
ZegoRoomStateChangedReason.LOGINED
1
登录房间成功。当登录房间或切换房间成功后,进入该状态,表示登录房间已经成功,用户可以正常收到房间内的其他用户和所有流信息增删的回调通知。
ZegoRoomStateChangedReason.LOGIN_FAILED
2
登录房间失败。当登录房间或切换房间失败后,进入该状态,表示登录房间或切换房间已经失败,比如 AppID、AppSign 或 Token 不正确等。
ZegoRoomStateChangedReason.RECONNECTING
3
房间连接临时中断。如果因为网络质量不佳产生的中断,SDK 会进行内部重试。
ZegoRoomStateChangedReason.RECONNECTED
4
房间重新连接成功。如果因为网络质量不佳产生的中断,SDK 会进行内部重试,重连成功后进入该状态。
ZegoRoomStateChangedReason.RECONNECT_FAILED
5
房间重新连接失败。如果因为网络质量不佳产生的中断,SDK 会进行内部重试,重连失败后进入该状态。
ZegoRoomStateChangedReason.KICK_OUT
6
被服务器踢出房间。例如有相同用户名在其他地方登录房间导致本端被踢出房间,会进入该状态。
ZegoRoomStateChangedReason.LOGOUT
7
登出房间成功。没有登录房间前默认为该状态,当调用 [logoutRoom] 登出房间成功或 [switchRoom] 内部登出当前房间成功后,进入该状态。
ZegoRoomStateChangedReason.LOGOUT_FAILED
8
登出房间失败。当调用 [logoutRoom] 登出房间失败或 [switchRoom] 内部登出当前房间失败后,进入该状态。

房间状态示意图

如果用户 A 短暂断线,但是在 90 秒内重连成功了,那么用户 B 不会收到 onRoomUserUpdate 的回调通知。

其中:

  • T0 = 0s:ClientA 的 SDK 收到客户端发起的 loginRoom 请求。
  • T1 ≈ T0 + 120ms:通常在调用 loginRoom 120 毫秒后,客户端可以加入房间。加入房间过程中,ClientA 的客户端会收到 onRoomStateChanged(ZegoRoomStateChangedReasonLogining, 0, extendedData, roomID)onRoomStateChanged(ZegoRoomStateChangedReasonLogined, 0, extendedData, roomID) 回调,分别通知客户端正在连接房间以及连接房间成功。
  • T2 ≈ T1 + 100ms:因网络传输延迟,ClientB 约在 100ms 后收到 onRoomUserUpdate(roomID, ZegoUpdateTypeAdd, userList) 回调以通知客户端 ClientA 加入房间。
  • T3:某个时间点,ClientA 因网络断开等原因导致上行网络变差。SDK 会尝试重新加入房间,同时客户端会收到 onRoomStateChanged(ZegoRoomStateChangedReasonReconnecting, 1002051, extendedData, roomID) 回调以通知客户端 ClientA 正在断线重连。
  • T4 ≈ T3 + 90S:ClientB 此时收到 onRoomUserUpdate(roomID, ZegoUpdateTypeDelete, userList) 回调以通知 ClientA 已断线。
  • T5 = T3 + time(小于20分钟):ClientA 在重连时间内恢复网络,重连成功。此时客户端会收到 onRoomStateChanged(ZegoRoomStateChangedReasonReconnected, 0, extendedData, roomID) 回调以通知客户端 ClientA 重连成功。
  • T6 ≈ T5 + 100ms:因网络传输延迟,ClientB 约在 100ms 后收到 onRoomUserUpdate(roomID, ZegoUpdateTypeAdd, userList) 回调以通知客户端 ClientA 重连成功。
  • T7 = T3 + 20min:如果 ClientA 连续 20 分钟无法重新加入房间,SDK 不再继续尝试重新连接。ClientA 将会收到 onRoomStateChanged(ZegoRoomStateChangedReasonReconnectFailed, 1002053, extendedData, roomID) 回调以通知客户端断开连接。

1.2 推流重连

在用户推流过程中,因网络信号问题/网络类型切换问题导致的推流不成功的情况,SDK 内部会进行自动重连。

若所有推流节点都尝试了仍不成功,用户将会收到 onPublisherStateUpdate 回调,“state” 为 ZegoPublisherStateNoPublish,且 “errorCode” 不为 0,表示 SDK 内部重连已失败,具体错误请根据 “errorCode” 的值进行判断,可参考 常见错误码。此时,业务侧可以考虑等待几秒后(比如 3 - 5 秒)开始重新推流,但是不要不断地进行重试,导致陷入死循环。

推流状态回调

状态 枚举值 含义
ZegoPublisherStateNoPublish
0
未推流状态,在推流前处于该状态。如果推流过程中出现稳态的异常,比如 AppID、AppSign 或 Token 不正确,或者其他用户已经在推送相同流 ID 的流(推流会失败),都会进入未推流状态。
ZegoPublisherStatePublishRequesting
1
正在请求推流状态,推流动作执行成功后,会进入正在请求推流状态。通常情况下,可通过该状态进行 UI 界面的展示。如果是因为网络质量不佳产生的中断,SDK 内部会进行重试,也会进入正在请求推流状态。
ZegoPublisherStatePublishing
2
正在推流状态,成功推流后进入该状态。此时,用户可以正常进行通信。

1.3 拉流重连

在用户拉流过程中,因网络信号问题/网络类型切换问题导致的拉流不成功的情况,SDK 内部会进行自动重连。

若所有拉流节点都尝试了仍不成功,用户将会收到 onPlayerStateUpdate 回调,“state” 为 ZegoPlayerStateNoPlay,且 “errorCode” 不为 0,表示 SDK 内部重连已失败,具体错误请根据 “errcode” 的值进行判断,可参考 常见错误码。此时,业务侧可以考虑等待几秒后(比如 3 - 5 秒)开始重新拉流,但是不要不断地进行重试,导致陷入死循环。

拉流状态回调

状态 枚举值 含义
ZegoPlayerStateNoPlay
0
未拉流状态,在拉流前处于该状态。如果拉流过程中出现稳态的异常,比如 AppID、AppSign 或 Token 不正确,都会进入未拉流状态。
ZegoPlayerStatePlayRequesting
1
正在请求拉流状态,拉流动作执行成功后,会进入正在请求拉流状态。通常情况下,可通过该状态进行 UI 界面的展示。如果是因为网络质量不佳产生的中断,SDK 内部会进行重试,也会进入正在请求拉流状态。
ZegoPlayerStatePlaying
2
正在拉流状态,成功拉流后进入该状态。此时,用户可以正常进行通信。

1.4 重连时间设置

因网络原因断开连接时,SDK 重连的默认时间是 20 分钟,超出该时间 SDK 将不再继续尝试重连。

  • 可通过 setEngineConfig 配置 "room_retry_time=xxxx",设置房间重连时间(单位为:秒)。
  • 可通过 setEngineConfig 配置 "av_retry_time=xxxx" ,设置推流、拉流重连时间(单位为:秒)。

2 处理异常断开

房间内用户断开连接时,默认情况下,房间内的其他用户会在 90 秒后收到该用户断线的回调通知。如需修改该默认值,请联系 ZEGO 技术支持。

2.1 处理主播端断网

SDK 会自动检测主播的网络情况,当检测到主播断网时,会自动暂停推流。如果网络在 20 分钟内恢复正常,SDK 会自动重新推流。

断网 90 秒后,如果网络没有恢复,房间内除主播外的其他用户会收到 onRoomStreamUpdate 回调中的“流删除”通知,观众可在收到此回调时,调用 stopPlayingStream 接口停止拉流。如果 SDK 重试推流成功,房间内的所有用户会收到 onRoomStreamUpdate 回调中的“流新增”通知,观众可在收到此回调时,调用 startPlayingStream 重新开始拉流。

2.2 观众端处理主播端网络异常

主播端断网时,观众端是无法监控到的。此时,观众端无法正常拉流,SDK 内部会自动重试拉流,如果重试后仍然拉不到流,观众端将会收到 onPlayerStateUpdate 回调,回调中的 “errorCode” 不为 0,建议观众端间隔一段时间(比如 3 秒后)后再次进行拉流。

在 SDK 内部会自动重试拉流的过程中,针对主播端的情况,可做以下处理:

  • 如果主播端网络恢复正常,重试拉流成功,观众端即可正常进行拉流。
  • 如果主播端网络一直没有恢复,主播端断网的 90 秒后,观众端会收到 onRoomStreamUpdate 回调中的“流删除”通知,观众端可在收到此回调时,调用 stopPlayingStream 接口停止拉流。
  • 如果后续主播端恢复正常且成功重新推流后,观众端可在收到 onRoomStreamUpdate 回调中的“流新增”通知时,调用 startPlayingStream 重新开始拉流。

为避免陷入拉流的死循环中,观众端在收到流删除通知要及时停止拉流。

2.3 观众端处理主播端 crash

主播端 crash 的情况下,主播端在 90 秒时仍未开播,观众端会收到 onRoomStreamUpdate 回调中的“流删除”通知,针对 90 秒内和 90 秒后主播开播情况,可做以下处理。

如果后续主播端恢复正常且成功重新推流后,观众端可在收到 onRoomStreamUpdate 回调中的“流新增”通知时,调用 startPlayingStream 重新开始拉流。