实现基本消息收发
本文介绍如何使用 ZIM SDK 快速实现基本的单聊会话消息收发功能。
本文档适用于开发以下平台的应用:iOS、Android、macOS、Windows、Web。
1 前提条件
在使用 ZIM SDK 前,请确保:
- 已安装 Flutter。
- 已安装 Dart 且版本为 [2.12.0, 4.0.0)。
- 测试设备满足以下要求:
- iOS 11.0 或以上版本的 iOS 设备或模拟器(推荐使用真机)。
- Android 4.1 或以上的 Android 设备或模拟器(推荐使用真机),如果是真机,请开启“允许调试”选项。
- Windows: Windows 10 或更高的版本(基于 x86-64 的 64 位操作系统)。
- macOS: macOS 10.13 或以上版本。
- Web 浏览器:
- Chrome 58 或以上版本
- Firefox 56 或以上版本
- Safari 11 或以上版本
- Opera 45 或以上版本
- QQ 浏览器 Windows 10.1 或以上版本/macOS 4.4 或以上版本
- 360 安全浏览器极速模式
- 设备已经连接到 Internet。
- 已在 ZEGO 控制台 创建项目,获取到了接入 ZIM SDK 服务所需的 AppID、AppSign。ZIM 服务权限不是默认开启的,使用前,请先在 ZEGO 控制台 自助开通 ZIM 服务(详情请参考 项目管理 - 即时通讯),若无法开通 ZIM 服务,请联系 ZEGO 技术支持开通。
2.3.0 及以上
版本的 SDK,开始支持 “AppSign 鉴权”,同时仍支持 “Token 鉴权”,若您需要升级鉴权方式,可参考 ZIM 如何从 AppSign 鉴权升级为 Token 鉴权。
2 集成 SDK
2.1 (可选)新建项目
2.2 导入 SDK
-
打开 “pubspec.yaml” 文件,以 “pub” 形式,添加 “zego_zim” 依赖:
Untitleddependencies: # 请填写具体的 SDK 版本号 # 请从发布日志查询 SDK 最新版本,并将 x.y.z 修改为具体的版本号 zego_zim: ^x.y.z
1 -
添加完成并保存文件后,在终端执行
flutter pub get
。 -
如果您使用的是 Web 平台,还需要在您的 Web 项目的 index.html 文件中,添加如下代码,引入 Web SDK。
Untitled<script src="assets/packages/zego_zim/assets/index.js" type="application/javascript"></script>
1
2.3 设置权限
开发者可以根据实际应用需要,设置应用所需权限。
-
iOS、Web 平台:无特殊权限要求。
-
Android 平台:
进入 “app/src/main” 目录,打开 “AndroidManifest.xml” 文件,添加权限。
Untitled<!-- SDK 必须使用的权限 --> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
1
2.4 防止混淆代码
如果您使用 Flutter 框架开发 Android 应用,还需要在 “proguard-rules.pro” 文件中,为 SDK 添加 -keep
类的配置,防止混淆 SDK 公共类名称。
-keep class **.zego.**{*;}
3 实现基本收发消息
以下流程中,我们以客户端 A 和 B 的消息交互为例:
3.1 实现流程
1. 导入头文件
在项目文件中引入头文件 “zego_zim.dart”。
import 'package:zego_zim/zego_zim.dart';
2. 创建 ZIM 实例
首先我们需要在 SDK 中创建 ZIM 单实例,实例对应的是一个用户,表示一个用户以客户端的身份登录系统。
例如,客户端 A、B 分别调用 create 接口,传入在 1 前提条件 中获取到的 AppID、AppSign(开发 Web 平台应用时无需使用 “appsign”,为防止暴露,请勿传入),创建了 A、B 的实例:
// 创建
// 通过插件创建 ZIM 单实例,传入 APPID、AppSign
// 请注意:ZIM 从 2.3.0 版本开始支持 AppSign 鉴权,SDK 也默认为 AppSign 鉴权,如果您需要切换鉴权方式:
// (1) 2.3.3 及以上版本的 SDK,支持鉴权方式的自主切换; (2) 2.3.0 版本的 SDK,需要切换为 “Token 鉴权” 时,请联系 ZEGO 技术支持处理
ZIMAppConfig appConfig = ZIMAppConfig();
appConfig.appID = appID;
appConfig.appSign = appSign;
ZIM.create(appConfig);
// 将 appID 和 appSign 替换为您申请的 AppID 和 AppSign,Web 平台无需传入 AppSign
3. 使用 ZIMEventHandler 获取回调
ZIMEventHandler 类包含了 ZIM 中各种事件回调的 static Function,可通过传入 Function 来接收 ZIM 中的事件回调,处理 SDK 异常、消息通知回调。
下图以在 “zim_event_handler_manager.dart” 文件中,设置自定义连接状态改变为例。
// 接收错误码的回调,通过该回调可以收到 sdk 的通用错误码。
static void Function(ZIM zim, ZIMError errorInfo)? onError;
// 用于提示 token 即将过期,开发者可以通过该回调监听 token 快要过期的通知,自定义应对这一事件的 UI 状态
static void Function(ZIM zim, int second)? onTokenWillExpire;
// 连接状态变化通知,开发者可以通过该回调监听当前的登录连接状态,展示对应的 UI 状态
static void Function(ZIM zim, ZIMConnectionState state, ZIMConnectionEvent event, Map extendedData)? onConnectionStateChanged;
// 接收 1v1 通信的消息回调,登录后可通过该回调接收 1v1 通信的消息
static void Function(ZIM zim, List<ZIMMessage> messageList, String fromUserID)? onReceivePeerMessage;
详细的接口介绍,请参考 onTokenWillExpire、onConnectionStateChanged、onReceivePeerMessage、onReceiveRoomMessage、onRoomMemberJoined、onRoomMemberLeft。
4. 登录 ZIM
创建实例后,客户端 A 和 B 需要登录 ZIM,只有登录成功后才可以开始发送、接收消息、更新 Token 等。
调用 login 接口,传入userID 和登录配置 ZIMLoginConfig 对象,进行登录。
- “userID”、“userName” 支持开发者自定义规则生成。建议开发者将 “userID” 设置为一个有意义的值,可将其与自己的业务账号系统进行关联。
2.3.0
或以上版本的 SDK,默认鉴权方式为 “AppSign 鉴权”,登录 ZIM 时无需传入Token
。- 如果您使用的是 “Token 鉴权”,请参考 使用 Token 鉴权 文档,获取 Token 后,并在登录 ZIM 时传入可选参数 Token,鉴权通过后才能登录成功。
// 登录时:
// 使用 Token 鉴权,需要开发者填入 "使用 Token 鉴权" 文档生成的 Token,详情请参考 [使用 Token 鉴权;开发 Web 平台应用时仅支持 Token 鉴权
// 使用 AppSign 鉴权 (2.3.0 或以上版本的默认鉴权方式),Token 参数填空字符串
try{
ZIMLoginConfig loginConfig = ZIMLoginConfig();
//该用户的用户昵称,不填写代表不修改用户昵称
loginConfig.userName = 'userName';
//若使用 token 作为登录鉴权的方式,请填写该参数,否则无需填写
loginConfig.token = '';
// 本次登录是否为离线登录,详情请参考离线登录相关文档
loginConfig.isOfflineLogin = false;
await ZIM.getInstance()?.login('zego', loginConfig);
// 登录成功,编写登录成功的业务逻辑
} on PlatformException catch(onError){
// 登录失败
//登录失败的错误码,请参考错误码文档进行处理
onError.code;
//登录失败的错误信息
onError.message;
}
5. 发送消息
客户端 A 登录成功后,可以向客户端 B 发送消息。
目前 ZIM 支持的消息类型如下:
目前 ZIM 支持的消息类型如下:
消息类型 | 说明 | 特性及适用场景 |
---|---|---|
ZIMTextMessage(1) | 文本消息。消息大小不超过 32 KB,单个客户端发送频率限制为 10 次/秒。 | 消息可靠有序,可存储为历史消息(保存时间请参考 计费说明 - 版本说明 中“历史消息存储天数”。);一般适用于“单聊”、“群聊”等即时聊天的场景和“房间聊天”的公屏聊天场景。房间解散后,“房间聊天”的消息不存储。 相关接口:sendMessage |
ZIMCommandMessage(2) | 开发者可自定义数据内容的信令消息。消息大小不超过 5 KB,单个客户端发送频率限制为 10 次/秒。 | 支持更高的并发;一般适用于“语聊房”、“在线课堂”等房间内的信令传输,比如上下麦操作、送礼物,发送在线课堂课件等。 相关接口:sendMessage |
ZIMBarrageMessage(20) | 房间内弹幕文本消息。消息大小不超过 5 KB,单个客户端发送频率无限制。 | 专门用于房间内的高频、不可靠、允许丢掉的消息,一般适用于发送“弹幕消息”的场景中。 支持高并发,但不可靠,不保证消息送达。 相关接口:sendMessage |
ZIMImageMessage(11) | 图片消息。支持主流图片格式,包括 JPG、PNG、BMP、TIFF、GIF、WebP,大小不超过 10 MB,单个客户端发送频率限制为 10 次/秒。 | 消息可靠有序,可存储为历史消息(保存时间请参考 计费说明 - 版本说明 中“历史消息存储天数”。);一般用于单聊、房间、群聊等即时聊天场景。 相关接口:sendMediaMessage |
ZIMFileMessage(12) | 文件消息。消息内容为文件,格式不限,大小不超过 100 MB,单个客户端发送频率限制为 10 次/秒。 | |
ZIMAudioMessage(13) | 语音消息。支持 MP3、M4A 格式的语音文件,时长不超过 300 秒,大小不超过 6 MB,单个客户端发送频率限制为 10 次/秒。 | |
ZIMVideoMessage(14) | 视频消息。支持 MP4、MOV 格式的视频文件,大小不超过 100 MB,单个客户端发送频率限制为 10 次/秒。仅支持视频编码格式为 H264 和 H265 的视频文件在消息发送成功后获取该视频首帧的宽、高信息。 | |
ZIMCombineMessage(100) | 合并消息,消息大小无限制,单个客户端发送频率限制为 10 次/秒。 | 消息可靠有序,可存储为历史消息(保存时间请参考 计费说明 - 版本说明 中“历史消息存储天数”。);一般用于单聊、房间、群聊等即时聊天场景。 相关接口:sendMessage |
ZIMCustomMessage(200) | 自定义消息。开发者可自定义消息的类型,并自行完成消息的解析,ZIM SDK 不负责定义和解析自定义消息的具体内容。 | 一般可用于发送投票类型、接龙类型、视频卡片类型等消息。 相关接口:sendMessage |
以下为发送单聊文本消息
为例:客户端 A 可以调用 sendMessage 接口,传入客户端 B 的 userID、消息内容、消息类型 ZIMConversationType,即可发送一条文本消息
到 B 的客户端。
- ZIMMessageSentResult 回调,判断消息是否发送成功。
- onMessageAttached 回调,在消息发送前,可以获得一个临时的 ZIMMessage,以便您添加一些业务处理逻辑。例如:在发送消息前,获取到该条消息的 ID 信息。开发者在发送“视频”等内容较大的消息时,可以在消息上传完成前,获取对应该条消息的 localMessageID,实现发送前 Loading 的效果。
// 以下以发送单聊信息为例,conversationType 设置为 ZIMConversationType.peer
ZIMTextMessage textMessage = ZIMTextMessage(message: "message");
ZIMMessageSendConfig sendConfig = ZIMMessageSendConfig();
// 设置消息优先级
sendConfig.priority = ZIMMessagePriority.low;
ZIMPushConfig pushConfig = ZIMPushConfig();
pushConfig.title = "离线推送的标题";
pushConfig.content = "离线推送的内容";
pushConfig.extendedData = "离线推送的扩展信息";
sendConfig.pushConfig = pushConfig;
ZIMMessageSendNotification notification = ZIMMessageSendNotification(onMessageAttached: (message){
// 发送前的回调,客户可以在这里获取一个临时对象,该对象与开发者创建的 zimMessage 对象属于同一对象,开发者可利用此特性做一些业务逻辑,如提前展示 UI 等
});
// 设置会话类型,选择其一向对应的会话类型发送消息
ZIMConversationType type = ZIMConversationType.peer;
ZIM.getInstance()!.sendMessage(textMessage, toConversationID, type, sendConfig).then((value) => {
// 开发者可以通过该回调监听消息是否发送成功。
}).catchError((onError){
// 开发者可以捕获发送失败的异常。
});
6. 接收单聊消息
客户端 B 登录 ZIM 后,通过实现 ZIMEventHandler 中的 onPeerMessageReceived 监听接口,接收客户端 A 发送过来的消息。
收到消息时,由于类型是基类,首先需要判断消息类型,开发者需要强转基类为具体的子类,然后获取消息内容。
onPeerMessageReceived = (ZIM zim, List<ZIMMessage> messageList,
ZIMMessageReceivedInfo info, String fromUserID) {
//收到 fromUserID 发来的 messageList
//收到单聊消息触发此处
for (ZIMMessage message in messageList) {
switch (message.type) {
case ZIMMessageType.text:
message as ZIMTextMessage;
break;
case ZIMMessageType.command:
message as ZIMCommandMessage;
break;
case ZIMMessageType.image:
message as ZIMImageMessage;
break;
case ZIMMessageType.file:
message as ZIMFileMessage;
break;
default:
}
}
};
7. 退出登录
如果客户端需要退出登录,直接调用 logout 接口即可。
ZIM.getInstance()!.logout();
8. 销毁 ZIM 实例
如果不需要 ZIM 实例,可直接调用 destroy 接口,销毁实例。
ZIM.getInstance()!.destroy();
3.2 API 时序图
通过以上的实现流程描述,API 接口调用时序图如下:
- 发送消息时,统一使用 sendMessage 接口,并根据消息类型传入对应的 ZIMConversationType 取值。
- 接收消息时:
- 单聊消息(Peer 类型),通过 onReceivePeerMessage 回调接收。
- 房间消息(Room 类型),通过 onReceiveRoomMessage 回调接收。
- 群组消息(Group 类型),通过 onReceiveGroupMessage 回调接收。