登录登出
更新时间: 2023/08/15 02:24:39
NIM Flutter SDK 提供手动登录和自动登录接口,以及自动重连和多端登录等机制和策略,满足您的登录业务需求。在调用 SDK 登录接口之前,需要先为应用下的每一位 IM 用户注册云信 IM 账号(account
,又称accid
),同时获取对应的 Token。
目前,云信提供两种注册方式:
- 方式 1:调用服务端 API 完成注册。正式生产环境中,必须使用该方式注册的 IM 账号。
- 方式 2:在云信控制台注册,该方式适用于调试阶段。
技术原理
账号注册与初次登录的流程如下:
上图中的流程说明如下:
- 开发者将应用的账号传入云信 IM 服务端,注册云信 IM 账号。
- 云信 IM 服务端返回 Token 给应用服务端。
- 应用客户端登录应用服务端。
- 应用服务端将 Token 返回给应用客户端。
- 应用客户端带 Token 登录云信 IM 服务端。
API 调用时序
下图展示了与用户首次登录登出相关的API 的调用时序,图中的 NIM 表示 NIM Flutter SDK。
登录相关监听
在首次登录前,需监听登录状态变化、多端登录事件和登录成功后的数据同步状态变化。
监听登录状态变化
可以通过登录状态事件流(authStatus
)监听当前登录状态。
SDK 暂不支持主动查询当前账号是否处于在线状态,请监听登录状态变化并进行状态缓存。
-
参数说明
状态事件包含两类:
NIMAuthStatusEvent
:通用登录状态事件,包含NIMAuthStatus
登录状态枚举(具体枚举值见下表)。NIMKickOutByOtherClientEvent
:被踢事件,包含状态字段与额外属性;在使用时,需要根据具体类型进行解析。
NIMAuthStatus | 说明 |
---|---|
unknown |
未定义 |
unLogin |
未登录/登录失败 |
netBroken |
网络连接已断开 |
connecting |
正在连接云信服务端 |
logging |
正在登录中 |
loggedIn |
已成功登录 |
kickOut |
被其他端的登录踢掉,此时应该跳转至手动登录界面。被踢后,无法自动登录 |
kickOutByOtherClient |
被同时在线的其他端主动踢掉(通过kickOutOtherOnlineClient 方法),此时应该跳转至手动登录界面。被踢后,无法自动登录 |
forbidden |
被云信服务端禁止登录云信 IM 账号被禁用。被禁止登录后,无法自动登录 |
versionError |
SDK 版本错误。出现该登录异常后,无法自动登录 |
pwdError |
云信 IM 账号(account )或 token 错误。出现该登录异常后,无法自动登录 |
登录状态变化流程相关详情,请参见下文的登录状态变化流程。
- 示例代码
dart
/// 开始监听事件
final subscription = NimCore.instance.authService.authStatus.listen((event) {
if (event is NIMKickOutByOtherClientEvent) {
/// 监听到被踢事件
} else if (event is NIMAuthStatusEvent) {
/// 监听到其他事件
}
});
/// 不再监听时,需要取消监听,否则造成内存泄漏
/// subscription.cancel();
监听多端登录事件
可通过以下接口监听多端登录事件,获取当前在线的设备列表。
dartclass AuthService {
/// 在线客户端列表变更事件
/// [NIMOnlineClient]
Stream<List<NIMOnlineClient>> get onlineClients;
}
- 参数说明
NIMOnlineClient 类型说明:
参数 | 类型 | 说明 |
---|---|---|
os |
String? | 客户端的操作系统信息 |
clientType |
NIMClientType |
客户端类型 |
loginTime |
int | 登录时间 |
customTag |
String? | 登录自定义属性 |
- 示例代码
dartfinal subscription = NimCore.instance.authService.onlineClients.listen((clients) {
clients.forEach((client) {
switch (client.clientType) {
case NIMClientType.windows:
// PC端(Windows)
break;
case NIMClientType.macos:
// PC端(macOS)
break;
case NIMClientType.web:
// Web端
break;
case NIMClientType.ios:
// 移动端(iOS)
break;
case NIMClientType.android:
// 移动端(Android)
break;
default:
// 未知
break;
}
});
});
/// 不再监听时,需要取消监听,否则造成内存泄漏
/// subscription.cancel();
监听数据同步状态
登录成功后,SDK 会自动同步群信息、离线消息、漫游消息和系统通知等数据。数据同步过程会广播数据同步状态变更事件(NIMDataSyncStatusEvent
),可通过以下接口监听该事件。
dartclass AuthService {
/// 登录状态变更事件
Stream<NIMAuthStatusEvent> get authStatus;
}
- 参数说明
数据同步状态事件包含一个类型为 NIMAuthStatus
的登录状态字段,标识当前同步状态:
NIMAuthStatus | 说明 |
---|---|
NIMAuthStatus.dataSyncStart |
数据同步开始 |
NIMAuthStatus.dataSyncFinish |
数据同步完成 |
- 示例代码
dart
/// 开始监听事件
final subscription = NimCore.instance.authService.authStatus.listen((event) {
if (event is NIMDataSyncStatusEvent) {
/// 监听到数据同步事件
if (event.status == NIMAuthStatus.dataSyncStart) {
/// 数据同步开始
} else if (event.status == NIMAuthStatus.dataSyncFinish) {
/// 数据同步完成
}
}
});
/// 不再监听时,需要取消监听,否则造成内存泄漏
/// subscription.cancel();
手动登录
在新设备上初次登录,以及被踢、切换账号与注销登录后下一次登录,需要使用手动登录。对应用户手动输入登录账号密码的场景。
调用login
方法即可手动登录。
javaclass AuthService {
/// 登录接口。sdk会自动连接服务器,传递用户信息,返回登录结果。
Future<NIMResult<void>> login(NIMLoginInfo loginInfo);
}
- NIMLoginInfo参数说明
NIMLoginInfo 参数 | 是否必传 | 说明 |
---|---|---|
account |
是 | 云信 IM 账号 |
token |
是 | 登录需要用到的 Token |
authType |
否 | SDK 认证类型:
|
loginExt |
否 | 登录自定义字段 |
customClientType |
否 | 自定义客户端类型 |
- 示例代码
dartNimCore.instance.authService
.login(NIMLoginInfo(account: 'account', token: 'token',))
.then(
(result) {
if (result.isSuccess) {
/// 登录成功
} else {
/// 登录失败
}
},
);
登录失败的错误码说明如下:
错误码 | 说明 |
---|---|
302 | appKey 、account 和token 三者不对应 |
408 | 与云信服务端的连接超时 |
415 | 网络断开或者与云信服务端建立连接失败 |
416 | 调用手动登录接口过于频繁 |
1000 | 本地数据库未打开引起的错误。请在手动登录成功后打开本地数据库。 |
自动登录
如需实现自动登录,需要在调用initialize
方法初始化 SDK 时,将本地保存的account
和token
传入NIMAndroidSDKOptions
或NIMIOSSDKOptions
的自动登录信息(autoLoginInfo
)。
手动登录成功后,保存至本地的用户账号和密码,可用作自动登录时使用。自动登录主要针对应用被杀进程后,再次启动时,无需输入用户名和密码即可完成登录的场景。此时可以在无网络,未登录成功的状态下直接访问用户本地 SDK 数据。
目前仅 Android 和 iOS 支持自动登录, Windows 和 macOS 不支持。
示例代码代码如下:
dartNimCore.instance.initialize(
NIMAndroidSDKOptions(
appKey: 'appkey',
autoLoginInfo: NIMLoginInfo(
account: 'account',
token: 'token',
),
),
).then(
(result) {
if (result.isSuccess) {
/// 初始化成功
} else {
/// 初始化失败
}
},
);
注销登录
调用logout
方法即可注销登录。
- API 原型
javaclass AuthService {
Future<NIMResult<void>> logout();
}
- 示例代码
dart NimCore.instance.authService
.logout()
.then(
(result) {
if (result.isSuccess) {
/// 成功
} else {
/// 失败
}
}
);
登录相关机制与策略
断网重连
SDK 提供了自动重连机制。在该机制下,SDK 与云信服务端断开连接后,将自动重新建立连接并重新登录。如果已监听登录状态变化,所有重连引发的登录状态变更都会触发 NIMAuthStatusEvent
事件通知。
SDK 在如下两种场景会自动重新建立与云信服务端的连接,您无需在应用上层自实现额外的重登逻辑。
- 手动/自动登录成功后,网络不佳导致连接断开的情况。
- 在初始化时配置自动登录后,网络不佳导致 SDK 与云信服务端出现连接问题(如连接超时)且账号密码本身正常(未被封禁,且账号密码均正确)时。
多端登录与互踢
您可在云信控制台配置如下多端登录策略:
- 只允许一端登录
- 桌面端(PC 与 Web)互踢、移动端(Android 和 iOS )互踢、桌面端与移动端可同时登录。
- 各端均可以同时登录在线(最多 10 个设备同时在线)
多端登录策略配置详情,请参见多端登录与互踢策略。
调用kickOutOtherOnlineClient
方法,可将同时登录 IM 的其他客户端踢下线。调用时需要传入 NIMOnlineClient
类型的对象(表示当前登录 IM 的在线设备列表),该对象通过监听多端登录事件( onlineClients
)获取。
当被其他客户端踢掉,本端会收到 NIMKickOutByOtherClientEvent
事件。收到该事件回调后,建议进行注销并切换到登录界面。
- 参数说明
NIMKickOutByOtherClientEvent
事件参数说明如下:
参数 | 类型 | 说明 |
---|---|---|
status |
NIMAuthStatus |
当前登录状态 |
clientType |
int? | 获取将当前客户端踢下线的客户端的类型 |
customClientType |
int? | 获取将当前客户端踢下线的客户端的自定义类型 |
- 示例代码
dart
NimCore.instance.authService
.kickOutOtherOnlineClient(client)
.then(
(result) {
if (result.isSuccess) {
/// 成功
} else {
/// 失败
}
}
);
登录状态变化流程
登录状态变化流程(不包含被踢下线和被 IM 服务端禁止登录等特殊状态)参见下图。图中,深蓝色元素代表登录状态,浅绿色元素代表自动登录或调用login
方法的手动登录。