当用户登录、登出声网 RTM 系统,或者网络连接发生变化时,声网 RTM SDK 与声网 RTM 系统之间的连接会在不同状态之间切换。可能的连接状态如下:
如下图所示,实线表示 SDK 会根据条件自动实现部分状态切换。虚线表示需要用户主动调用 API 来实现。
OnConnectionStateChangedHandler
回调返回最新的状态 CONNECTION_STATE
枚举以及状态变化的原因 CONNECTION_CHANGE_REASON
枚举。你可以通过此回调对连接状态进行管理。你可以利用 OnConnectionStateChangedHandler
回调返回的状态和状态改变原因在下列情况中主动调用 API 变更连接状态。
在你调用 Login
登录 RTM 系统时,连接状态会从 CONNECTION_STATE_DISCONNECTED
转换为 CONNECTION_STATE_CONNECTING
,状态改变原因为 CONNECTION_CHANGE_REASON_LOGIN
。处于 CONNECTION_STATE_CONNECTING
状态时,连接状态会自动转换为下列状态之一:
CONNECTION_STATE_DISCONNECTED
:用户登录失败或登录超时(12 秒内未登录系统)。CONNECTION_STATE_CONNECTED
:用户登录成功。当连接状态变为 CONNECTION_STATE_DISCONNECTED
,你需要重新调用 Login
登录。
当连接处于 CONNECTION_STATE_CONNECTED
状态时,如果由于网络原因与声网 RTM 系统的连接中断超过 4 秒,连接状态会转换为 CONNECTION_STATE_RECONNECTING
,状态改变原因为 CONNECTION_CHANGE_REASON_INTERRUPTED
。处于 CONNECTION_STATE_RECONNECTING
状态时,RTM SDK 会持续自动重新登录 RTM 系统直至登录成功,因此你无需进行任何登录操作。在断线重连期间发送的消息不会被投递,建议你在恢复连接后重新发送。重新登录成功后,连接状态会转换为 CONNECTION_STATE_CONNECTED
,SDK 不会返回 OnLoginSuccessHandler
回调。
如果一直无法重新登录成功,连接状态会保持在 CONNECTION_STATE_RECONNECTING
。你可以调用 Logout
先登出系统再根据实际业务情况调用 Login
方法重新登录 RTM 系统。
根据连接中断到重新自动登录成功的时长不同,RTM 系统的行为也会有区别:
CONNECTION_STATE_CONNECTED
。用户的在线状态不变。OnMemberLeftHandler
回调。如果用户在之后重新成功登录系统,连接状态会转换为 CONNECTION_STATE_CONNECTED。
SDK 会自动将用户加入之前加入的频道,同频道的用户会收到 OnMemberJoinedHandler
回调。由于此时 RTM 系统已将用户从在线列表中移除, SDK 还会自动同步用户属性到 RTM 系统。在 CONNECTION_STATE_RECONNECTING
状态下,由于 SDK 会一直重连声网 RTM 系统,此时如果 Token 过期,SDK 会返回 OnTokenExpiredHandler
回调。但是该回调不会对连接状态产生影响。
如果相同的用户 ID 从另一个客户端实例登录 RTM 系统,当前客户端实例中正在登录状态的用户会被 RTM 系统踢出,连接状态变为 CONNECTION_STATE_ABORTED
。你可以调用 Logout
先登出系统再根据实际业务情况调用 Login
方法重新登录 RTM 系统。
CONNECTION_STATE_ABORTED
状态下,调用所有需要当前用户登录的 API 都会失败。在实际业务场景中,对于被踢出的用户,建议应用对用户自动进行登出,但需要让用户手动进行再次登录。如果你实现了被踢状态下的自动登出和自动登录,可能会导致两端用户循环互踢。循环互踢一旦发生,需要一端的用户登出或者杀掉进程才会停止。如果你调用 Logout
登出 RTM 系统,连接状态会转换为 CONNECTION_STATE_DISCONNECTED
。RTM 系统会将对应用户从在线用户列表和频道中移除,同一频道的用户会收到 OnMemberLeftHandler
回调。
参考以下示例代码监听连接状态:
// 监听连接状态
public void OnConnectionStateChangedHandler(int id, CONNECTION_STATE state, CONNECTION_CHANGE_REASON reason)
{
Print("OnConnectionStateChangedHandler: %d", state);
}