diff --git a/docs/.vuepress/sidebar/document.ts b/docs/.vuepress/sidebar/document.ts
index 4ff03a56d..3fa72b057 100644
--- a/docs/.vuepress/sidebar/document.ts
+++ b/docs/.vuepress/sidebar/document.ts
@@ -25,9 +25,6 @@ const documentSidebar = [
{ text: 'Demo(EaseIM App)体验', link: 'demo.html', except: ['web', 'windows', 'react-native', 'flutter', 'unity', 'server-side'] },
{ text: '快速开始', link: 'quickstart.html', except: ['windows', 'react-native', 'flutter', 'unity', 'server-side'] },
{ text: '快速开始', link: 'quickstart.html', only: ['windows', 'react-native', 'flutter', 'unity'] },
- { text: '按需导入 SDK(推荐)', link: 'import_sdk_minicore.html', only: ['web'] },
- { text: 'SDK 集成概述', link: 'overview.html', only: ['android', 'ios', 'web', 'harmonyos', 'flutter'] },
- { text: 'SDK 集成概述', link: 'overview.html', only: ['windows', 'react-native', 'unity'] },
// { text: '私有云 SDK 集成配置', link: 'privatecloud.html', except: ['windows', 'server-side', 'react-native', 'flutter', 'unity'] },
{ text: 'SDK 更新日志', link: 'releasenote.html', except: ['server-side']},
/*{ text: 'API reference', link: 'apireference.html', only: ['android', 'ios', 'web', 'windows', 'react-native', 'flutter', 'unity']},*/
@@ -40,8 +37,19 @@ const documentSidebar = [
except: ['applet', 'electron','linux']
},
{
- text: '基础功能',
+ text: '用户指南',
children: [
+ { text: '集成 SDK', link: 'integration.html' },
+ { text: '初始化', link: 'initialization.html' },
+ {
+ text: '登录',
+ collapsible: true,
+ children: [
+ { text: '登录介绍', link: 'login.html' },
+ { text: '连接', link: 'connection.html' },
+ { text: '多设备登录', link: 'multi_device.html' },
+ ]
+ },
{
text: '消息管理',
collapsible: true,
@@ -53,6 +61,7 @@ const documentSidebar = [
{ text: '搜索消息', link: 'message_search.html', except: ['web', 'harmonyos']},
{ text: '消息回执', link: 'message_receipt.html'},
{ text: '修改消息', link: 'message_modify.html'},
+ { text: '消息表情回复', link: 'reaction.html' },
{ text: '转发消息', link: 'message_forward.html', except: ['web']},
{ text: '导入和插入消息', link: 'message_import_insert.html', except: ['web']},
{ text: '更新消息', link: 'message_update.html', except: ['web']},
@@ -60,6 +69,7 @@ const documentSidebar = [
{ text: '置顶消息', link: 'message_pin.html', except: ['harmonyos']},
{ text: '翻译消息', link: 'message_translation.html', except: ['harmonyos']},
{ text: '只投在线用户', link: 'message_deliver_only_online.html'},
+ { text: '消息审核(举报)', link: 'moderation.html', except: ['harmonyos']},
{ text: '获取消息流量统计', link: 'message_traffic_statis.html', only: ['android', 'ios'] },
]
},
@@ -70,15 +80,13 @@ const documentSidebar = [
{ text: '会话介绍', link: 'conversation_overview.html' },
{ text: '会话列表', link: 'conversation_list.html' },
{ text: '本地会话', link: 'conversation_local.html', only: ['web'] },
- { text: '会话已读回执', link: 'conversation_receipt.html', only: ['android', 'ios', 'web'] },
+ { text: '会话已读回执', link: 'conversation_receipt.html' },
{ text: '会话未读数', link: 'conversation_unread.html', except: ['web'] },
{ text: '置顶会话', link: 'conversation_pin.html' },
{ text: '会话标记', link: 'conversation_mark.html' },
{ text: '删除会话', link: 'conversation_delete.html' },
]
},
- { text: '管理用户属性', link: 'userprofile.html' },
- { text: '管理用户关系', link: 'user_relationship.html' },
{
text: '群组管理',
collapsible: true,
@@ -87,6 +95,8 @@ const documentSidebar = [
{ text: '创建和管理群组', link: 'group_manage.html' },
{ text: '管理群组成员', link: 'group_members.html' },
{ text: '管理群组属性', link: 'group_attributes.html' },
+ { text: '管理子区', link: 'thread.html', except: ['harmonyos'] },
+ { text: '管理子区消息', link: 'thread_message.html', except: ['harmonyos'] }
]
},
{
@@ -99,13 +109,16 @@ const documentSidebar = [
{ text: '管理聊天室属性', link: 'room_attributes.html' },
]
},
- ],
- except: ['applet', 'server-side', 'electron','linux']
- },
- {
- text: '进阶功能',
- children: [
- {
+ {
+ text: '用户相关',
+ collapsible: true,
+ children: [
+ { text: '用户关系', link: 'user_relationship.html' },
+ { text: '用户属性', link: 'userprofile.html' },
+ { text: '在线状态订阅', link: 'message_retrieve.html' },
+ ]
+ },
+ {
text: '离线推送',
collapsible: true,
children: [
@@ -139,33 +152,33 @@ const documentSidebar = [
{ text: 'FAQ', link: 'push/push_solution.html', only: ['android', 'ios','harmonyos']},
]
},
- { text: '登录多个设备', link: 'multi_device.html' },
- { text: '管理在线状态订阅', link: 'presence.html' },
- { text: '消息表情回复', link: 'reaction.html' },
- {
- text: '子区管理',
- collapsible: true,
- children: [
- { text: '管理子区', link: 'thread.html', except: ['harmonyos'] },
- { text: '管理子区消息', link: 'thread_message.html', except: ['harmonyos'] }
- ]
- },
- { text: '消息审核(举报)', link: 'moderation.html', except: ['harmonyos']},
],
except: ['applet','server-side','electron','linux']
},
{
- text: '其他',
+ text: '错误排查',
children: [
{ text: '错误码', link: 'error.html' },
- //{ text: 'EaseIMKit 使用指南', link: 'easeimkit.html', except: ['web', 'windows', 'react-native', 'flutter', 'unity'] },
- { text: 'EaseCallKit 使用指南', link: 'easecallkit.html', except: ['web', 'windows', 'react-native', 'flutter', 'unity', 'harmonyos'] },
+ { text: '日志', link: 'log.html', except: ['flutter'] },
+ ],
+ except: ['applet', 'server-side','electron','linux']
+ },
+ {
+ text: 'CallKit 使用指南',
+ children: [
+ { text: 'EaseCallKit 使用指南', link: 'easecallkit.html', only: ['android', 'ios'] },
{ text: 'CallKit 使用指南', link: 'easecallkit.html', only: ['web'] },
- { text: '苹果隐私策略', link: 'privacy_policy.html', only: ['ios'] },
],
except: ['applet', 'server-side','electron','linux']
},
+ {
+ text: '苹果隐私策略',
+ children: [
+ { text: '苹果隐私策略', link: 'privacy_policy.html', only: ['ios'] },
+ ],
+ except: ['applet', 'server-side','electron','linux']
+ },
{
text: '精简版 SDK',
children: [
@@ -182,22 +195,30 @@ const documentSidebar = [
only: ['applet']
},
{
- text: '集成介绍',
+ text: '用户指南',
children: [
- { text: '微信小程序', link: 'wechat.html' },
- { text: 'QQ 小程序', link: 'qq.html' },
- { text: '百度小程序', link: 'baidu.html' },
- { text: '抖音小程序', link: 'bytedance.html' },
- { text: '支付宝小程序', link: 'alipay.html' },
- { text: 'Uniapp 全平台', link: 'uniapp.html' },
- { text: '小程序 API 文档', link: 'apidoc.html' },
- ],
- only: ['applet']
- },
- {
- text: '基本功能',
- children: [
- { text: '初始化及登录', link: 'initialization.html' },
+ {
+ text: '集成介绍',
+ children: [
+ { text: '微信小程序', link: 'wechat.html' },
+ { text: 'QQ 小程序', link: 'qq.html' },
+ { text: '百度小程序', link: 'baidu.html' },
+ { text: '抖音小程序', link: 'bytedance.html' },
+ { text: '支付宝小程序', link: 'alipay.html' },
+ { text: 'Uniapp 全平台', link: 'uniapp.html' },
+ { text: '小程序 API 文档', link: 'apidoc.html' },
+ ],
+ },
+ { text: '初始化', link: 'initialization.html' },
+ {
+ text: '登录',
+ collapsible: true,
+ children: [
+ { text: '登录介绍', link: 'login.html' },
+ { text: '连接', link: 'connection.html' },
+ { text: '多设备登录', link: 'multi_device.html' },
+ ],
+ },
{
text: '消息管理',
collapsible: true,
@@ -207,11 +228,13 @@ const documentSidebar = [
{ text: '获取历史消息', link: 'message_retrieve.html' },
{ text: '撤回消息', link: 'message_recall.html' },
{ text: '消息回执', link: 'message_receipt.html' },
+ { text: '消息表情回复', link: 'reaction.html' },
{ text: '修改消息', link: 'message_modify.html' },
{ text: '删除消息', link: 'message_delete.html' },
{ text: '置顶消息', link: 'message_pin.html' },
{ text: '翻译消息', link: 'message_translation.html' },
- { text: '只投在线用户', link: 'message_deliver_only_online.html'},
+ { text: '只投在线用户', link: 'message_deliver_only_online.html'},
+ { text: '消息审核(举报)', link: 'moderation.html'},
]
},
{
@@ -226,8 +249,6 @@ const documentSidebar = [
{ text: '删除会话', link: 'conversation_delete.html'},
]
},
- { text: '管理用户属性', link: 'userprofile.html' },
- { text: '管理用户关系', link: 'user_relationship.html' },
{
text: '群组管理',
collapsible: true,
@@ -236,6 +257,14 @@ const documentSidebar = [
{ text: '创建和管理群组', link: 'group_manage.html' },
{ text: '管理群组成员', link: 'group_members.html' },
{ text: '管理群组属性', link: 'group_attributes.html' },
+ {
+ text: '子区管理',
+ collapsible: true,
+ children: [
+ { text: '管理子区', link: 'thread.html' },
+ { text: '管理子区消息', link: 'thread_message.html' }
+ ]
+ },
]
},
{
@@ -248,12 +277,15 @@ const documentSidebar = [
{ text: '管理聊天室属性', link: 'room_attributes.html' },
]
},
- ],
- only: ['applet']
- },
- {
- text: '进阶功能',
- children: [
+ {
+ text: '用户相关',
+ collapsible: true,
+ children: [
+ { text: '用户关系', link: 'user_relationship.html' },
+ { text: '用户属性', link: 'userprofile.html' },
+ { text: '在线状态订阅', link: 'presence.html' },
+ ]
+ },
{ text: '离线推送',
collapsible: true,
children: [
@@ -265,25 +297,20 @@ const documentSidebar = [
{ text: 'uni-app 离线推送', link: 'push/uniapp_push.html' }
]
},
- { text: '登录多个设备', link: 'multi_device.html' },
- { text: '管理在线状态订阅', link: 'presence.html' },
- { text: '消息表情回复', link: 'reaction.html' },
- {
- text: '子区管理',
- collapsible: true,
- children: [
- { text: '管理子区', link: 'thread.html' },
- { text: '管理子区消息', link: 'thread_message.html' }
- ]
- },
- { text: '消息审核(举报)', link: 'moderation.html'},
],
only: ['applet']
},
{
- text: '其他帮助',
+ text: '错误排查',
children: [
{ text: '错误码', link: 'error.html' },
+ { text: '日志', link: 'log.html' },
+ ],
+ only: ['applet']
+ },
+ {
+ text: '其他帮助',
+ children: [
{ text: 'Uniapp 生成原生 Android、iOS 应用', link: 'uniappnativeapp.html' },
{ text: '小程序模板使用指南', link: 'uniappuikit.html' },
{ text: '如何配置服务器域名', link: 'serverconfig.html' },
diff --git a/docs/README.md b/docs/README.md
index c187db4f8..88417a7d7 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -106,6 +106,9 @@ starter:
- icon: /sdk/iOS.svg
link: /document/ios/easecallkit.html
text: iOS
+ - icon: /sdk/web.svg
+ link: /document/web/easecallkit.html
+ text: Web
projects:
- title: SDK/服务端功能
features:
diff --git a/docs/document/android/connection.md b/docs/document/android/connection.md
new file mode 100644
index 000000000..8dd950803
--- /dev/null
+++ b/docs/document/android/connection.md
@@ -0,0 +1,67 @@
+# 连接
+
+应用客户端成功连接到环信服务器后,才能使用环信即时通讯 SDK 的收发消息等功能。
+
+你调用 `loginWithToken` 或 `login` 方法登录后,客户端 SDK 会自动连接环信服务器。关于登录详情,请参见[登录文档](login.html)。
+
+## 监听连接状态
+
+你可以通过注册连接监听确认连接状态。
+
+```java
+EMConnectionListener connectionListener = new EMConnectionListener() {
+ @Override
+ public void onConnected() {
+
+ }
+ @Override
+ public void onDisconnected(int errorCode) {
+
+ }
+
+ @Override
+ public void onLogout(int errorCode) {
+
+ }
+
+ @Override
+ public void onTokenWillExpire() {
+
+ }
+
+ @Override
+ public void onTokenExpired() {
+
+ }
+ // 连接成功,开始从服务器拉取离线消息时触发。
+ // 注意:如果本次登录服务器没有离线消息,不会触发该回调。
+ @Override
+ public void onOfflineMessageSyncStart() {
+
+ }
+ // 离线用户上线后从服务器拉取离线消息结束时触发。
+ // 注意:如果再拉取离线过程中因网络或其他原因导致连接断开,不会触发该回调。
+ @Override
+ public void onOfflineMessageSyncFinish() {
+
+ }
+};
+// 注册连接状态监听
+EMClient.getInstance().addConnectionListener(connectionListener);
+// 移除连接状态监听
+EMClient.getInstance().removeConnectionListener(connectionListener);
+```
+
+## 自动重连
+
+登录后,如果由于网络信号弱、切换网络等引起的连接中断,SDK 会自动尝试重连。重连成功或者失败时分别会收到 `onConnected` 和 `onDisconnected` 通知。
+
+不过,SDK 在以下情况下会停止自动重连。你需要调用 `login` 方法登录。
+
+- 用户调用了 SDK 的登出方法 `logout` 主动退出登录。
+- 登录时鉴权错误,例如, token 无效(错误码 104)或已过期(错误码 108)。
+- 用户在其他的设备上更改了密码,导致此设备上自动登录失败,提示错误码 216。
+- 用户的账号被从服务器端删除,提示错误码 207。
+- 用户在另一设备登录,将当前设备上登录的用户踢出,提示错误码 206。
+- 用户登录设备数量超过限制,提示错误码 214。
+- 应用程序的日活跃用户数量(DAU)或月活跃用户数量(MAU)达到上限,提示错误码 8。
\ No newline at end of file
diff --git a/docs/document/android/conversation_receipt.md b/docs/document/android/conversation_receipt.md
index e71e0f212..68880530b 100644
--- a/docs/document/android/conversation_receipt.md
+++ b/docs/document/android/conversation_receipt.md
@@ -16,6 +16,13 @@
2. 消息接收方进入会话页面,阅读消息后,调用 `ackConversationRead` 方法发送会话已读回执。
3. 消息发送方通过监听 `OnConversationRead` 回调接收会话已读回执。
+## 前提条件
+
+开始前,请确保满足以下条件:
+
+- 完成 SDK 初始化,并连接到服务器,详见 [快速开始](quickstart.html)。
+- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。
+
## 实现方法
参考以下步骤在单聊中实现会话已读回执:
diff --git a/docs/document/android/initialization.md b/docs/document/android/initialization.md
new file mode 100644
index 000000000..6cb7476b6
--- /dev/null
+++ b/docs/document/android/initialization.md
@@ -0,0 +1,24 @@
+# SDK 初始化
+
+初始化是使用 SDK 的必要步骤,需在所有接口方法调用前完成。
+
+如果进行多次初始化操作,只有第一次初始化以及相关的参数生效。
+
+:::tip
+需要在主进程中进行初始化。
+:::
+
+## 前提条件
+
+有效的环信即时通讯 IM 开发者账号和 App key,详见[环信即时通讯云控制台的相关文档](/product/enable_and_configure_IM.html#创建应用)。
+
+## 初始化
+
+初始化示例代码:
+
+```java
+EMOptions options = new EMOptions();
+options.setAppKey("Your appkey");
+......// 其他 EMOptions 配置。
+EMClient.getInstance().init(context, options);
+```
diff --git a/docs/document/android/integration.md b/docs/document/android/integration.md
new file mode 100644
index 000000000..8aa916b69
--- /dev/null
+++ b/docs/document/android/integration.md
@@ -0,0 +1,163 @@
+# 集成 SDK
+
+本文介绍如何将环信即时通讯 IM SDK 集成到你的 Android 项目。
+
+## 开发环境要求
+
+- Android Studio 3.0 或以上版本;
+- Android SDK API 等级 21 或以上;
+- Android 5.0 或以上版本的设备。
+
+## 集成 SDK
+
+选择如下任意一种方式将环信即时通讯 IM SDK 集成到你的项目中。
+
+:::tip
+
+1. 以下集成方式只需选择一种,同时使用多种集成方式可能会报错。
+2. 请点击查看[发版说明](releasenote.html)获得最新版本号。
+
+:::
+
+### 方法一:使用 mavenCentral 自动集成
+
+:::tip
+
+该方法仅适用于 v3.8.2 或以上版本。
+
+:::
+
+1. 在项目的 `build.gradle` 中添加 `mavenCentral()` 仓库。
+
+```gradle
+buildscript {
+ repositories {
+ ...
+ mavenCentral()
+ }
+ ...
+}
+
+allprojects {
+ repositories {
+ ...
+ mavenCentral()
+ }
+}
+```
+
+2. 在 `module` 的 `build.gradle` 中添加如下依赖:
+
+```gradle
+...
+dependencies {
+ ...
+ // x.y.z 请填写具体版本号,必须为 3.8.2 或以上版本。
+ // 可通过 SDK 发版说明获得最新版本号。
+ implementation 'io.hyphenate:hyphenate-chat:x.x.x'
+}
+```
+
+:::tip
+如果使用 3.8.0 之前的版本,gradle 依赖需要按照下面格式添加:
+:::
+
+```gradle
+implementation 'io.hyphenate:hyphenate-sdk:3.7.5' // 完整版本,包含音视频功能
+
+implementation 'io.hyphenate:hyphenate-sdk-lite:3.7.5' // 精简版,只包含IM功能
+```
+
+### 方法二:手动复制 SDK 文件
+
+打开 SDK 下载页面,获取最新版的环信即时通讯 IM Android SDK,然后解压。
+
+
+
+将 SDK 包内 libs 路径下的如下文件,拷贝到你的项目路径下:
+
+| 文件或文件夹 | 项目路径 |
+| :------------------- | :--------------------- |
+| `hyphenatechat_xxx.jar` 文件 | `/app/libs/ ` |
+| `arm64-v8a` 文件夹 | `/app/src/main/jniLibs/` |
+| `armeabi-v7a` 文件夹 | `/app/src/main/jniLibs/` |
+| `x86` 文件夹 | `/app/src/main/jniLibs/` |
+| `x86_64` 文件夹 | `/app/src/main/jniLibs/` |
+
+如果对生成的 `apk` 大小比较敏感,我们建议使用 `jar` 方式,并且手工拷贝 `so`,而不是使用 `Aar`,因为 `Aar` 方式会把各个平台的 `so` 文件都包含在其中。采用 `jar` 方式,可以仅保留一个 `ARCH` 目录,建议仅保留 `armeabi-v7a`,这样虽然在对应平台执行的速度会降低,但是能有效减小 `apk` 的大小。
+
+### 方法三:动态加载 .so 库文件
+
+为了减少应用安装包的大小,SDK 提供了 `EMOptions#setNativeLibBasePath` 方法支持动态加载 SDK 所需的 `.so` 文件。以 SDK 4.5.0 为例,`.so` 文件包括 `libcipherdb.so` 和 `libhyphenate.so` 两个文件。**从 4.11.0 开始,`.so`文件还包含 `libaosl.so` 文件**。
+
+该功能的实现步骤如下:
+
+1. 下载最新版本的 SDK 并解压缩。
+2. 集成 `hyphenatechat_4.5.0.jar` 到你的项目中。
+3. 将所有架构的 `.so` 文件上传到你的服务器,并确保应用程序可以通过网络下载目标架构的 `.so` 文件。
+4. 应用运行时,会检查 `.so` 文件是否存在。如果未找到,应用会下载该 `.so` 文件并将其保存到你自定义的应用程序的私有目录中。
+5. 调用 `EMClient#init` 初始化时,将 `.so` 文件所在的 app 私有目录作为参数设置进 `EMOptions#setNativeLibBasePath` 方法中。
+6. 调用 `EMClient#init` 初始化后,SDK 会自动从指定路径加载 `.so` 文件。
+
+:::tip
+1. 该方法仅适合手动集成 Android SDK,不适用于通过 Maven Central 集成。
+2. so 库的路径取决于 `EMOptions#setNativeLibBasePath` 方法的 `path` 参数:
+- 若设置了 `path` 参数,SDK 内部会使用 `System.load` 从设置的路径下搜索和加载 so 库。该路径必须为有效的 app 的私有目录路径。
+- `path` 参数为空或者不调用该方法时,SDK 内部会使用 `system.loadLibrary` 从系统默认路径中搜索并加载 so 库。
+:::
+
+```java
+//假设用户已经通过动态下发的方式,将环信 SDK 中的 libcipherdb.so 和 libhyphenate.so 两个 so 库,放到 app 的 /data/data/packagename/files 目录下。
+String filesPath = mContext.getFilesDir().getAbsolutePath();
+
+EMOptions options = new EMOptions();
+options.setNativeLibBasePath(filesPath);
+
+EMClient.getInstance().init(mContext, options);
+
+```
+
+### 添加项目权限
+
+根据场景需要,在 `/app/src/main/AndroidManifest.xml` 文件中添加如下行,获取相应的设备权限:
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+### 防止代码混淆
+
+在 `app/proguard-rules.pro` 文件中添加如下行,防止混淆 SDK 的代码:
+
+```java
+-keep class com.hyphenate.** {*;}
+-dontwarn com.hyphenate.**
+```
\ No newline at end of file
diff --git a/docs/document/android/log.md b/docs/document/android/log.md
new file mode 100644
index 000000000..b1fb04d45
--- /dev/null
+++ b/docs/document/android/log.md
@@ -0,0 +1,27 @@
+# SDK 日志
+
+环信即时通讯 IM 日志记录 SDK 相关的信息和事件。环信技术支持团队帮你排查问题时可能会请你发送 SDK 日志。
+
+## 输出信息到日志文件
+
+默认情况下,SDK 最多可生成和保存三个文件,`easemob.log` 和两个 `easemob_YYYY-MM-DD_HH-MM-SS.log` 文件。这些文件为 UTF-8 编码,每个不超过 2 MB。SDK 会将最新的日志写入 `easemob.log` 文件,写满时则会将其重命名为对应时间点的 `easemob_YYYY-MM-DD_HH-MM-SS.log` 文件,若日志文件超过三个,则会删除最早的文件。
+
+例如,SDK 在 2024 年 1 月 1 日上午 8:00:00 记录日志时会生成 `easemob.log` 文件,若在 8:30:00 将 `easemob.log` 文件写满则会将其重命名为 `easemob_2024-01-01_08-30-00.log` 文件,随后在 9:30:30 和 10:30:30 分别生成了 `easemob_2024-01-01_09-30-30.log` 和 `easemob_2024-01-01_10-30-30.log` 文件,则此时 `easemob_2024-01-01_08-30-00.log` 文件会被移除。
+
+SDK 默认输出调试信息(所有日志,包括调试信息、警告和错误),如果只需输出错误日志,需要关闭调试模式。
+
+```java
+// 需要在 SDK 初始化后调用
+EMClient.getInstance().setDebugMode(false);
+```
+
+## 获取本地日志
+
+打开以下目录,获取本地日志。在下列代码中,你需要进行如下替换:
+
+- `{应用包名}` 替换为应用的包名,例如 `com.hyphenate.chatuidemo`。
+- `{App Key}` 需要替换为应用的环信 App Key。
+
+```shell
+adb pull /sdcard/android/data/{应用包名}/{App Key}/core_log
+```
\ No newline at end of file
diff --git a/docs/document/android/login.md b/docs/document/android/login.md
new file mode 100644
index 000000000..25d146767
--- /dev/null
+++ b/docs/document/android/login.md
@@ -0,0 +1,127 @@
+# 登录
+
+初始化 IM SDK 后,你需要首先调用接口登录。登录成功后,才能使用 IM 的功能。
+
+## 用户注册
+
+用户注册模式分为以下两种:
+
+- 开放注册:一般在体验 Demo 和测试环境时使用,正式环境中不推荐使用该方式注册环信账号。要使用开放注册,需要在[环信即时通讯云控制台](https://console.easemob.com/user/login)的**即时通讯** > **服务概览**的**设置**区域,将**用户注册模式**设置为**开放注册**。只有打开该开关,才能使用客户端或 [REST API](/document/server-side/account_system.html#开放注册单个用户)开放注册用户。
+
+示例代码如下所示:
+
+ ```java
+// 注册失败会抛出 HyphenateException。
+EMClient.getInstance().createAccount(mAccount, mPassword);// 同步方法。
+```
+
+- 授权注册:通过环信提供的 REST API 注册环信用户账号,注册后保存到你的服务器或返给客户端。要使用授权注册,你需要在[环信即时通讯云控制台](https://console.easemob.com/user/login)的**即时通讯** > **服务概览**的**设置**区域,将**用户注册模式**设置为**授权注册**。相关的 REST API 介绍,详见[授权注册单个用户](/document/server-side/account_system.html#授权注册单个用户)和[批量授权注册用户](/document/server-side/account_system.html#批量授权注册用户)的接口介绍。
+
+除此以外,可以在[环信即时通讯云控制台](https://console.easemob.com/user/login)创建正式环境下和测试环境下的用户,详见[创建用户相关介绍](/product/enable_and_configure_IM.html#创建-im-用户)。
+
+## 主动登录
+
+1. **用户 ID + token** 是更加安全的登录方式。
+
+测试环境下,你在[环信即时通讯云控制台](https://console.easemob.com/user/login)创建用户后,环信服务器会自动为这些用户分配用户 Token,详见[测试环境下创建用户的介绍](/product/enable_and_configure_IM.html#测试环境)。
+
+使用 token 登录时需要处理 token 过期的问题,比如在每次登录时更新 token 等机制。
+
+```java
+EMClient.getInstance().loginWithToken(mAccount, mToken, new EMCallBack() {
+ // 登录成功回调
+ @Override
+ public void onSuccess() {
+
+ }
+
+ // 登录失败回调,包含错误信息
+ @Override
+ public void onError(int code, String error) {
+
+ }
+});
+```
+
+2. **用户 ID + 密码**登录是传统的登录方式。用户名和密码均由你的终端用户自行决定,密码需要符合[密码规则要求](/document/server-side/account_system.html#开放注册单个用户)。
+
+```java
+EMClient.getInstance().login(mAccount, mPassword, new EMCallBack() {
+ // 登录成功回调
+ @Override
+ public void onSuccess() {
+
+ }
+
+ // 登录失败回调,包含错误信息
+ @Override
+ public void onError(int code, String error) {
+
+ }
+
+});
+```
+
+## 自动登录
+
+初始化时,你可以设置 `EMOptions#setAutoLogin` 选项确定是否自动登录。如果设置为自动登录,则登录成功之后,后续初始化 SDK 时会自动登录。
+
+## 获取当前登录的用户
+
+你可以调用 `EMClient#getCurrentUser` 方法获取当前登录用户的用户 ID。
+
+## 获取登录状态
+
+你可以调用 `EMClient#isLoggedIn` 方法获取当前用户的登录状态。
+
+## 退出登录
+
+你可以调用 `logout` 方法退出登录。退出登录后,你不会再收到其他用户发送的消息。
+
+同步方法:
+
+```java
+EMClient.getInstance().logout(true);
+```
+
+异步方法:
+
+```java
+EMClient.getInstance().logout(true, new EMCallBack() {
+
+ @Override
+ public void onSuccess() {
+
+ }
+
+ @Override
+ public void onError(int code, String message) {
+
+ }
+});
+```
+
+:::tip
+
+1. 如果集成了 FCM 等第三方推送,`logout` 方法中 `unbindToken` 参数需设为 `true`,退出时会解绑设备 token,否则可能会出现退出了,还能收到消息推送通知的现象。
+有时可能会遇到网络问题而解绑失败,app 处理时可以弹出提示框让用户选择,是否继续退出(弹出框提示继续退出能收到消息的风险),如果用户选择继续退出,传 `false` 再调用 `logout` 方法退出成功。当然也可以失败后还是返回退出成功,然后在后台起个线程不断调用 `logout` 方法直到成功。这样存在风险,即用户杀掉了 app,网络恢复后用户还会继续收到消息。
+
+2. 如果调用异步退出方法,在收到 `onsuccess` 回调后才能去调用 IM 相关方法,例如 `loginWithToken`。
+:::
+
+## 账号切换
+
+若在 app 中从当前账号切换到其他账号,你需要首先调用 `logout` 方法登出,然后再调用 `loginWithToken` 或 `login` 方法登录。
+
+## 多设备登录
+
+除了单端单设备登录,环信即时通讯 IM 支持同一账号在多端的多个设备上登录。多设备登录时,若同端设备数量超过限制,新登录的设备会将之前登录的设备踢下线。
+
+关于多设备登录场景中的设备数量限制、互踢策略以及信息同步,详见[多设备登录文档](multi_device.html)。
+
+
+## 更多
+
+### 登录被封禁账号的提示
+
+在环信即时通讯控制台或调用 REST API 封禁用户账号后,若仍使用该账号登录,SDK会返回 "service is disabled"(305 错误), 可以根据用户这个返回值来进行相应的提示或者处理。
diff --git a/docs/document/android/message_receipt.md b/docs/document/android/message_receipt.md
index 8804e117c..c93139af3 100644
--- a/docs/document/android/message_receipt.md
+++ b/docs/document/android/message_receipt.md
@@ -38,6 +38,7 @@
- 完成 SDK 初始化,并连接到服务器,详见 [快速开始](quickstart.html)。
- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。
+- 要使用群消息已读回执功能,需在[环信即时通讯云控制台](https://console.easemob.com/user/login)开通,具体费用详见[产品价格](/product/pricing.html#增值服务费用)。
## 实现方法
diff --git a/docs/document/android/multi_device.md b/docs/document/android/multi_device.md
index 42c3dcfc8..2dd0493de 100644
--- a/docs/document/android/multi_device.md
+++ b/docs/document/android/multi_device.md
@@ -96,7 +96,7 @@ EMClient.getInstance().chatManager().sendMessage(message);
初始化 SDK 时,你可以调用 `EMOptions#setCustomDeviceName` 方法设置登录设备的名称。设置后,若因达到了登录设备数量限制而导致在已登录的设备上强制退出时,被踢设备收到的 `EMConnectionListener#onLogout` 回调会包含导致该设备被踢下线的自定义设备名称。
-:::notice
+:::tip
登录成功后才会将该设置发送到服务器。
:::
@@ -138,7 +138,7 @@ EMClient.getInstance().chatManager().sendMessage(message);
2. 初始化 SDK 时,调用 `EMOptions#setCustomOSPlatform` 方法自定义设置登录设备的平台。确保该方法中的 `platform` 参数的值与环信控制台的**添加自定义平台**对话框中设置的**设备平台**的值相同。
-:::notice
+:::tip
登录成功后才会将该设置发送到服务器。
:::
@@ -154,7 +154,7 @@ EMClient.getInstance().chatManager().sendMessage(message);
初始化 SDK 时,你可以调用 `EMOptions#setLoginCustomExt` 方法设置登录设备的自定义扩展信息。设置后,若因达到了登录设备数量限制而导致在已登录的设备上强制退出时(`206` 错误,`USER_LOGIN_ANOTHER_DEVICE`),被踢设备收到的 `EMConnectionListener#onLogout` 回调会包含导致该设备被踢下线的新登录设备的自定义扩展信息。
-:::notice
+:::tip
登录成功后才会将该设置发送到服务器。
:::
diff --git a/docs/document/android/quickstart.md b/docs/document/android/quickstart.md
index e906ce17a..896def1e0 100644
--- a/docs/document/android/quickstart.md
+++ b/docs/document/android/quickstart.md
@@ -40,19 +40,11 @@
### 2. 集成 SDK
-选择如下任意一种方式将环信即时通讯 IM SDK 集成到你的项目中。
+你可以使用 mavenCentral 自动集成。该方法仅适用于 v3.8.2 或以上版本。获取最新 SDK 的版本号,详见 [SDK 更新日志](releasenote.html)。
-:::notice
-
-- 以下集成方式只需选择一种,同时使用多种集成方式可能会报错。
-- 请点击查看[发版说明](releasenote.html)获得最新版本号。
- :::
-
-#### 方法一:使用 mavenCentral 自动集成
-
-该方法仅适用于 v3.8.2 或以上版本。
+除此之外,你还可以通过手动复制 SDK 文件和动态加载 `.so` 库文件的方法集成 IM SDK,详见[集成文档](integration.html)。
-1. 在项目的 `build.gradle` 中添加 `mavenCentral()`仓库。
+1. 在项目的 `build.gradle` 中添加 `mavenCentral()` 仓库。
```gradle
buildscript {
@@ -83,8 +75,6 @@ dependencies {
}
```
-获取最新 SDK 的版本号:[SDK 更新日志](releasenote.html)
-
:::notice
如果使用 3.8.0 之前的版本,gradle 依赖需要按照下面格式添加:
:::
@@ -95,55 +85,6 @@ implementation 'io.hyphenate:hyphenate-sdk:3.7.5' // 完整版本,包含音视
implementation 'io.hyphenate:hyphenate-sdk-lite:3.7.5' // 精简版,只包含IM功能
```
-#### 方法二:手动复制 SDK 文件
-
-打开 [SDK 下载](https://www.easemob.com/download/im)页面,获取最新版的环信即时通讯 IM Android SDK,然后解压。
-
-
-
-将 SDK 包内 libs 路径下的如下文件,拷贝到你的项目路径下:
-
-| 文件或文件夹 | 项目路径 |
-| :------------------- | :--------------------- |
-| hyphenatechat_xxx.jar 文件 | /app/libs/ |
-| arm64-v8a 文件夹 | /app/src/main/jniLibs/ |
-| armeabi-v7a 文件夹 | /app/src/main/jniLibs/ |
-| x86 文件夹 | /app/src/main/jniLibs/ |
-| x86_64 文件夹 | /app/src/main/jniLibs/ |
-
-如果对生成的 `apk` 大小比较敏感,我们建议使用 `jar` 方式,并且手工拷贝 `so`,而不是使用 `Aar`,因为 `Aar` 方式会把各个平台的 `so` 文件都包含在其中。采用 `jar` 方式,可以仅保留一个 `ARCH` 目录,建议仅保留 `armeabi-v7a`,这样虽然在对应平台执行的速度会降低,但是能有效减小 `apk` 的大小。
-
-#### 方法三:动态加载 .so 库文件
-
-为了减少应用安装包的大小,SDK 从 4.5.0 开始提供了 `EMOptions#setNativeLibBasePath` 方法支持动态加载 SDK 所需的 `.so` 文件。以 SDK 4.5.0 为例,`.so` 文件包括 `libcipherdb.so` 和 `libhyphenate.so` 两个文件。**从 4.11.0 开始,`.so` 文件还包含 `libaosl.so` 文件。**
-
-该功能的实现步骤如下:
-
-1. 下载最新版本的 SDK 并解压缩。
-2. 集成 `hyphenatechat_4.5.0.jar` 到你的项目中。
-3. 将所有架构的 `.so` 文件上传到你的服务器,并确保应用程序可以通过网络下载目标架构的 `.so` 文件。
-4. 应用运行时,会检查 `.so` 文件是否存在。如果未找到,应用会下载该 `.so` 文件并将其保存到你自定义的应用程序的私有目录中。
-5. 调用 `EMClient#init` 初始化时,将 `.so` 文件所在的 app 私有目录作为参数设置进 `EMOptions#setNativeLibBasePath` 方法中。
-6. 调用 `EMClient#init` 初始化后,SDK 会自动从指定路径加载 `.so` 文件。
-
-:::tip
-1. 该方法仅适合手动集成 Android SDK,不适用于通过 Maven Central 集成。
-2. so 库的路径取决于 `EMOptions#setNativeLibBasePath` 方法的 `path` 参数:
-- `path` 参数为空或者不调用该方法时,SDK 内部会使用 `system.loadLibrary` 从系统默认路径中搜索并加载 so 库。
-- `path` 参数不为空时,SDK 内部会使用 `System.load` 从设置的路径下搜索和加载 so 库。该路径必须为有效的 app 的私有目录路径。
-:::
-
-```java
-//假设用户已经通过动态下发的方式,将环信 SDK 中的 libcipherdb.so 和 libhyphenate.so 两个 so 库,放到 app 的 /data/data/packagename/files 目录下。
-String filesPath = mContext.getFilesDir().getAbsolutePath();
-
-EMOptions options = new EMOptions();
-options.setNativeLibBasePath(filesPath);
-
-EMClient.getInstance().init(mContext, options);
-
-```
-
### 3. 添加项目权限
根据场景需要,在 `/app/src/main/AndroidManifest.xml` 文件中添加如下行,获取相应的设备权限:
@@ -184,7 +125,7 @@ EMClient.getInstance().init(mContext, options);
### 4. 防止代码混淆
-在 app/proguard-rules.pro 文件中添加如下行,防止混淆 SDK 的代码:
+在 `app/proguard-rules.pro` 文件中添加如下行,防止混淆 SDK 的代码:
```java
-keep class com.hyphenate.** {*;}
@@ -223,7 +164,7 @@ android {
### 1. SDK 初始化
-在主进程中进行初始化:
+在**主进程**中进行初始化:
```java
EMOptions options = new EMOptions();
@@ -249,7 +190,7 @@ try {
}
```
-:::notice
+:::tip
该注册模式为在客户端注册,主要用于测试,简单方便,但不推荐在正式环境中使用,需要在[环信控制台](https://console.easemob.com/user/login)中手动开通开放注册功能;正式环境中应使用服务器端调用 Restful API 注册,具体见[注册单个用户](/document/server-side/account_system.html#开放注册单个用户)。
:::
@@ -279,7 +220,7 @@ EMClient.getInstance().login(mAccount, mPassword, new EMCallBack() {
});
```
-:::notice
+:::tip
1. 除了注册监听器,其他的 SDK 操作均需在登录之后进行。
2. 登录成功后需要调用 `EMClient.getInstance().chatManager().loadAllConversations();` 和 `EMClient.getInstance().groupManager().loadAllGroups();`,确保进入主页面后本地会话和群组均加载完毕。
3. 如果之前登录过,App 长期在后台运行后切换到前台运行可能会导致加载到内存的群组和会话为空。为了避免这种情况,可在主页面的 `oncreate` 里也添加这两种方法,不过,最好将这两种方法放在程序的开屏页。
diff --git a/docs/document/android/releasenote.md b/docs/document/android/releasenote.md
index a3e357891..72a021075 100644
--- a/docs/document/android/releasenote.md
+++ b/docs/document/android/releasenote.md
@@ -74,7 +74,7 @@
### 新增特性
-- [IM SDK] 新增[从服务器拉取离线消息的开始和结束的事件回调](/document/android/overview.html#连接状态相关): `EMConnectionListener#onOfflineMessageSyncStart` 和 `EMConnectionListener#onOfflineMessageSyncFinish`。
+- [IM SDK] 新增[从服务器拉取离线消息的开始和结束的事件回调](/document/android/connection): `EMConnectionListener#onOfflineMessageSyncStart` 和 `EMConnectionListener#onOfflineMessageSyncFinish`。
- [IM SDK] 新增 `EMGroupManager#asyncCheckIfInMuteList` 接口,可以查看当前用户是否在群组禁言名单中。
- [IM SDK] 原消息置顶接口 `EMChatManager#asyncPinMessage` 和 `EMChatManager#asyncUnPinMessage` [增加对单聊会话中置顶消息的支持](message_pin.html)。接口无变化。
- [IM SDK] 新增 `EMRecallMessageInfo#getConversationId` 接口,在撤回消息的 `EMMessageListener#onMessageRecalledWithExt` 事件中[返回被撤回的消息所属的会话 ID](message_recall.html#设置消息撤回监听)。
diff --git a/docs/document/applet/connection.md b/docs/document/applet/connection.md
new file mode 100644
index 000000000..29fef1392
--- /dev/null
+++ b/docs/document/applet/connection.md
@@ -0,0 +1,43 @@
+# 连接
+
+应用客户端成功连接到环信服务器后,才能使用环信即时通讯 SDK 的收发消息等功能。
+
+你调用 `open` 方法登录后,客户端 SDK 会自动连接环信服务器。关于登录详情,请参见[登录文档](login.html)。
+
+## 监听连接状态
+
+```javascript
+conn.addEventHandler("connectionListener", {
+ onConnected: () => {
+ console.log("连接成功");
+ },
+ // 自 4.8.0 版本,`onDisconnected` 事件新增断开原因回调参数, 告知用户触发 `onDisconnected` 的原因。
+ onDisconnected: () => {
+ console.log("连接断开");
+ },
+ onReconnecting: () => {
+ console.log("重连中");
+ };
+});
+```
+
+## 自动重连
+
+登录后,SDK 在以下情况下会尝试自动重连:
+
+- 网络断开
+
+- 网络切换
+
+- 非主动调用登出
+
+不过,SDK 在以下情况下会停止自动重连。你需要调用 `open` 方法登录。
+
+- 用户调用了 SDK 的登出方法 `close` 主动退出登录。
+- 登录时鉴权错误,例如, token 无效(错误码 104)或已过期(错误码 108)。
+- 用户在其他的设备上更改了密码,导致此设备上自动登录失败,提示错误码 216。
+- 用户的账号被从服务器端删除,提示错误码 207。
+- 用户在另一设备登录,将当前设备上登录的用户踢出,提示错误码 206。
+- 用户登录设备数量超过限制,提示错误码 214。
+- 应用程序的日活跃用户数量(DAU)或月活跃用户数量(MAU)达到上限,提示错误码 8。
+
diff --git a/docs/document/applet/initialization.md b/docs/document/applet/initialization.md
index 1b0edeee4..3ecbc5511 100644
--- a/docs/document/applet/initialization.md
+++ b/docs/document/applet/initialization.md
@@ -1,26 +1,10 @@
-# 初始化及登录
+# SDK 初始化
-
-
-本页介绍小程序 SDK 集成过程中的初始化及登录。
+初始化是使用 SDK 的必要步骤,需在所有接口方法调用前完成。
## 前提条件
-开始前,请注册有效的环信即时通讯 IM 开发者账号且获得 App key,见 [环信即时通讯云管理后台](https://console.easemob.com/user/login)。
-
-## 引入 SDK
-
-对于 JavaScript SDK,导入代码如下:
-
-```javascript
-import EC from "easemob-websdk";
-```
-
-对于 TypeScript SDK,导入代码如下, EasemobChat 是 SDK 类型的命名空间。
-
-```javascript
-import EC, { EasemobChat } from "easemob-websdk";
-```
+有效的环信即时通讯 IM 开发者账号和 App key,详见[环信即时通讯云控制台的相关文档](/product/enable_and_configure_IM.html#创建应用)。
## SDK 初始化
@@ -50,185 +34,3 @@ const conn = new EC.connection({
| `apiUrl` | String | 是 | 指定的 REST 服务器。在未开启 DNS 的情况下使用,一般适用于开发者要实现数据隔离、特别注重数据安全的场景。要获取该服务器地址,需在环信控制台的**即时通讯 > 服务概览**页面,查看**域名配置**表格中的 **Rest Api** 设置。|
| `url` | String | 是 | 指定的消息服务器。在未开启 DNS 的情况下使用,一般适用于开发者要实现数据隔离、特别注重数据安全的场景。 要获取该服务器地址,需在环信控制台的**即时通讯 > 服务概览**页面,查看**域名配置**表格中的**微信小程序**或**支付宝小程序**设置。 |
-## 注册用户
-
-本节介绍三种用户注册方式。
-
-### 控制台注册
-
-通过控制台注册用户,详见[创建 IM 用户](/product/enable_and_configure_IM.html#创建-im-用户)。
-
-### REST API 注册
-
-请参考 [注册用户](/document/server-side/account_system.html#注册用户)。
-
-### SDK 注册
-
-若支持 SDK 注册,需登录[环信即时通讯云控制台](https://console.easemob.com/user/login),选择 **即时通讯** > **服务概览**,将 **设置**下的 **用户注册模式** 设置为 **开放注册**。
-
-```javascript
-conn
- .registerUser({
- /** 用户 ID。 */
- username: string,
- /** 密码。 */
- password: string
- })
- .then((res) => {
- console.log(res);
- });
-```
-
-## 用户登录
-
-SDK 不支持自动登录,只支持通过以下方式手动登录:
-
-- 用户 ID + 密码
-- 用户 ID + token
-
-登录时传入的用户 ID 必须为 String 类型,支持的字符集详见[用户注册的 RESTful 接口](/document/server-side/account_system.html#注册用户)。
-
-调用登录接口后,收到 `onConnected` 回调表明 SDK 与环信服务器连接成功。
-
-## 手动登录
-
-**用户 ID +密码** 登录是传统的登录方式。用户 ID 和密码都是你的终端用户自行决定,密码需要符合密码规则要求。
-
-```javascript
-conn
- .open({
- user: "username",
- pwd: "password",
- })
- .then(() => {
- console.log("login success");
- })
- .catch((reason) => {
- console.log("login fail", reason);
- });
-```
-
-**用户 ID + token** 是更加安全的登录方式。token 可以通过调用 REST API 获取,详见 [环信用户 token 的获取](/product/easemob_user_token.html)。
-
-:::notice
-使用 token 登录时需要处理 token 过期的问题,比如在每次登录时更新 token 等机制。
-:::
-
-```javascript
-conn
- .open({
- user: "username",
- accessToken: "token",
- })
- .then(() => {
- console.log("login success");
- })
- .catch((reason) => {
- console.log("login fail", reason);
- });
-```
-
-登录重试机制如下:
-
-- 登录时,若服务器返回明确的失败原因,例如,token 不正确,SDK 不会重试登录。
-- 若登录因超时失败,SDK 会重试登录。
-
-## 退出登录
-
-```typescript
-conn.close();
-```
-
-## 连接状态相关
-
-你可以通过注册连接监听器确认连接状态。
-
-```javascript
-conn.addEventHandler("handlerId", {
- onConnected: () => {
- console.log("onConnected");
- },
- // 自 4.8.0 版本,`onDisconnected` 事件新增断开原因回调参数, 告知用户触发 `onDisconnected` 的原因。
- onDisconnected: () => {
- console.log("onDisconnected");
- },
- onTokenWillExpire: () => {
- console.log("onTokenWillExpire");
- },
- onTokenExpired: () => {
- console.log("onTokenExpired");
- },
-});
-```
-
-### 断网自动重连
-
-如果由于网络信号弱、切换网络等引起的连接中断,系统会自动尝试重连。重连成功或者失败分别会收到 `onConnected` 和 `onDisconnected` 通知。
-
-你可以设置最大重连次数 `autoReconnectNumMax`,该参数默认为 5 次。
-
-### 被动退出登录
-
-对于 `onDisconnected` 通知,错误码(`errorCode`)可能为以下几种,建议 App 返回登录界面。
-
-| 错误码 | 描述 |
-| :------------------------------------------------- | :------------------------- |
-| WEBIM_CONNCTION_USER_LOGIN_ANOTHER_DEVICE=206 | 用户已经在其他设备登录。 |
-| WEBIM_CONNCTION_USER_REMOVED=207 | 用户账户已经被移除。 |
-| WEBIM_CONNCTION_USER_KICKED_BY_CHANGE_PASSWORD=216 | 由于密码变更被踢下线。 |
-| WEBIM_CONNCTION_USER_KICKED_BY_OTHER_DEVICE=217 | 由于其他设备登录被踢下线。 |
-
-## 输出信息到日志文件
-
-开启日志输出:
-
-```javascript
-logger.enableAll();
-```
-- 设置日志不输出到控制台:
-
-```javascript
-logger.setConsoleLogVisibility(false)
-```
-
-- 监听 SDK 日志事件:
-
-```javascript
-logger.onLog = (log)=>{
- console.log('im logger', log)
-}
-```
-
-关闭日志输出:
-
-```javascript
-logger.disableAll();
-```
-
-设置日志输出等级:
-
-```javascript
-// 0 - 5 或者 'TRACE','DEBUG','INFO','WARN','ERROR','SILENT';
-logger.setLevel(0);
-```
-
-设置缓存日志:
-
-```javascript
-logger.setConfig({
- useCache: false, // 是否缓存
- maxCache: 3 * 1024 * 1024, // 最大缓存字节
-});
-// 缓存全部等级日志
-logger.setLevel(0);
-```
-
-下载日志:
-
-```javascript
-logger.download();
-```
-
-## 日志上报
-
-自 4.8.1 版本,小程序 SDK 支持日志上报功能, 即将日志会上传到环信服务器。该功能默认关闭,如有需要, 在初始化时,可将 `enableReportLogs` 参数设置为 `true`,然后联系商务开通日志上报功能。
\ No newline at end of file
diff --git a/docs/document/applet/intergrated.md b/docs/document/applet/intergrated.md
new file mode 100644
index 000000000..5e27149c8
--- /dev/null
+++ b/docs/document/applet/intergrated.md
@@ -0,0 +1,122 @@
+# 集成 SDK
+
+本文介绍如何将环信即时通讯 IM SDK 集成到你的 Web 项目。
+
+## 开发环境要求
+
+- 支持的浏览器:
+ - Chrome 54+
+ - Firefox 10+
+ - Safari 6+
+
+## 安装
+
+### 使用 npm 安装
+
+```bash
+npm install easemob-websdk
+```
+
+## 引入 SDK
+
+### js 引入 SDK
+
+对于 JavaScript SDK,导入代码如下:
+
+```javascript
+import ChatSDK from "easemob-websdk";
+```
+
+### Ts 引入 SDK
+
+对于 TypeScript SDK,导入代码如下, EasemobChat 是 SDK 类型的命名空间。
+
+```typescript
+import ChatSDK, { EasemobChat } from "easemob-websdk";
+```
+
+### 按需导入 SDK 模块
+
+SDK 提供了灵活的模块化设计,允许开发者根据需求引入功能模块,并将其注册到 miniCore 中使用。
+
+miniCore 是一个基座,支持登录登出和发送消息等基础功能,而且包含消息对象。因此,若只使用收发消息功能,则只需引入 miniCore。若使用其他功能,miniCore 支持使用插件的方式引入其他功能模块。按需引入模块的方式实现了不同模块的灵活组合,从而避免不必要的代码加载,减小了应用程序的体积。
+
+tip:
+只有按需导入 SDK 的方式才支持本地会话管理功能。
+小程序 uniapp 不支持使用 miniCore 的集成方式。
+
+```javascript
+import MiniCore from "easemob-websdk/miniCore/miniCore";
+import * as contactPlugin from "easemob-websdk/contact/contact";
+```
+
+支持按需导入的 SDK 模块
+
+| 模块名称 | 导入文件 | 使用方式 |
+| -------- | -------- | -------- |
+| 联系人和消息管理 | import * as contactPlugin from "easemob-websdk/contact/contact"; | miniCore.usePlugin(contactPlugin, "contact") |
+| 群组 | import * as groupPlugin from "easemob-websdk/group/group"; | miniCore.usePlugin(groupPlugin, "group") |
+| 聊天室 | import * as chatroomPlugin from "easemob-websdk/chatroom/chatroom"; | miniCore.usePlugin(chatroomPlugin, "chatroom") |
+| 子区 | import * as threadPlugin from "easemob-websdk/thread/thread"; | miniCore.usePlugin(threadPlugin, "thread"); |
+| 翻译 | import * as translationPlugin from "easemob-websdk/translation/translation";| miniCore.usePlugin(translationPlugin, "translation"); |
+| 在线状态订阅 | import * as presencePlugin from "easemob-websdk/presence/presence"; | miniCore.usePlugin(presencePlugin, "presence"); |
+| 会话免打扰 | import * as silentPlugin from "easemob-websdk/silent/silent";| miniCore.usePlugin(silentPlugin, "silent");
+ |
+
+
+### 注册模块到 miniCore
+
+```javascript
+const miniCore = new MiniCore({
+ appKey: "your appKey",
+});
+
+// "contact" 为固定值
+miniCore.usePlugin(contactPlugin, "contact");
+```
+
+### 使用注册的模块
+
+```javascript
+// 获取联系人列表
+miniCore.contact.getContacts();
+
+// 登录
+miniCore.open({
+ username: "username",
+ password: "password",
+ // accessToken: 'token'
+});
+
+// 登出
+miniCore.close();
+
+// 监听事件
+miniCore.addEventHandler("handlerId", {
+ onTextMessage: (message) => {
+ console.log(message);
+ },
+});
+
+//发送文本消息
+const sendTextMsg = () => {
+ const option: EasemobChat.CreateTextMsgParameters = {
+ chatType: "singleChat",
+ type: "txt",
+ to: "to",
+ msg: "hello",
+ };
+ const msg = miniCore.Message.create(option);
+ miniCore
+ .send(msg)
+ .then((res: any) => {
+ console.log("发送成功", res, msg);
+ })
+ .catch((err: any) => {
+ console.log("发送失败", err);
+ });
+};
+
+```
+
+
diff --git a/docs/document/applet/log.md b/docs/document/applet/log.md
new file mode 100644
index 000000000..7de982af0
--- /dev/null
+++ b/docs/document/applet/log.md
@@ -0,0 +1,58 @@
+# SDK 日志
+
+环信即时通讯 IM 日志记录 SDK 相关的信息和事件。环信技术支持团队帮你排查问题时可能会请你发送 SDK 日志。
+
+## 输出信息到日志文件
+
+开启日志输出:
+
+```javascript
+logger.enableAll();
+```
+- 设置日志不输出到控制台:
+
+```javascript
+logger.setConsoleLogVisibility(false)
+```
+
+- 监听 SDK 日志事件:
+
+```javascript
+logger.onLog = (log)=>{
+ console.log('im logger', log)
+}
+```
+
+关闭日志输出:
+
+```javascript
+logger.disableAll();
+```
+
+设置日志输出等级:
+
+```javascript
+// 0 - 5 或者 'TRACE','DEBUG','INFO','WARN','ERROR','SILENT';
+logger.setLevel(0);
+```
+
+设置缓存日志:
+
+```javascript
+logger.setConfig({
+ useCache: false, // 是否缓存
+ maxCache: 3 * 1024 * 1024, // 最大缓存字节
+});
+// 缓存全部等级日志
+logger.setLevel(0);
+```
+
+下载日志:
+
+```javascript
+logger.download();
+```
+
+## 日志上报
+
+自 4.8.1 版本,小程序 SDK 支持日志上报功能, 即将日志会上传到环信服务器。该功能默认关闭,如有需要, 在初始化时,可将 `enableReportLogs` 参数设置为 `true`,然后联系商务开通日志上报功能。
\ No newline at end of file
diff --git a/docs/document/applet/login.md b/docs/document/applet/login.md
new file mode 100644
index 000000000..9aab07e26
--- /dev/null
+++ b/docs/document/applet/login.md
@@ -0,0 +1,72 @@
+# 登录
+
+初始化 IM SDK 后,你需要首先调用接口登录。登录成功后,才能使用 IM 的功能。
+
+## 用户注册
+
+用户注册支持以下方式:
+
+- 开放注册:一般在体验 Demo 和测试环境时使用,正式环境中不推荐使用该方式注册环信账号。要使用开放注册,需要在[环信即时通讯云控制台](https://console.easemob.com/user/login)的**即时通讯** > **服务概览**的**设置**区域,将**用户注册模式**设置为**开放注册**。只有打开该开关,才能使用客户端或 [REST API](/document/server-side/account_system.html#开放注册单个用户)开放注册用户。
+
+示例代码如下:
+
+```javascript
+conn.registerUser({
+ username: "user1",
+ password: "xxx",
+});
+```
+
+- 授权注册:通过环信提供的 REST API 注册环信用户账号,注册后保存到你的服务器或返给客户端。要使用授权注册,你需要在[环信即时通讯云控制台](https://console.easemob.com/user/login)的**即时通讯** > **服务概览**的**设置**区域,将**用户注册模式**设置为**授权注册**。相关的 REST API 介绍,详见[授权注册单个用户](/document/server-side/account_system.html#授权注册单个用户)和[批量授权注册用户](/document/server-side/account_system.html#批量授权注册用户)的接口介绍。
+
+除此以外,可以在[环信即时通讯云控制台](https://console.easemob.com/user/login)创建正式环境下和测试环境下的用户,详见[创建用户相关介绍](/product/enable_and_configure_IM.html#创建-im-用户)。
+
+## 登录方式
+
+1. **用户 ID + token** 是更加安全的登录方式。
+
+测试环境下,你在[环信即时通讯云控制台](https://console.easemob.com/user/login)创建用户后,环信服务器会自动为这些用户分配用户 Token,详见[测试环境下创建用户的介绍](/product/enable_and_configure_IM.html#测试环境)。
+
+使用 token 登录时需要处理 token 过期的问题,比如在每次登录时更新 token 等机制。
+
+```javascript
+conn
+ .open({
+ user: "username",
+ accessToken: "token",
+ })
+ .then(() => {
+ console.log("login success");
+ })
+ .catch((reason) => {
+ console.log("login fail", reason);
+ });
+```
+2. **用户 ID + 密码** 登录是传统的登录方式。用户名和密码均由你的终端用户自行决定,密码需要符合[密码规则要求](/document/server-side/account_system.html#开放注册单个用户)。
+
+```javascript
+conn
+ .open({
+ user: "username",
+ pwd: "password",
+ })
+ .then(() => {
+ console.log("login success");
+ })
+ .catch((reason) => {
+ console.log("login fail", reason);
+ });
+```
+
+## 退出登录
+
+```javascript
+conn.close();
+```
+
+## 多设备登录
+
+除了单端单设备登录,环信即时通讯 IM 支持同一账号在多端的多个设备上登录。多设备登录时,若同端设备数量超过限制,新登录的设备会将之前登录的设备踢下线。
+
+关于多设备登录场景中的设备数量限制、互踢策略以及信息同步,详见[多设备登录文档](multi_device.html)。
+
diff --git a/docs/document/applet/wechat.md b/docs/document/applet/wechat.md
index 2c70fda37..262d13d8e 100644
--- a/docs/document/applet/wechat.md
+++ b/docs/document/applet/wechat.md
@@ -31,6 +31,8 @@ request 合法域名:
4. https://a4.easemob.com
5. https://a5.easemob.com
6. https://a1-chatfile.easemob.com
+7. https://rs.chat.agora.io
+8. https://rs.easemob.com
:::
:::tip
diff --git a/docs/document/flutter/connection.md b/docs/document/flutter/connection.md
new file mode 100644
index 000000000..fc72cc64b
--- /dev/null
+++ b/docs/document/flutter/connection.md
@@ -0,0 +1,49 @@
+# 连接
+
+应用客户端成功连接到环信服务器后,才能使用环信即时通讯 SDK 的收发消息等功能。
+
+你调用 `loginWithToken` 方法登录后,客户端 SDK 会自动连接环信服务器。关于登录详情,请参见[登录文档](login.html)。
+
+## 监听连接状态
+
+你可以通过注册连接监听确认连接状态。
+
+```dart
+// 添加监听
+EMClient.getInstance.addConnectionEventHandler(
+ 'Identifier',
+ EMConnectionEventHandler(
+ onConnected: () {},
+ onDisconnected: () {},
+ onTokenDidExpire: () {},
+ onTokenWillExpire: () {},
+ onUserAuthenticationFailed: () {},
+ onUserDidForbidByServer: () {},
+ onUserDidChangePassword: () {},
+ onUserDidLoginFromOtherDevice: (info) {},
+ onUserDidLoginTooManyDevice: () {},
+ onUserDidRemoveFromServer: () {},
+ onUserKickedByOtherDevice: () {},
+ onAppActiveNumberReachLimit: () {},
+ onOfflineMessageSyncStart: () {},
+ onOfflineMessageSyncFinish: () {},
+ ),
+);
+
+// 移除监听
+EMClient.getInstance.removeConnectionEventHandler('Identifier');
+```
+
+## 自动重连
+
+登录后,如果由于网络信号弱、切换网络等引起的连接中断,SDK 会自动尝试重连。重连成功或者失败时分别会收到 `onConnected` 和 `onDisconnected` 通知。
+
+不过,SDK 在以下情况下会停止自动重连。你需要调用 `login` 方法登录。
+
+- 用户调用了 SDK 的登出方法 `logout` 主动退出登录。
+- 登录时鉴权错误,例如, token 无效(错误码 104)或已过期(错误码 108)。
+- 用户在其他的设备上更改了密码,导致此设备上自动登录失败,提示错误码 216。
+- 用户的账号被从服务器端删除,提示错误码 207。
+- 用户在另一设备登录,将当前设备上登录的用户踢出,提示错误码 206。
+- 用户登录设备数量超过限制,提示错误码 214。
+- 应用程序的日活跃用户数量(DAU)或月活跃用户数量(MAU)达到上限,提示错误码 8。
\ No newline at end of file
diff --git a/docs/document/flutter/conversation_receipt.md b/docs/document/flutter/conversation_receipt.md
new file mode 100644
index 000000000..7ea392f32
--- /dev/null
+++ b/docs/document/flutter/conversation_receipt.md
@@ -0,0 +1,74 @@
+# 会话已读回执
+
+会话已读回执指接收方进入会话页面,阅读会话中的所有消息后,调用接口向服务器发送会话已读回执,服务器将该回执回调给消息发送方,消息发送方将会收到会话已读回调。在多端多设备登录下,接收方的其他设备也会收到该回调。
+
+目前,单聊和群组聊天支持会话已读回执。本文介绍如何使用环信即时通讯 IM Flutter SDK 实现会话已读回执功能。
+
+会话已读回执的效果示例,如下图所示:
+
+
+
+## 技术原理
+
+ 单聊会话已读回执实现的流程如下:
+
+ 1. 设置 `EMOptions#requireAck` 为 `true` 开启已读回执功能。
+ 2. 消息接收方进入会话页面,阅读消息后,调用 `EMChatManager#sendConversationReadAck` 方法发送会话已读回执。
+ 3. 消息发送方通过监听 `EMChatEventHandler#onConversationRead` 回调接收会话已读回执, 同时会话中的消息会变为“对方已读”状态,即 `EMMessage#hasReadAck` 会变为 `true`。
+
+## 前提条件
+
+开始前,请确保满足以下条件:
+
+- 完成 SDK 初始化,并连接到服务器,详见 [快速开始](quickstart.html)。
+- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。
+
+ ## 实现方法
+
+ 参考以下步骤在单聊中实现会话已读回执:
+
+ 1. 开启已读回执功能,即 SDK 初始化时设置 `EMOptions#requireAck` 为 `true`。
+
+ ```dart
+// 设置是否需要接受方已读确认,默认为 true
+ final options = EMOptions(
+ appKey: appKey,
+ requireAck: true,
+ );
+ ```
+
+ 2. 接收方发送会话已读回执。
+
+消息接收方进入会话页面,查看会话中是否有未读消息。若有,调用 `EMChatManager#sendConversationReadAck` 方法发送会话已读回执,没有则不发送。该方法为异步方法,需要捕捉异常。
+
+若会话中存在多条未读消息,建议调用该方法,因为若调用发送消息已读回执方法 `ackMessageRead`,则需要调用多次。
+
+```dart
+try {
+ await EMClient.getInstance.chatManager
+ .sendConversationReadAck(conversationId);
+} on EMError catch (e) {
+ debugPrint(e.toString());
+}
+```
+
+3. 消息发送方监听会话已读回执的回调。
+
+同一用户 ID 登录多设备的情况下,用户在一台设备上发送会话已读回执,其他设备会收到 `EMChatEventHandler#onConversationRead` 回调。
+
+:::tip
+对于群组聊天,会话已读回执只用于清空服务端的群组会话的未读数,消息发送方不会通过 `EMChatEventHandler#onConversationRead` 回调收到会话已读回执。
+:::
+
+```dart
+EMClient.getInstance.chatManager.addEventHandler(
+ 'identifier',
+ EMChatEventHandler(
+ onConversationRead: (from, to) {},
+ ),
+);
+```
+
+## 会话已读回执和消息未读数
+
+消息接收方调用 `EMChatManager#sendConversationReadAck` 方法发送会话已读回执,开发者可调用 `EMConversation#markAllMessagesAsRead` 方法将所有未读消息设置为已读,即将该会话的未读消息数清零。
diff --git a/docs/document/flutter/initialization.md b/docs/document/flutter/initialization.md
new file mode 100644
index 000000000..c8fb342a8
--- /dev/null
+++ b/docs/document/flutter/initialization.md
@@ -0,0 +1,22 @@
+# SDK 初始化
+
+初始化是使用 SDK 的必要步骤,需在所有接口方法调用前完成。
+
+如果进行多次初始化操作,只有第一次初始化以及相关的参数生效。
+
+:::tip
+需要在主进程中进行初始化。
+:::
+
+## 前提条件
+
+有效的环信即时通讯 IM 开发者账号和 App key,详见[环信即时通讯云控制台的相关文档](enable_and_configure_IM.html#创建应用)。
+
+## 初始化
+
+初始化示例代码:
+
+```dart
+final options = EMOptions(appKey: appKey);
+await EMClient.getInstance.init(options);
+```
diff --git a/docs/document/flutter/integration.md b/docs/document/flutter/integration.md
new file mode 100644
index 000000000..ebafad146
--- /dev/null
+++ b/docs/document/flutter/integration.md
@@ -0,0 +1,56 @@
+# 集成 SDK
+
+本文介绍如何将环信即时通讯 IM SDK 集成到你的 Android 项目。
+
+## 开发环境要求
+
+- Flutter 2.0.0 或以上版本;
+- Dart 2.12 或以上版本;
+
+### 使用命令创建项目
+
+```dart
+flutter create quick_start
+```
+
+### 设置 Android
+
+1. 打开文件 quick_start/android/app/build.gradle 在文件最后添加:
+
+```dart
+android {
+ defaultConfig {
+ minSdkVersion 21
+ }
+}
+```
+
+2. 打开文件 quick_start/android/app/src/main/AndroidManifest.xml,在 下添加:
+
+```xml
+
+
+
+```
+
+3. 在 quick_start/android/app/proguard-rules.pro 中设置免混淆规则:
+
+```java
+-keep class com.hyphenate.** {*;}
+-dontwarn com.hyphenate.**
+```
+
+### 设置 iOS
+
+iOS 需要 iOS 11.0 以上版本,
+
+打开文件 quick_start/ios/Runner.xcodeproj,修改:TARGETS -> General -> Deployment info, 设置 iOS 版本为 11.0。
+
+
+### 集成 SDK
+
+```shell
+cd quick_start
+flutter pub add im_flutter_sdk
+flutter pub get
+```
diff --git a/docs/document/flutter/login.md b/docs/document/flutter/login.md
new file mode 100644
index 000000000..da0af7f80
--- /dev/null
+++ b/docs/document/flutter/login.md
@@ -0,0 +1,86 @@
+# 登录
+
+初始化 IM SDK 后,你需要首先调用接口登录。登录成功后,才能使用 IM 的功能。
+
+## 用户注册
+
+用户注册模式分为以下两种:
+
+- 开放注册:一般在体验 Demo 和测试环境时使用,正式环境中不推荐使用该方式注册环信账号。要使用开放注册,需要在[环信即时通讯云控制台](https://console.easemob.com/user/login)的**即时通讯** > **服务概览**的**设置**区域,将**用户注册模式**设置为**开放注册**。只有打开该开关,才能使用客户端或 [REST API](/document/server-side/account_system.html#开放注册单个用户)开放注册用户。
+
+示例代码如下所示:
+
+```dart
+try {
+ await EMClient.getInstance.createAccount(userId, password);
+} on EMError catch (e) {}
+```
+
+- 授权注册:通过环信提供的 REST API 注册环信用户账号,注册后保存到你的服务器或返给客户端。要使用授权注册,你需要在[环信即时通讯云控制台](https://console.easemob.com/user/login)的**即时通讯** > **服务概览**的**设置**区域,将**用户注册模式**设置为**授权注册**。相关的 REST API 介绍,详见[授权注册单个用户](/document/server-side/account_system.html#授权注册单个用户)和[批量授权注册用户](/document/server-side/account_system.html#批量授权注册用户)的接口介绍。
+
+除此以外,可以在[环信即时通讯云控制台](https://console.easemob.com/user/login)创建正式环境下和测试环境下的用户,详见[创建用户相关介绍](/product/enable_and_configure_IM.html#创建-im-用户)。
+
+## 主动登录
+
+1. **用户 ID + token** 是更加安全的登录方式。token 可以通过调用 REST API 获取。 详见 [环信用户 token 的获取](/document/server-side/easemob_user_token.html)。
+
+测试环境下,你在[环信即时通讯云控制台](https://console.easemob.com/user/login)创建用户后,环信服务器会自动为这些用户分配用户 Token,详见[测试环境下创建用户的介绍](/product/enable_and_configure_IM.html#测试环境)。
+
+使用 token 登录时需要处理 token 过期的问题,比如在每次登录时更新 token 等机制。
+
+```dart
+try {
+ await EMClient.getInstance.loginWithToken(userId, token);
+} on EMError catch (e) {
+ debugPrint("loginWithToken error: ${e.code} ${e.description}");
+}
+```
+
+2. **用户 ID + 密码** 登录是传统的登录方式。用户名和密码都是你的终端用户自行决定,密码需要符合密码规则要求。
+
+```dart
+try {
+ await EMClient.getInstance.login(userId, password);
+} on EMError catch (e) {}
+```
+
+## 自动登录
+
+初始化时,你可以设置 `EMOptions#autoLogin` 选项确定是否自动登录。如果设置为自动登录,则登录成功之后,后续初始化 SDK 时会自动登录。
+
+## 获取当前登录的用户
+
+你可以调用 `EMClient#currentUserId` 方法获取当前登录用户的用户 ID。
+
+## 获取登录状态
+
+你可以调用 `EMClient#isLoginBefore` 方法获取当前用户的登录状态。
+
+## 退出登录
+
+你可以调用 `EMClient#logout` 方法退出登录。退出登录后,你不会再收到其他用户发送的消息。
+
+```dart
+try {
+ await EMClient.getInstance.logout();
+} on EMError catch (e) {
+ debugPrint("logout error: ${e.code} ${e.description}");
+}
+```
+
+## 账号切换
+
+若在 app 中从当前账号切换到其他账号,你需要首先调用 `logout` 方法登出,然后再调用 `loginWithToken` 方法登录。
+
+## 多设备登录
+
+除了单端单设备登录,环信即时通讯 IM 支持同一账号在多端的多个设备上登录。多设备登录时,若同端设备数量超过限制,新登录的设备会将之前登录的设备踢下线。
+
+关于多设备登录场景中的设备数量限制、互踢策略以及信息同步,详见[多设备登录文档](multi_device.html)。
+
+
+## 更多
+
+### 登录被封禁账号的提示
+
+在环信即时通讯控制台或调用 REST API 封禁用户账号后,若仍使用该账号登录,SDK会返回 "service is disabled"(305 错误), 可以根据用户这个返回值来进行相应的提示或者处理。
diff --git a/docs/document/flutter/message_receipt.md b/docs/document/flutter/message_receipt.md
index 3e6a23297..2063434e8 100644
--- a/docs/document/flutter/message_receipt.md
+++ b/docs/document/flutter/message_receipt.md
@@ -1,40 +1,36 @@
-# 消息回执
+# 实现消息回执
-单聊会话支持消息送达回执、会话已读回执和消息已读回执,发送方发送消息后可及时了解接收方是否及时收到并阅读了信息,也可以了解整个会话是否已读。
+**单聊会话支持消息送达回执和消息已读回执**,发送方发送消息后可及时了解接收方是否及时收到并阅读了消息。
-群聊会话只支持消息已读回执。群成员在发送消息时,可以设置该消息是否需要已读回执。仅专业版及以上版本支持群消息已读回执功能。若要使用该功能,需在[环信即时通讯云控制台](https://console.easemob.com/user/login)开通,具体费用详见[产品价格](/product/pricing.html#增值服务费用)。
+**群聊会话只支持消息已读回执,不支持送达回执**。群成员在发送消息时,可以设置该消息是否需要已读回执。要使用该功能,你需要[在环信即时通讯云控制台上开通该功能](/product/enable_and_configure_IM.html#设置群消息已读回执),具体费用详见[产品价格](/product/pricing.html#增值服务费用)。
-:::tip
-仅单聊消息支持送达回执,群聊消息不支持。
-:::
+消息送达回执和已读回执的效果示例,如下图所示:
-本文介绍如何使用环信即时通讯 IM Flutter SDK 实现单聊和群聊的消息回执功能。
+
## 技术原理
-环信即时通讯 IM Flutter SDK 通过 `EMChatManager` 类提供消息的送达回执和已读回执功能。核心方法如下:
+使用环信即时通讯 IM Flutter SDK 可以实现消息的送达回执与已读回执。
-- `EMOptions.requireDeliveryAck` 送达回执的全局开关;
-- `EMOptions.requireAck` 已读回执的全局开关;
-- `EMChatManager.sendConversationReadAck` 发送会话的已读回执;
-- `EMChatManager.sendMessageReadAck` 发送单聊消息的已读回执;
-- `EMChatManager.sendGroupMessageReadAck` 发送群组消息的已读回执;
+- 单聊消息送达回执的逻辑如下:
-实现送达和已读回执的逻辑分别如下:
+ 1. 你可以通过设置 `EMOptions#requireDeliveryAck` 为 `true` 开启送达回执功能。
+ 2. 消息接收方收到消息后,SDK 自动向发送方触发送达回执。
+ 3. 消息发送方通过监听 `EMChatEventHandler#onMessagesDelivered` 回调接收消息送达回执。
-- 消息送达回执
+- 单聊消息已读回执的逻辑如下:
- 1. 消息发送方在发送消息前通过 `EMOptions.requireDeliveryAck` 开启送达回执功能。
- 2. 消息接收方收到消息后,SDK 自动向发送方触发送达回执。
- 3. 消息发送方通过监听 `onMessageDelivered` 回调接收消息送达回执。
+ 1. 你可以通过设置 `EMOptions#requireAck` 为 `true` 开启已读回执功能。
+ 2. 消息接收方收到消息后,调用 `EMChatManager#sendMessageReadAck` 方法发送消息已读回执。
+ 3. 消息发送方通过监听 `EMMessageListener#onMessagesRead` 回调接收消息已读回执。
-- 会话及消息已读回执
+- 群聊消息已读回执的逻辑如下:
- 1. 消息发送方在发送消息前通话 `EMOptions.requireAck` 开启已读回执功能。
- 2. 消息接收方收到或阅读消息后,调用 API `SendConversationReadAck` 或 `SendMessageReadAck` 发送会话或消息已读回执。
- 3. 消息发送方通过监听 `onConversationRead` 或 `onMessagesRead` 回调接收会话或消息已读回执。
+ 1. 你可以通过设置 `EMOptions#requireAck` 为 `true` 开启消息已读回执功能。
+ 2. 发送方在群组中发送消息时设置 `EMMessage#needGroupAck` 为 `true` 要求接收方返回消息已读回执。
+ 3. 接收方收到或阅读消息后通过 `EMChatManager#sendGroupMessageReadAck` 方法发送群组消息的已读回执。
## 前提条件
@@ -42,171 +38,193 @@
- 完成 SDK 初始化,并连接到服务器,详见 [快速开始](quickstart.html)。
- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。
-- 群消息已读回执功能仅在环信 IM 专业版及以上版本支持该功能。若要使用该功能,需在[环信即时通讯云控制台](https://console.easemob.com/user/login)开通,具体费用详见[产品价格](/product/pricing.html#增值服务费用)。
+- 要使用群消息已读回执功能,需在[环信即时通讯云控制台](https://console.easemob.com/user/login)开通,具体费用详见[产品价格](/product/pricing.html#增值服务费用)。
## 实现方法
-### 消息送达回执
+### 单聊消息送达回执
-1. 发送方开启全局送达回执。当接收方收到消息后,SDK 底层会自动进行消息送达回执。
+1. 开启消息送达功能,即 SDK 初始化时将 `EMOptions#requireDeliveryAck` 设置为 `true`。
```dart
-// sdk app key
-String appKey = "appKey";
-// 开启消息送达回执
-bool requireDeliveryAck = true;
-EMOptions options = EMOptions(
- appKey: appKey,
- requireDeliveryAck: requireDeliveryAck,
-);
-await EMClient.getInstance.init(options);
+// 设置是否需要接收方送达确认,默认 `false` 即不需要。
+ final options = EMOptions(
+ appKey: appKey,
+ requireDeliveryAck: true,
+ );
```
-2. 发送方监听事件 `onMessagesDelivered` 回调,收到接收方的送达回执。
+2. 接收方收到消息后,SDK 自动向发送方触发送达回执。
+
+3. 发送方监听 `EMChatEventHandler#onMessagesDelivered` 事件,收到接收方的送达回执。你可以在收到该通知时,显示消息的送达状态。
```dart
-// 添加监听器
-EMClient.getInstance.chatManager.addEventHandler(
- "UNIQUE_HANDLER_ID",
- EMChatEventHandler(
- onMessagesDelivered: (list) => {},
- ),
-);
+ EMClient.getInstance.chatManager.addEventHandler(
+ 'identifier',
+ EMChatEventHandler(
+ onMessagesDelivered: (messages) {},
+ ),
+ );
```
-### 消息和会话的已读回执
+### 单聊消息已读回执
-消息已读回执用于告知单聊或群聊中的用户接收方已阅读其发送的消息。为降低消息已读回执方法的调用次数,SDK 还支持在单聊中使用会话已读回执功能,用于获知接收方是否阅读了会话中的未读消息。
+单聊既支持单条消息已读回执,也支持[会话已读回执](conversation_receipt.html)。我们建议你结合使用这两种回执,见实现步骤的描述。
-#### 单聊
+单聊消息的已读回执有效期与消息在服务端的存储时间一致,即在服务器存储消息期间均可发送已读回执。消息在服务端的存储时间与你订阅的套餐包有关,详见[产品价格](/product/pricing.html#套餐包功能详情)。
-单聊既支持消息已读回执,也支持会话已读回执。我们建议你按照如下逻辑结合使用两种回执结合使用,减少发送消息已读回执数量。
+参考如下步骤在单聊中实现消息已读回执。
-- 聊天页面未打开时,若有未读消息,进入聊天页面,发送会话已读回执;
-- 聊天页面打开时,若收到消息,发送消息已读回执。
+1. App 开启已读回执功能,即 SDK 初始化时将 `EMOptions#requireAck` 设置为 `true`。
-##### 会话已读回执
+```dart
+ final options = EMOptions(
+ appKey: appKey,
+ requireAck: true,
+ );
+```
-参考如下步骤在单聊中实现会话已读回执。
+2. 接收方发送消息已读回执。
-1. 开启全局的消息已读回执开关。如果全局设置不开启,消息和会话的相应设置也无法生效。
+- 聊天页面未打开时,若有未读消息,进入聊天页面,发送会话已读回执。这种方式可避免发送多个消息已读回执。
```dart
-EMOptions options = EMOptions(
- appKey: appKey,
- requireAck: true,
-);
-EMClient.getInstance.init(options);
+try {
+ await EMClient.getInstance.chatManager
+ .sendConversationReadAck(conversationId);
+} on EMError catch (e) {
+ debugPrint(e.toString());
+}
```
-2. 接收方执行会话已读回执操作。进入会话页面,查看会话中是否有未读消息。若有,发送会话已读回执,没有则不再发送。
+- 聊天页面打开时,若收到消息,发送单条消息已读回执。
```dart
-String convId = "convId";
try {
- await EMClient.getInstance.chatManager.sendConversationReadAck(convId);
+ EMClient.getInstance.chatManager.sendMessageReadAck(message);
} on EMError catch (e) {
-
+ debugPrint('Failed to send message read ack: ${e.description}');
}
```
-3. 发送方监听 `onConversationRead` 回调,接收会话已读回执。
+3. 消息发送方监听消息已读回调。
+
+消息发送方可以通过 `EMChatEventHandler#onMessagesRead` 事件监听指定消息是否已读,示例代码如下:
```dart
EMClient.getInstance.chatManager.addEventHandler(
- "UNIQUE_HANDLER_ID",
+ 'identifier',
EMChatEventHandler(
- onConversationRead: (from, to) => {},
+ onMessagesRead: (messages) {},
),
);
```
-> 同一用户 ID 登录多设备的情况下,用户在一台设备上发送会话已读回执,服务器会将会话的未读消息数置为 `0`,同时其他设备会收到 `onConversationRead` 回调。
+### 群聊消息已读回执
-##### 消息已读回执
+对于群聊,群成员发送消息时,可以设置该消息是否需要已读回执。若需要,每个群成员阅读消息后,应该调用`EMChatManager#sendGroupMessageReadAck` 方法发送已读回执,阅读该消息的群成员数量即为已读回执的数量。
-单聊消息的已读回执有效期与消息在服务端的存储时间一致,即在服务器存储消息期间均可发送已读回执。消息在服务端的存储时间与你订阅的套餐包有关,详见[产品价格](/product/pricing.html#套餐包功能详情)。
+群消息已读回执特性的使用限制如下表所示:
-参考如下步骤在单聊中实现消息已读回执。
+| 使用限制| 默认 | 描述 |
+| :--------- | :----- | :------- |
+| 功能开通 | 关闭 | 若要使用该功能,你需要在[环信即时通讯云控制台](https://console.easemob.com/user/login)的**即时通讯** > **功能配置** > **功能配置总览**> **基础功能**页签下,搜索找到 **消息已读回执(群聊)** 开通功能。具体费用详见[产品价格](/product/pricing.html#增值服务费用)。 |
+| 使用权限 | 所有群成员 | 默认情况下,所有群成员发送消息时可要求已读回执。如果仅需群主和群管理员发消息时要求已读回执,可联系商务修改。 |
+| 已读回执有效期 | 3 天 | 群聊已读回执的有效期为 3 天,即群组中的消息发送时间超过 3 天,服务器不记录阅读该条消息的群组成员,也不会发送已读回执。 |
+| 群规模 | 200 人 | 该特性最大支持 200 人的群组。如果超过 200 人/群,群成员发送的消息不会返回已读回执。你可以联系商务提升群成员人数上限。 |
+| 查看返回已读回执数量 | 消息发送方 | 对消息返回的已读回执数量(或返回已读回执的人数),默认仅消息发送方可查看。如需所有群成员均可查看,可联系商务开通。 |
+
+你可以按以下步骤实现群消息已读回执特性:
+
+1. 开启已读回执功能,即 SDK 初始化时将 `EMOptions#requireAck` 设置为 `true`。
-1. 开启全局的消息已读回执开关。如果全局设置不开启,消息和会话的相应设置也无法生效。
+该功能开启后,接收方阅读消息后,SDK 底层会自动进行消息已读回执。
```dart
-EMOptions options = EMOptions(
- appKey: "appKey",
- requireAck: true,
-);
-EMClient.getInstance.init(options);
+ final options = EMOptions(
+ appKey: appKey,
+ requireAck: true,
+ );
```
-2. 消息发送方监听 `onMessagesRead` 事件。
+2. 发送方发送消息时设置 `EMMessage#needGroupAck` 属性为 `true`。
+
+与单聊消息的 app 层级设置已读回执功能不同,群聊消息是在发送消息时设置指定消息是否需要已读回执。
```dart
-EMClient.getInstance.chatManager.addEventHandler(
- "UNIQUE_HANDLER_ID",
- EMChatEventHandler(
- onMessagesRead: (list) => {},
- ),
+EMMessage message = EMMessage.createTxtSendMessage(
+ targetId: targetId,
+ content: 'content',
);
+message.needGroupAck = true;
```
-3. 消息接收方发送已读回执
+3. 发送群组消息的已读回执。
```dart
-try {
- EMClient.getInstance.chatManager.sendMessageReadAck(msg);
-} on EMError catch (e) {
-
+void sendGroupReadAck(EMMessage message) async {
+ if (message.needGroupAck != true) return;
+ try {
+ await EMClient.getInstance.chatManager.sendGroupMessageReadAck(message.msgId, message.conversationId!);
+ } on EMError catch (e) {
+ debugPrint('Failed to send group read ack: ${e.description}');
+ }
}
```
-### 群聊
-
-对于群聊,群成员发送消息时,可以设置该消息是否需要已读回执。若需要,每个群成员在阅读消息后,SDK 均会发送已读回执,即阅读该消息的群成员数量即为已读回执的数量。群聊已读回执的有效期为 3 天,即群组中的消息发送时间超过 3 天,服务器不记录阅读该条消息的群组成员,也不会发送已读回执。
-
-群消息已读回执特性的使用限制如下表所示:
-
-| 使用限制| 默认 | 描述 |
-| :--------- | :----- | :------- |
-| 功能开通 | 关闭 | 若要使用该功能,你需要在[环信即时通讯云控制台](https://console.easemob.com/user/login)的**即时通讯** > **功能配置** > **功能配置总览**> **基础功能**页签下,搜索找到 **消息已读回执(群聊)** 开通功能。具体费用详见[产品价格](/product/pricing.html#增值服务费用)。 |
-| 使用权限 | 所有群成员 | 默认情况下,所有群成员发送消息时可要求已读回执。如果仅需群主和群管理员发消息时要求已读回执,可联系商务修改。 |
-| 已读回执有效期 | 3 天 | 群聊已读回执的有效期为 3 天,即群组中的消息发送时间超过 3 天,服务器不记录阅读该条消息的群组成员,也不会发送已读回执。 |
-| 群规模 | 200 人 | 该特性最大支持 200 人的群组。如果超过 200 人/群,群成员发送的消息不会返回已读回执。你可以联系商务提升群成员人数上限。 |
-| 查看返回已读回执数量 | 消息发送方 | 对消息返回的已读回执数量(或返回已读回执的人数),默认仅消息发送方可查看。如需所有群成员均可查看,可联系商务开通。 |
+4. 消息发送方监听群组消息已读回调。
-你可以按以下步骤实现群消息已读回执特性:
+群消息已读回调在 `EMMessageListener#onGroupMessageRead` 中实现。
-1. 消息发送方需要知道群组消息是否已读,需要监听 `onGroupMessageRead` 事件。
+发送方接收到群组消息已读回执后,调用 `EMMessage#groupAckCount()` 方法会得到最新的已读数量
```dart
EMClient.getInstance.chatManager.addEventHandler(
- "UNIQUE_HANDLER_ID",
+ 'identifier',
EMChatEventHandler(
- onGroupMessageRead: (list) => {},
+ onGroupMessageRead: (groupMessageAcks) {
+ },
),
);
```
-2. 群成员发送消息时若需已读回执,需设置 `needGroupAck` 为 `true`。
+5. 消息发送方获取群组消息的已读回执详情。
+
+你可以调用 `EMChatManager#fetchGroupAcks` 方法从服务器获取单条消息的已读回执的详情。
```dart
-// 设置消息类型为群消息
-msg.chatType = ChatType.GroupChat;
- // 设置本条消息需要群消息回执
-msg.needGroupAck = true;
try {
- await EMClient.getInstance.chatManager.sendMessage(msg);
+ await EMClient.getInstance.chatManager.fetchGroupAcks('msgId', 'groupId');
} on EMError catch (e) {
-
+ debugPrint('Failed to fetch group acks: ${e.description}');
}
```
-3. 群组里面的接收方收到消息,调用 `sendGroupMessageReadAck` 告知消息发送方消息已读。成功发送后,消息发送方会收到 `onGroupMessageRead` 回调。
+### 查看消息送达和已读状态
+
+对于单聊消息,本地通过 `EMMessage#hasDeliverAck` 字段存储消息送达状态。
+
+对于单聊消息,本地通过以下字段存储消息已读状态:
+
+| 字段 | 描述 |
+| :--------- | :----- |
+| `EMMessage#hasRead` | 用户是否已读了该消息。如果是自己发送的消息,该字段的值固定为 `true`。|
+| `EMMessage#hasReadAck` | 是否(消息接收方)已发送或(消息发送方)已收到消息已读回执。如果是自己发送的消息,记录的是对方是否已读。如果是对方的消息,则记录的是自己是否发送过已读回执。 |
+
+对于群聊消息,本地数据库通过以下字段存储消息已读状态:
+
+| 字段 | 描述 |
+| :--------- | :----- |
+| `EMMessage#hasReadAck` | 用户是否已读了该消息。如果是自己发送的消息,该字段的值固定为 `true`。|
+
+通过方法 `EMMessage#groupAckCount` 查询已阅读消息的群成员数量。
+
+### 已读回执与未读消息数
+
+- 会话已读回执发送后,开发者需要调用 `EMConversation#markAllMessagesAsRead` 方法将该会话的所有消息置为已读,即会话的未读消息数清零。
+
+- 消息已读回执发送后,开发者需要调用 `EMConversation#markMessageAsRead` 方法将该条消息置为已读,否则则消息未读数不会有变化。
+
+
+
-```dart
-try {
- EMClient.getInstance.chatManager.sendGroupMessageReadAck(msgId, groupId);
-} on EMError catch (e) {
- // 发送群消息已读失败,错误代码:e.code,错误描述:e.description
-}
-```
diff --git a/docs/document/flutter/multi_device.md b/docs/document/flutter/multi_device.md
index efdc34be0..e789ba97a 100644
--- a/docs/document/flutter/multi_device.md
+++ b/docs/document/flutter/multi_device.md
@@ -96,7 +96,7 @@ try {
初始化 SDK 时,你可以调用 `EMOptions#deviceName` 方法设置登录设备的名称。设置后,若因达到了登录设备数量限制而导致在已登录的设备上强制退出时,被踢设备收到的 `EMConnectionListener#onUserDidLoginFromOtherDevice` 回调会包含导致该设备被踢下线的自定义设备名称。
-:::notice
+:::tip
登录成功后才会将该设置发送到服务器。
:::
@@ -128,7 +128,7 @@ EMClient.getInstance.addConnectionEventHandler(
2. 初始化 SDK 时,调用 `EMOptions#osType` 方法自定义设置登录设备的平台。确保该方法中的 `osType` 参数的值与环信控制台的**添加自定义平台**对话框中设置的**设备平台**的值相同。
-:::notice
+:::tip
登录成功后才会将该设置发送到服务器。
:::
@@ -143,7 +143,7 @@ EMClient.getInstance.init(options);
初始化 SDK 时,你可以调用 `EMOptions.loginExtension` 方法设置登录设备的自定义扩展信息。设置后,若因达到了登录设备数量限制而导致在已登录的设备上强制退出时(例如 Android 平台提示 `206` 错误,`USER_LOGIN_ANOTHER_DEVICE`),被踢设备收到的 `EMConnectionEventHandler#onUserDidLoginFromOtherDevice` 回调会包含导致该设备被踢下线的新登录设备的自定义扩展信息。
-:::notice
+:::tip
登录成功后才会将该设置发送到服务器。
:::
diff --git a/docs/document/harmonyos/connection.md b/docs/document/harmonyos/connection.md
new file mode 100644
index 000000000..6f799b07f
--- /dev/null
+++ b/docs/document/harmonyos/connection.md
@@ -0,0 +1,55 @@
+# 连接
+
+应用客户端成功连接到环信服务器后,才能使用环信即时通讯 SDK 的收发消息等功能。
+
+你调用 `loginWithToken` 或 `login` 方法登录后,客户端 SDK 会自动连接环信服务器。关于登录详情,请参见[登录文档](login.html)。
+
+## 监听连接状态
+
+你可以通过注册连接监听确认连接状态。
+
+```TypeScript
+let connectionListener: ConnectionListener = {
+ onConnected: (): void => {
+ // 长连接建立
+ },
+ onDisconnected: (errorCode: number): void => {
+ // 长连接断开
+ },
+ onLogout: (errorCode: number, info: LoginExtInfo): void => {
+ // 触发退出,需要主动调用 ChatClient#logout 方法
+ },
+ onTokenExpired: (): void => {
+ // 使用 token 登录时,token 过期触发。
+ },
+ onTokenWillExpire: (): void => {
+ // 使用 token 登录时,token 将要过期时触发。
+ // 注意:如果本次登录服务器没有离线消息,不会触发该回调。
+ },
+ onOfflineMessageSyncStart: () => {
+ // 连接成功,开始从服务器拉取离线消息时触发。
+ },
+ onOfflineMessageSyncFinish: () => {
+ // 离线用户上线后从服务器拉取离线消息结束时触发。
+ // 注意:如果再拉取离线过程中因网络或其他原因导致连接断开,不会触发该回调。
+ }
+}
+// 注册连接状态监听
+ChatClient.getInstance().addConnectionListener(connectionListener);
+// 移除连接状态监听
+ChatClient.getInstance().removeConnectionListener(connectionListener);
+```
+
+## 自动重连
+
+登录后,如果由于网络信号弱、切换网络等引起的连接中断,SDK 会自动尝试重连。重连成功或者失败时分别会收到 `onConnected` 和 `onDisconnected` 通知。
+
+不过,SDK 在以下情况下会停止自动重连。你需要调用 `login` 方法登录。
+
+- 用户调用了 SDK 的登出方法 `logout` 主动退出登录。
+- 登录时鉴权错误,例如, token 无效(错误码 104)或已过期(错误码 108)。
+- 用户在其他的设备上更改了密码,导致此设备上自动登录失败,提示错误码 216。
+- 用户的账号被从服务器端删除,提示错误码 207。
+- 用户在另一设备登录,将当前设备上登录的用户踢出,提示错误码 206。
+- 用户登录设备数量超过限制,提示错误码 214。
+- 应用程序的日活跃用户数量(DAU)或月活跃用户数量(MAU)达到上限,提示错误码 8。
\ No newline at end of file
diff --git a/docs/document/harmonyos/conversation_receipt.md b/docs/document/harmonyos/conversation_receipt.md
new file mode 100644
index 000000000..03edda36f
--- /dev/null
+++ b/docs/document/harmonyos/conversation_receipt.md
@@ -0,0 +1,66 @@
+# 会话已读回执
+
+会话已读回执指接收方进入会话页面,阅读会话中的所有消息后,调用接口向服务器发送会话已读回执,服务器将该回执回调给消息发送方,消息发送方将会收到会话已读回调。在多端多设备登录下,接收方的其他设备也会收到该回调。
+
+目前,单聊和群组聊天支持会话已读回执。本文介绍如何使用环信即时通讯 IM HarmonyOS SDK 实现会话已读回执功能。
+
+会话已读回执的效果示例,如下图所示:
+
+
+
+## 技术原理
+
+ 单聊会话已读回执实现的流程如下:
+
+ 1. 设置 `ChatOptions#setRequireReadAck` 为 `true` 开启已读回执功能。
+ 2. 消息接收方进入会话页面,阅读消息后,调用 `ackConversationRead` 方法发送会话已读回执。
+ 3. 消息发送方通过监听 `onConversationRead` 回调接收会话已读回执。
+
+## 前提条件
+
+开始前,请确保满足以下条件:
+
+- 完成 SDK 初始化,并连接到服务器,详见 [快速开始](quickstart.html)。
+- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。
+
+ ## 实现方法
+
+ 参考以下步骤在单聊中实现会话已读回执:
+
+ 1. 开启已读回执功能,即 SDK 初始化时设置 `ChatOptions#setRequireReadAck` 为 `true`。
+
+ ```TypeScript
+// 设置是否需要消息已读回执,设为 `true`。
+options.setRequireReadAck(true);
+ ```
+
+ 2. 接收方发送会话已读回执。
+
+消息接收方进入会话页面,查看会话中是否有未读消息。若有,调用 `ackConversationRead` 方法发送会话已读回执,没有则不发送。
+
+若会话中存在多条未读消息,建议调用该方法,因为若调用发送消息已读回执方法 `ackMessageRead`,则需要调用多次。
+
+```TypeScript
+ChatClient.getInstance().chatManager()?.ackConversationRead(conversationId);
+```
+
+3. 消息发送方监听会话已读回执的回调。
+
+同一用户 ID 登录多设备的情况下,用户在一台设备上发送会话已读回执,其他设备会收到 `onConversationRead` 回调。
+
+:::tip
+对于群组聊天,会话已读回执只用于清空服务端的群组会话的未读数,消息发送方不会通过 `onConversationRead` 回调收到会话已读回执。
+:::
+
+```TypeScript
+let conversationListener: ConversationListener = {
+ onConversationRead: (from: string, to: string): void => {
+ // 会话已读回调
+ }
+}
+ChatClient.getInstance().chatManager()?.addConversationListener(conversationListener);
+```
+
+## 会话已读回执和消息未读数
+
+消息接收方调用 `ackConversationRead` 方法发送会话已读回执,开发者可调用 `Conversation#markAllMessagesAsRead` 方法将所有未读消息设置为已读,即将该会话的未读消息数清零。
diff --git a/docs/document/harmonyos/initialization.md b/docs/document/harmonyos/initialization.md
new file mode 100644
index 000000000..d447e9da5
--- /dev/null
+++ b/docs/document/harmonyos/initialization.md
@@ -0,0 +1,20 @@
+# SDK 初始化
+
+初始化是使用 SDK 的必要步骤,需在所有接口方法调用前完成。
+
+如果进行多次初始化操作,只有第一次初始化以及相关的参数生效。
+
+## 前提条件
+
+有效的环信即时通讯 IM 开发者账号和 App key,详见[环信即时通讯云控制台的相关文档](enable_and_configure_IM.html#创建应用)。
+
+## 初始化
+
+初始化示例代码:
+
+```TypeScript
+let options = new ChatOptions("Your appkey");
+......// 其他 ChatOptions 配置。
+// 初始化时传入上下文以及 options
+ChatClient.getInstance().init(context, options);
+```
diff --git a/docs/document/harmonyos/integration.md b/docs/document/harmonyos/integration.md
new file mode 100644
index 000000000..cfb49175b
--- /dev/null
+++ b/docs/document/harmonyos/integration.md
@@ -0,0 +1,70 @@
+# 集成 SDK
+
+本文介绍如何将环信即时通讯 IM SDK 集成到你的 HarmonyOS 项目。
+
+## 开发环境要求
+
+- DevEco Studio NEXT Release(5.0.3.900)及以上;
+- HarmonyOS SDK API 12 及以上;
+- HarmonyOS NEXT.0.0.71 或以上版本的设备。
+
+## 集成 SDK
+
+打开 [SDK 下载](https://www.easemob.com/download/im)页面,获取最新版的环信即时通讯 IM HarmonyOS SDK,得到 `har` 形式的 SDK 文件。
+
+将 SDK 文件,拷贝到 `entry` 模块或者其他需要的模块下的 `libs` 目录。
+
+修改模块目录的 `oh-package.json5` 文件,在 `dependencies` 节点增加依赖声明。
+
+```json
+{
+ "dependencies": {
+ "@easemob/chatsdk": "file:./libs/chatsdk-x.x.x.har"
+ }
+}
+```
+最后单击 **File > Sync and Refresh Project** 按钮,直到同步完成。
+
+### 添加项目权限
+
+在模块的 `module.json5` ,例如:`entry` 模块的 `module.json5` 中,配置示例如下:
+
+```json
+{
+ module: {
+ requestPermissions: [
+ {
+ name: "ohos.permission.GET_NETWORK_INFO",
+ },
+ {
+ name: "ohos.permission.INTERNET",
+ },
+ ],
+ },
+}
+```
+
+### 在工程 `build-profile.json5` 中设置支持字节码 HAR 包。
+
+修改工程级 `build-profile.json5` 文件,在 `products` 节点下设置 `useNormalizedOHMUrl` 为 `true`。
+
+```json
+{
+ "app": {
+ "products": [
+ {
+ "buildOption": {
+ "strictMode": {
+ "useNormalizedOHMUrl": true
+ }
+ }
+ }
+ ]
+ }
+}
+````
+
+:::tip
+- 此配置需要将 `DevEco Studio` 升级到 `Beta2(5.0.3.502)` 及以上版本。
+- SDK 1.3.0 及以上版本采用字节码构建方式打包,必须设置 `useNormalizedOHMUrl` 为 `true`。
+:::
\ No newline at end of file
diff --git a/docs/document/harmonyos/log.md b/docs/document/harmonyos/log.md
new file mode 100644
index 000000000..917e9fb94
--- /dev/null
+++ b/docs/document/harmonyos/log.md
@@ -0,0 +1,27 @@
+# SDK 日志
+
+环信即时通讯 IM 日志记录 SDK 相关的信息和事件。环信技术支持团队帮你排查问题时可能会请你发送 SDK 日志。
+
+## 输出信息到日志文件
+
+环信即时通讯 IM 日志记录 SDK 相关的信息和事件。环信技术支持团队帮你排查问题时可能会请你发送 SDK 日志。
+
+默认情况下,SDK 最多可生成和保存三个文件,`easemob.log` 和两个 `easemob_YYYY-MM-DD_HH-MM-SS.log` 文件。这些文件为 UTF-8 编码,每个不超过 2 MB。SDK 会将最新的日志写入 `easemob.log` 文件,写满时则会将其重命名为对应时间点的 `easemob_YYYY-MM-DD_HH-MM-SS.log` 文件,若日志文件超过三个,则会删除最早的文件。
+
+例如,SDK 在 2024 年 1 月 1 日上午 8:00:00 记录日志时会生成 `easemob.log` 文件,若在 8:30:00 将 `easemob.log` 文件写满则会将其重命名为 `easemob_2024-01-01_08-30-00.log` 文件,随后在 9:30:30 和 10:30:30 分别生成了 `easemob_2024-01-01_09-30-30.log` 和 `easemob_2024-01-01_10-30-30.log` 文件,则此时 `easemob_2024-01-01_08-30-00.log` 文件会被移除。
+
+SDK 默认输出调试信息(所有日志,包括调试信息、警告和错误),如果只需输出错误日志,需要关闭调试模式。
+
+```TypeScript
+ChatLog.setLogLevel(ChatLogLevel.ERROR_LEVEL);
+```
+
+## 获取本地日志
+
+打开以下目录,获取本地日志。
+
+```
+hdc file recv /data/app/el2/100/base/{应用包名}/{App Key}/core_log
+```
+
+获取本地日志,需要将 `{应用包名}` 替换为应用的包名,例如 `com.hyphenate.chatuidemo`;`{App Key}` 需要替换为应用的环信 App Key。
\ No newline at end of file
diff --git a/docs/document/harmonyos/login.md b/docs/document/harmonyos/login.md
new file mode 100644
index 000000000..aa71c90c9
--- /dev/null
+++ b/docs/document/harmonyos/login.md
@@ -0,0 +1,91 @@
+# 登录
+
+初始化 IM SDK 后,你需要首先调用接口登录。登录成功后,才能使用 IM 的功能。
+
+## 用户注册
+
+用户注册模式分为以下两种:
+
+- 开放注册:一般在体验 Demo 和测试环境时使用,正式环境中不推荐使用该方式注册环信账号。要使用开放注册,需要在[环信即时通讯云控制台](https://console.easemob.com/user/login)的**即时通讯** > **服务概览**的**设置**区域,将**用户注册模式**设置为**开放注册**。只有打开该开关,才能使用客户端或 [REST API](/document/server-side/account_system.html#开放注册单个用户)开放注册用户。
+
+示例代码如下所示:
+
+```TypeScript
+ChatClient.getInstance().createAccount(userId, pwd).then(()=> {
+ // success logic
+});
+```
+
+- 授权注册:通过环信提供的 REST API 注册环信用户账号,注册后保存到你的服务器或返给客户端。要使用授权注册,你需要在[环信即时通讯云控制台](https://console.easemob.com/user/login)的**即时通讯** > **服务概览**的**设置**区域,将**用户注册模式**设置为**授权注册**。相关的 REST API 介绍,详见[授权注册单个用户](/document/server-side/account_system.html#授权注册单个用户)和[批量授权注册用户](/document/server-side/account_system.html#批量授权注册用户)的接口介绍。
+
+除此以外,可以在[环信即时通讯云控制台](https://console.easemob.com/user/login)创建正式环境下和测试环境下的用户,详见[创建用户相关介绍](/product/enable_and_configure_IM.html#创建-im-用户)。
+
+## 主动登录
+
+**用户 ID + token** 是更加安全的登录方式。
+
+测试环境下,你在[环信即时通讯云控制台](https://console.easemob.com/user/login)创建用户后,环信服务器会自动为这些用户分配用户 Token,详见[测试环境下创建用户的介绍](/product/enable_and_configure_IM.html#测试环境)。
+
+使用 token 登录时需要处理 token 过期的问题,比如在每次登录时更新 token 等机制。
+
+```TypeScript
+ChatClient.getInstance().loginWithToken(userId, token).then(() => {
+ // 登录成功回调
+}).catch((e: ChatError) => {
+ // 登录失败回调,包含错误信息
+});
+```
+
+**用户 ID + 密码** 登录是传统的登录方式。用户名和密码均由你的终端用户自行决定,密码需要符合[密码规则要求](/document/server-side/account_system.html#开放注册单个用户)。
+
+```TypeScript
+ChatClient.getInstance().login(userId, pwd).then(() => {
+ // 登录成功回调
+}).catch((e: ChatError) => {
+ // 登录失败回调,包含错误信息
+});
+```
+
+## 自动登录
+
+初始化时,你可以设置 `ChatOptions#setAutoLogin` 选项确定是否自动登录。如果设置为自动登录,则登录成功之后,后续初始化 SDK 时会自动登录。
+
+## 获取当前登录的用户
+
+你可以调用 `ChatClient#getCurrentUser` 方法获取当前登录用户的用户 ID。
+
+## 获取登录状态
+
+你可以调用 `ChatClient#isLoggedIn` 方法获取当前用户的登录状态。
+
+## 退出登录
+
+你可以调用 `logout` 方法退出登录。退出登录后,你不会再收到其他用户发送的消息。
+
+```TypeScript
+ChatClient.getInstance().logout().then(()=> {
+ // success logic
+})
+```
+
+:::tip
+
+1. 如果集成了鸿蒙推送,`logout` 方法中 `unbindToken` 参数需设为 `true`,退出时会解绑设备 token,否则可能会出现退出了,还能收到消息推送通知的现象。
+2. 有时可能会遇到网络问题而解绑失败,app 处理时可以弹出提示框让用户选择,是否继续退出(弹出框提示继续退出能收到消息的风险),如果用户选择继续退出,传 `false` 再调用 `logout` 方法退出成功。
+
+:::
+
+## 账号切换
+
+若在 app 中从当前账号切换到其他账号,你需要首先调用 `logout` 方法登出,然后再调用 `loginWithToken` 或 `login` 方法登录。
+
+## 多设备登录
+
+除了单端单设备登录,环信即时通讯 IM 支持同一账号在多端的多个设备上登录。多设备登录时,若同端设备数量超过限制,新登录的设备会将之前登录的设备踢下线。
+关于多设备登录场景中的设备数量限制、互踢策略以及信息同步,详见[多设备登录文档](multi_device.html)。
+
+## 更多
+
+### 登录被封禁账号的提示
+
+在环信即时通讯控制台或调用 REST API 封禁用户账号后,若仍使用该账号登录,SDK会返回 "service is disabled"(305 错误), 可以根据用户这个返回值来进行相应的提示或者处理。
diff --git a/docs/document/harmonyos/message_receipt.md b/docs/document/harmonyos/message_receipt.md
index f497f5fa7..72b3e1c80 100644
--- a/docs/document/harmonyos/message_receipt.md
+++ b/docs/document/harmonyos/message_receipt.md
@@ -1,43 +1,36 @@
-# 消息回执
+# 实现消息回执
-单聊会话支持消息送达回执、会话已读回执和消息已读回执,发送方发送消息后可及时了解接收方是否及时收到并阅读了信息,也可以了解整个会话是否已读。
+**单聊会话支持消息送达回执和消息已读回执**,发送方发送消息后可及时了解接收方是否及时收到并阅读了消息。
-群聊会话只支持消息已读回执。群成员在发送消息时,可以设置该消息是否需要已读回执。仅专业版及以上版本支持群消息已读回执功能。若要使用该功能,需在[环信即时通讯云控制台](https://console.easemob.com/user/login)开通,具体费用详见[产品价格](/product/pricing.html#增值服务费用)。
+**群聊会话只支持消息已读回执,不支持送达回执**。群成员在发送消息时,可以设置该消息是否需要已读回执。要使用该功能,你需要[在环信即时通讯云控制台上开通该功能](/product/enable_and_configure_IM.html#设置群消息已读回执),具体费用详见[产品价格](/product/pricing.html#增值服务费用)。
-:::tip
-仅单聊消息支持送达回执,群聊消息不支持。
-:::
+消息送达回执和已读回执的效果示例,如下图所示:
-本文介绍如何使用环信即时通讯 IM HarmonyOS SDK 实现单聊和群聊的消息回执功能。
+
## 技术原理
-使用环信即时通讯 IM SDK 可以实现消息的送达回执与已读回执,核心方法如下:
+使用环信即时通讯 IM HarmonyOS SDK 可以实现消息的送达回执与已读回执。
-- `ChatOptions#setRequireDeliveryAck` 开启送达回执;
-- `ChatManager#ackConversationRead` 发出指定会话的已读回执;
-- `ChatManager#ackMessageRead` 发出指定消息的已读回执;
-- `ChatManager#ackGroupMessageRead` 发出群组消息的已读回执。
+- 单聊消息送达回执的逻辑如下:
-送达和已读回执逻辑分别如下:
+ 1. 你可以通过设置 `ChatOptions.setRequireDeliveryAck` 为 `true` 开启送达回执功能。
+ 2. 消息接收方收到消息后,SDK 自动向发送方触发送达回执。
+ 3. 消息发送方通过监听 `ChatMessageListener#onMessageDelivered` 回调接收消息送达回执。
-单聊消息送达回执:
+- 单聊消息已读回执的逻辑如下:
-1. 消息发送方在发送消息前通过 `ChatOptions.setRequireDeliveryAck` 开启送达回执功能;
-2. 消息接收方收到消息后,SDK 自动向发送方触发送达回执;
-3. 消息发送方通过监听 `OnMessageDelivered` 回调接收消息送达回执。
+ 1. 你可以通过设置 `ChatOptions.setRequireReadAck` 为 `true` 开启已读回执功能。
+ 2. 消息接收方收到消息后,调用 `ChatManager#ackMessageRead` 方法发送消息已读回执。
+ 3. 消息发送方通过监听 `ChatMessageListener#onMessageRead` 回调接收消息已读回执。
-已读回执:
+- 群聊消息已读回执的逻辑如下:
-- 单聊会话及消息已读回执
- 1. 调用 `ChatOptions.setRequireReadAck` 设置需要发送已读回执,传 `true`;
- 2. 消息接收方收到或阅读消息后,调用 API `ackConversationRead` 或 `ackMessageRead` 发送会话或消息已读回执;
- 3. 消息发送方通过监听 `ConversationListener#OnConversationRead` 或 `ChatMessageListener#OnMessageRead` 回调接收会话或消息已读回执。
-- 群聊只支持消息已读回执:
- 1. 你可以通过设置 `ChatMessage.isNeedGroupAck` 为 `true` 开启群聊消息已读回执功能;
- 2. 消息接收方收到或阅读消息后通过 `ackGroupMessageRead` 发送群组消息的已读回执。
+ 1. 你可以通过设置 `ChatMessage.isNeedGroupAck` 为 `true` 开启消息已读回执功能。
+ 2. 发送方在群组中发送消息时设置 `EMMessage#setIsNeedGroupAck` 为 `true` 要求接收方返回消息已读回执。
+ 3. 接收方收到或阅读消息后通过 `ChatManager#ackGroupMessageRead` 方法发送群组消息的已读回执。
## 前提条件
@@ -45,20 +38,22 @@
- 完成 SDK 初始化,并连接到服务器,详见 [快速开始](quickstart.html)。
- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。
-- 群消息已读回执功能仅在环信 IM 专业版及以上版本支持该功能。若要使用该功能,需在[环信即时通讯云控制台](https://console.easemob.com/user/login)开通,具体费用详见[产品价格](/product/pricing.html#增值服务费用)。
-
+- 要使用群消息已读回执功能,需在[环信即时通讯云控制台](https://console.easemob.com/user/login)开通,具体费用详见[产品价格](/product/pricing.html#增值服务费用)。
+
## 实现方法
-### 消息送达回执
+### 单聊消息送达回执
-若在消息送达时收到通知,你可以打开消息送达开关,这样在消息到达对方设备时你可以收到通知。
+1. 开启消息送达功能,即 SDK 初始化时将 `ChatOptions.setRequireDeliveryAck` 设置为 `true`。
```TypeScript
// 设置是否需要接收方送达确认,默认 `false` 即不需要。
-options.setRequireDeliveryAck(false);
+options.setRequireDeliveryAck(true);
```
-`onMessageDelivered` 回调是对方收到消息时的通知,你可以在收到该通知时,显示消息的送达状态。
+2. 接收方收到消息后,SDK 自动向发送方触发送达回执。
+
+3. 发送方监听 `ChatMessageListener#onMessageDelivered` 事件,收到接收方的送达回执。你可以在收到该通知时,显示消息的送达状态。
```TypeScript
let msgListener: ChatMessageListener = {
@@ -75,64 +70,31 @@ ChatClient.getInstance().chatManager()?.addMessageListener(msgListener);
ChatClient.getInstance().chatManager()?.removeMessageListener(msgListener);
```
-### 消息已读回执
-
-消息已读回执用于告知单聊或群聊中的用户接收方已阅读其发送的消息。为降低消息已读回执方法的调用次数,SDK 还支持在单聊中使用会话已读回执功能,用于获知接收方是否阅读了会话中的未读消息。
-
-#### 单聊
+### 单聊消息已读回执
-单聊既支持消息已读回执,也支持会话已读回执。我们建议你按照如下逻辑结合使用两种回执,减少发送消息已读回执数量。
+单聊既支持单条消息已读回执,也支持[会话已读回执](conversation_receipt.html)。我们建议你结合使用这两种回执,见实现步骤的描述。
-- 聊天页面未打开时,若有未读消息,进入聊天页面,发送会话已读回执;
-- 聊天页面打开时,若收到消息,发送消息已读回执。
+单聊消息的已读回执有效期与消息在服务端的存储时间一致,即在服务器存储消息期间均可发送已读回执。消息在服务端的存储时间与你订阅的套餐包有关,详见[产品价格](/product/pricing.html#套餐包功能详情)。
-第一步是在设置中打开已读回执开关:
+参考如下步骤在单聊中实现消息已读回执。
+1. App 开启已读回执功能,即 SDK 初始化时将 `ChatOptions.setRequireReadAck` 设置为 `true`。
```TypeScript
-// 设置是否需要消息已读回执,设为 `true`。
+// 设置是否需要接受方已读确认,默认为true
options.setRequireReadAck(true);
```
-##### 会话已读回执
-
- 参考以下步骤在单聊中实现会话已读回执。
-
- 1. 接收方发送会话已读回执。
-
- 消息接收方进入会话页面,查看会话中是否有未读消息。若有,发送会话已读回执,没有则不再发送。
+1. 接收方发送消息已读回执。
+- 聊天页面打开时,若收到消息,发送单条消息已读回执。
+
```TypeScript
ChatClient.getInstance().chatManager()?.ackConversationRead(conversationId);
```
-2. 消息发送方监听会话已读回执的回调。
-
-```TypeScript
-let conversationListener: ConversationListener = {
- onConversationRead: (from: string, to: string): void => {
- // 会话已读回调
- }
-}
-ChatClient.getInstance().chatManager()?.addConversationListener(conversationListener);
-```
-
-> 同一用户 ID 登录多设备的情况下,用户在一台设备上发送会话已读回执,服务器会将会话的未读消息数置为 `0`,同时其他设备会收到 `OnConversationRead` 回调。
-
-##### 消息已读回执
-
-单聊消息的已读回执有效期与消息在服务端的存储时间一致,即在服务器存储消息期间均可发送已读回执。消息在服务端的存储时间与你订阅的套餐包有关,详见[产品价格](/product/pricing.html#套餐包功能详情)。
-
-参考如下步骤在单聊中实现消息已读回执。
-
- 1. 接收方发送已读回执消息。
-
- 消息接收方进入会话时,发送会话已读回执。
-
-```TypeScript
-ChatClient.getInstance().chatManager()?.ackMessageRead(messageId);
-```
-
-在会话页面,接收到消息时,根据消息类型发送消息已读回执,如下所示:
+- 接收方在会话页面,接收到消息时,再根据消息类型发送单个消息已读回执。
+
+ 聊天页面未打开时,若有未读消息,进入聊天页面,发送会话已读回执。这种方式可避免发送多个消息已读回执。
```TypeScript
let msgListener: ChatMessageListener = {
@@ -146,6 +108,7 @@ let msgListener: ChatMessageListener = {
ChatClient.getInstance().chatManager()?.addMessageListener(msgListener);
private sendReadAck(message: ChatMessage) {
+ // 这里是接收的消息,未发送过已读回执且是单聊。
if (message.getDirection() === MessageDirection.RECEIVE
&& !message.isReceiverRead()
&& message.getChatType() === ChatType.Chat) {
@@ -156,9 +119,9 @@ private sendReadAck(message: ChatMessage) {
}
```
-2. 消息发送方监听消息已读回调。
+3. 消息发送方监听消息已读回调。
-你可以调用接口监听指定消息是否已读,示例代码如下:
+消息发送方可以通过 `ChatMessageListener.onMessageRead` 事件监听指定消息是否已读,示例代码如下:
```TypeScript
let msgListener: ChatMessageListener = {
@@ -171,9 +134,9 @@ let msgListener: ChatMessageListener = {
ChatClient.getInstance().chatManager()?.addMessageListener(msgListener);
```
-#### 群聊
+### 群聊消息已读回执
-对于群聊,群成员发送消息时,可以设置该消息是否需要已读回执。若需要,每个群成员在阅读消息后,SDK 均会发送已读回执,即阅读该消息的群成员数量即为已读回执的数量。
+对于群聊,群成员发送消息时,可以设置该消息是否需要已读回执。若需要,每个群成员阅读消息后,应该调用`ChatManager.ackGroupMessageRead` 方法发送已读回执,阅读该消息的群成员数量即为已读回执的数量。
群消息已读回执特性的使用限制如下表所示:
@@ -187,7 +150,18 @@ ChatClient.getInstance().chatManager()?.addMessageListener(msgListener);
你可以按以下步骤实现群消息已读回执特性:
-1. 群成员发送消息时若需已读回执,需设置 `ChatMessage` 的方法 `setIsNeedGroupAck()` 为 `true`。
+1. 开启已读回执功能,即 SDK 初始化时将 `ChatOptions.setRequireReadAck` 设置为 `true`。
+
+该功能开启后,接收方阅读消息后,SDK 底层会自动进行消息已读回执。
+
+```TypeScript
+// 设置是否需要接受方已读确认,默认为 `true`。
+options.setRequireReadAck(true);
+```
+
+2. 发送方发送消息时设置 `ChatMessage.setIsNeedGroupAck` 属性为 `true`。
+
+与单聊消息的 app 层级设置已读回执功能不同,群聊消息是在发送消息时设置指定消息是否需要已读回执。
```TypeScript
let message = ChatMessage.createTextSendMessage(to, content);
@@ -198,7 +172,7 @@ message.setChatType(ChatType.GroupChat);
message.setIsNeedGroupAck(true);
```
-2. 消息接收方发送群组消息的已读回执。
+3. 消息接收方发送群组消息的已读回执。
```TypeScript
if (message.isNeedGroupAck() && !message.isUnread()) {
@@ -207,23 +181,57 @@ if (message.isNeedGroupAck() && !message.isUnread()) {
}
```
-3. 消息发送方监听群组消息已读回调。
+4. 消息发送方监听群组消息已读回调。
+
+群消息已读回调在 `ChatMessageListener#onGroupMessageRead` 中实现。
-群消息已读回调在消息监听类 `ChatMessageListener` 中。
+发送方接收到群组消息已读回执后,其发出消息的属性 `ChatMessage.groupAckCount` 会有相应变化。
```TypeScript
-// 接收到群组消息体的已读回执, 消息的接收方已经阅读此消息。
-onGroupMessageRead?: (groupReadAcks: Array) => void;
+let msgListener: ChatMessageListener = {
+ ......
+ onGroupMessageRead?: (groupReadAcks: Array) => {
+ // 接收到群组消息体的已读回执, 消息的接收方已经阅读此消息。
+ }
+ ......
+}
+ChatClient.getInstance().chatManager()?.addMessageListener(msgListener);
```
-接收到群组消息已读回执后,发出消息的属性 `ChatMessage#groupAckCount` 会有相应变化;
-
-4. 消息发送方获取群组消息的已读回执详情。
+5. 消息发送方获取群组消息的已读回执详情。
-如果想实现群消息已读回执的列表显示,可以通过下列接口获取到已读回执的详情。
+你可以调用 `ChatManager#fetchGroupReadAcks` 方法从服务器获取单条消息的已读回执的详情。
```TypeScript
ChatClient.getInstance().chatManager()?.fetchGroupReadAcks(messageId, pageSize, startAckId).then((result) => {
// success logic
})
-```
\ No newline at end of file
+```
+
+### 查看消息送达和已读状态
+
+对于单聊消息,本地通过 `ChatMessage.isDelivered` 字段存储消息送达状态。
+
+对于单聊消息,本地通过以下字段存储消息已读状态:
+
+| 字段 | 描述 |
+| :--------- | :----- |
+| `ChatMessage.isUnread` | 用户是否已读了该消息。如果是自己发送的消息,该字段的值固定为 `true`。|
+| `ChatMessage.isReceiverRead` | 是否(消息接收方)已发送或(消息发送方)已收到消息已读回执。如果是自己发送的消息,记录的是对方是否已读。如果是对方的消息,则记录的是自己是否发送过已读回执。 |
+
+对于群聊消息,本地数据库通过以下字段存储消息已读状态:
+
+| 字段 | 描述 |
+| :--------- | :----- |
+| `ChatMessage.isUnread` | 用户是否已读了该消息。如果是自己发送的消息,该字段的值固定为 `true`。|
+| `ChatMessage.groupAckCount` | 已阅读消息的群成员数量。 |
+
+### 已读回执与未读消息数
+
+- 会话已读回执发送后,开发者需要调用 `Conversation.markAllMessagesAsRead` 方法将该会话的所有消息置为已读,即会话的未读消息数清零。
+
+- 消息已读回执发送后,开发者需要调用 `Conversation.markMessageAsRead` 方法将该条消息置为已读,则消息未读数会有变化。
+
+
+
+
diff --git a/docs/document/harmonyos/multi_device.md b/docs/document/harmonyos/multi_device.md
index 2dd8b2859..0729a96b6 100644
--- a/docs/document/harmonyos/multi_device.md
+++ b/docs/document/harmonyos/multi_device.md
@@ -75,7 +75,7 @@ ChatClient.getInstance().contactManager()?.getSelfIdsOnOtherPlatform().then(ids
初始化 SDK 时,你可以调用 `ChatOptions#setLoginCustomExt` 方法设置登录设备的自定义扩展信息。设置后,若因达到了登录设备数量限制而导致在已登录的设备上强制退出时(`206` 错误,`USER_LOGIN_ANOTHER_DEVICE`),被踢设备收到的 `ConnectionListener#onLogout` 回调会包含导致该设备被踢下线的新登录设备的自定义扩展信息。
-:::notice
+:::tip
登录成功后才会将该设置发送到服务器。
:::
diff --git a/docs/document/harmonyos/quickstart.md b/docs/document/harmonyos/quickstart.md
index f01d287cd..d6dbe3e58 100644
--- a/docs/document/harmonyos/quickstart.md
+++ b/docs/document/harmonyos/quickstart.md
@@ -56,7 +56,7 @@
]
}
}
-````
+```
:::tip
- 此配置需要将 `DevEco Studio` 升级到 `Beta2(5.0.3.502)` 及以上版本。
diff --git a/docs/document/harmonyos/releasenote.md b/docs/document/harmonyos/releasenote.md
index 5de78336e..80a53de4d 100644
--- a/docs/document/harmonyos/releasenote.md
+++ b/docs/document/harmonyos/releasenote.md
@@ -44,7 +44,7 @@
- `ChatOptions#setLoginCustomExt`:设置设备的扩展信息;
- `ChatOptions#getLoginCustomExt`:获取设备的扩展信息。
- `ConnectionListener#onLogout(errorCode: number, info: LoginExtInfo)`:多设备登录场景下,若当前设备被新登录设备踢下线,被踢设备收到的事件中会携带新设备的扩展信息。
-- 新增[从服务器拉取离线消息的开始和结束的事件回调](overview.html#连接状态相关): `ConnectionListener#onOfflineMessageSyncStart` 和 `ConnectionListener#onOfflineMessageSyncFinish`。
+- 新增[从服务器拉取离线消息的开始和结束的事件回调](connection.html#监听连接状态): `ConnectionListener#onOfflineMessageSyncStart` 和 `ConnectionListener#onOfflineMessageSyncFinish`。
- 新增 `GroupManager#checkIfInGroupMutelist` 接口,可以[查看当前用户是否在群组禁言列表中](group_members.html#检查自己是否在禁言列表中)。
- 新增 [错误码 213 ChatError#USER_BIND_ANOTHER_DEVICE](error.html),用于当用户达到登录设备上线时,当前设备无法登录的场景。
- 在撤回消息的 `ChatMessageListener#onMessageRecalled` 事件中[返回被撤回的消息所属的会话 ID](message_recall.html#设置消息撤回监听)。
diff --git a/docs/document/ios/connection.md b/docs/document/ios/connection.md
new file mode 100644
index 000000000..df358eadc
--- /dev/null
+++ b/docs/document/ios/connection.md
@@ -0,0 +1,54 @@
+# 连接
+
+应用客户端成功连接到环信服务器后,才能使用环信即时通讯 SDK 的收发消息等功能。
+
+你调用 `login` 方法登录后,客户端 SDK 会自动连接环信服务器。关于登录详情,请参见[登录文档](login.html)。
+
+## 监听连接状态
+
+你可以通过注册连接监听确认连接状态。
+
+```swift
+override func viewDidLoad() {
+ ...
+ // 注册连接状态监听,在 SDK 初始化之后调用。
+ EMClient.shared().add(self, delegateQueue: nil)
+ ...
+}
+
+extension ViewController: EMClientDelegate {
+ // 连接成功,开始从服务器拉取离线消息时触发。
+ // 注意:如果本次登录服务器没有离线消息,不会触发该回调。
+ func onOfflineMessageSyncStart() {
+ }
+ // 离线用户上线后从服务器拉取离线消息结束时触发。
+ // 注意:如果再拉取离线过程中因网络或其他原因导致连接断开,不会触发该回调。
+ func onOfflineMessageSyncFinish() {
+ }
+
+ // 连接状态变更时触发该回调
+ func connectionStateDidChange(_ aConnectionState: EMConnectionState) {
+
+ }
+
+ // token 已过期
+ func tokenDidExpire(_ aErrorCode: EMErrorCode) {
+
+ }
+}
+
+```
+
+## 自动重连
+
+登录后,如果由于网络信号弱、切换网络等引起的连接中断,SDK 会自动尝试重连。重连成功或者失败时会收到 `connectionStateDidChange` 通知。
+
+不过,SDK 在以下情况下会停止自动重连。你需要调用 `login` 方法登录。
+
+- 用户调用了 SDK 的登出方法 `logout` 主动退出登录。
+- 登录时鉴权错误,例如, token 无效(错误码 104)或已过期(错误码 108)。
+- 用户在其他的设备上更改了密码,导致此设备上自动登录失败,提示错误码 216。
+- 用户的账号被从服务器端删除,提示错误码 207。
+- 用户在另一设备登录,将当前设备上登录的用户踢出,提示错误码 206。
+- 用户登录设备数量超过限制,提示错误码 214。
+- 应用程序的日活跃用户数量(DAU)或月活跃用户数量(MAU)达到上限,提示错误码 8。
\ No newline at end of file
diff --git a/docs/document/ios/conversation_receipt.md b/docs/document/ios/conversation_receipt.md
index b46f10b77..94ef21479 100644
--- a/docs/document/ios/conversation_receipt.md
+++ b/docs/document/ios/conversation_receipt.md
@@ -16,6 +16,13 @@
2. 消息接收方进入会话页面,阅读消息后,调用 `ackConversationRead` 方法发送会话已读回执;
3. 消息发送方通过监听 `onConversationRead` 回调接收会话已读回执。
+## 前提条件
+
+开始前,请确保满足以下条件:
+
+- 完成 SDK 初始化,并连接到服务器,详见 [快速开始](quickstart.html)。
+- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。
+
## 实现方法
参考以下步骤在单聊中实现会话已读回执:
diff --git a/docs/document/ios/initialization.md b/docs/document/ios/initialization.md
new file mode 100644
index 000000000..c1764cf18
--- /dev/null
+++ b/docs/document/ios/initialization.md
@@ -0,0 +1,19 @@
+# SDK 初始化
+
+初始化是使用 SDK 的必要步骤,需在所有接口方法调用前完成。
+
+如果进行多次初始化操作,只有第一次初始化以及相关的参数生效。
+
+## 前提条件
+
+有效的环信即时通讯 IM 开发者账号和 App key,详见[环信即时通讯云控制台的相关文档](/product/enable_and_configure_IM.html#创建应用)。
+
+## 初始化
+
+初始化示例代码:
+
+```swift
+let options = EMOptions(appkey: "Your appkey")
+......// 其他 EMOptions 配置。
+EMClient.shared().initializeSDK(with: options)
+```
diff --git a/docs/document/ios/integration.md b/docs/document/ios/integration.md
new file mode 100644
index 000000000..c16006dd6
--- /dev/null
+++ b/docs/document/ios/integration.md
@@ -0,0 +1,46 @@
+# 集成 SDK
+
+本文介绍如何将环信即时通讯 IM SDK 集成到你的 Android 项目。
+
+## 开发环境要求
+
+- Xcode (推荐最新版本)。
+- 安装 iOS 10.0 或更高版本的 iOS 模拟器或 Apple 设备。
+- CocoaPods 1.10.1 或更高版本。
+
+## 集成 SDK
+
+选择如下任意一种方式将环信即时通讯 IM SDK 集成到你的项目中。
+
+:::tip
+
+1. 以下集成方式只需选择一种,同时使用多种集成方式可能会报错。
+2. 请点击查看[发版说明](releasenote.html)获得最新版本号。
+
+:::
+
+### 方法一:使用 Cocoapods 自动集成
+
+1. 在 **Terminal** 里进入项目根目录,并运行 pod init 命令。项目文件夹下会生成一个 Podfile 文本文件。
+打开 **Podfile** 文件,修改文件为如下内容:
+
+```ruby
+# platform :ios, '10.0'
+
+ target 'EMChatQuickstart' do
+ pod 'HyphenateChat'
+ end
+ ```
+
+2. 运行 `pod update` 命令更新本地库版本。
+3. 运行 `pod install` 命令安装 HyphenateChat SDK。成功安装后,**Terminal** 中会显示 Pod installation complete!,此时项目文件夹下会生成一个 `xcworkspace` 文件。
+
+### 方法二:手动复制 SDK 文件
+
+打开 SDK 下载页面,获取最新版的环信即时通讯 IM SDK SDK,然后解压。
+
+将 SDK 包内的 `HyphenateChat.xcframework` 拖入到你的工程中。
+
+:::tip
+如果使用`4.11.0`及以上版本的SDK,需要将`aosl.xcframework`和`HyphenateChat.xcframework`同时导入到工程中。
+:::
diff --git a/docs/document/ios/log.md b/docs/document/ios/log.md
new file mode 100644
index 000000000..4db03b4a4
--- /dev/null
+++ b/docs/document/ios/log.md
@@ -0,0 +1,39 @@
+# SDK 日志
+
+环信即时通讯 IM 日志记录 SDK 相关的信息和事件。环信技术支持团队帮你排查问题时可能会请你发送 SDK 日志。
+
+## 输出信息到日志文件
+
+默认情况下,SDK 最多可生成和保存三个文件,`easemob.log` 和两个 `easemob_YYYY-MM-DD_HH-MM-SS.log` 文件。这些文件为 UTF-8 编码,每个不超过 2 MB。SDK 会将最新的日志写入 `easemob.log` 文件,写满时则会将其重命名为对应时间点的 `easemob_YYYY-MM-DD_HH-MM-SS.log` 文件,若日志文件超过三个,则会删除最早的文件。
+
+例如,SDK 在 2024 年 1 月 1 日上午 8:00:00 记录日志时会生成 `easemob.log` 文件,若在 8:30:00 将 `easemob.log` 文件写满则会将其重命名为 `easemob_2024-01-01_08-30-00.log` 文件,随后在 9:30:30 和 10:30:30 分别生成了 `easemob_2024-01-01_09-30-30.log` 和 `easemob_2024-01-01_10-30-30.log` 文件,则此时 `easemob_2024-01-01_08-30-00.log` 文件会被移除。
+
+SDK 的 `EMOptions#logLevel` 指定了日志输出级别,默认为 `EMLogLevelDebug`,即所有等级日志。
+
+- (默认)EMLogLevelDebug:所有等级的日志;
+- EMLogLevelWarning:警告及错误;
+- EMLogLevelError:错误。
+
+开发阶段若希望在 XCode console 上输出 SDK 日志,可在 SDK 初始化时打开开关。
+
+```objectivec
+EMOptions* option = [EMOptions optionsWithAppkey:@"<#appkey#>"];
+// 日志输出到 XCode console
+option.enableConsoleLog = YES;
+// 调整日志输出级别,默认为所有级别。
+option.logLevel = EMLogLevelDebug;
+[EMClient.sharedClient initializeSDKWithOptions:option];
+```
+
+## 获取本地日志
+
+SDK 会写入日志文件到本地。日志文件路径如下:沙箱 Library/Application Support/HyphenateSDK/easemobLog。
+
+以真机为例,获取本地日志过程如下:
+
+- 打开 Xcode,连接设备,选择 **Xcode** > **Window** > **Devices and Simulators**。
+- 进入 **Devices** 选项卡,在左侧选择目标设备,例如 Easemob IM,点击设置图标,然后选择 **Download Container**。
+
+
+
+日志文件 `easemob.log` 文件在下载包的 `AppData/Library/Application Support/HyphenateSDK/easemobLog` 目录下。
\ No newline at end of file
diff --git a/docs/document/ios/login.md b/docs/document/ios/login.md
new file mode 100644
index 000000000..82cdfbce4
--- /dev/null
+++ b/docs/document/ios/login.md
@@ -0,0 +1,115 @@
+# 登录
+
+初始化 IM SDK 后,你需要首先调用接口登录。登录成功后,才能使用 IM 的功能。
+
+## 用户注册
+
+用户注册模式分为以下两种:
+
+- 开放注册:一般在体验 Demo 和测试环境时使用,正式环境中不推荐使用该方式注册环信账号。要使用开放注册,需要在[环信即时通讯云控制台](https://console.easemob.com/user/login)的**即时通讯** > **服务概览**的**设置**区域,将**用户注册模式**设置为**开放注册**。只有打开该开关,才能使用客户端或 [REST API](/document/server-side/account_system.html#开放注册单个用户)开放注册用户。
+
+示例代码如下所示:
+
+```Objective-C
+// 异步方法
+[[EMClient sharedClient] registerWithUsername:@"username"
+ password:@"your password"
+ completion:^(NSString *aUsername, EMError *aError) {
+ }];
+```
+
+- 授权注册:通过环信提供的 REST API 注册环信用户账号,注册后保存到你的服务器或返给客户端。要使用授权注册,你需要在[环信即时通讯云控制台](https://console.easemob.com/user/login)的**即时通讯** > **服务概览**的**设置**区域,将**用户注册模式**设置为**授权注册**。相关的 REST API 介绍,详见[授权注册单个用户](/document/server-side/account_system.html#授权注册单个用户)和[批量授权注册用户](/document/server-side/account_system.html#批量授权注册用户)的接口介绍。
+
+除此以外,可以在[环信即时通讯云控制台](https://console.easemob.com/user/login)创建用户,详见[创建用户相关介绍](/product/enable_and_configure_IM.html#创建-im-用户)。
+
+## 主动登录
+
+1. **用户 ID + token** 是更加安全的登录方式。
+
+使用 token 登录时需要处理 token 过期的问题,比如在每次登录时更新 token 等机制。
+
+```swift
+EMClient.shared().login(withUsername: "userId", token: "token") { userId, err in
+ if err == nil {
+ // 登录成功
+ } else {
+ // 登录失败
+ }
+}
+```
+
+2. **用户 ID + 密码** 是传统的登录方式。用户名和密码均由你的终端用户自行决定,密码需要符合密码规则要求。
+
+```Objective-C
+ //SDK 初始化 `EMOptions` 时可以传入 `loginExtensionInfo` 属性投递给被踢下线的设备。该属性需要开启多设备登录的情况下才能生效。
+ EMOptions *options = [EMOptions optionsWithAppkey:<#AppKey#>];
+ options.loginExtensionInfo = @"you was kicked out by other device";
+ [EMClient.sharedClient initializeSDKWithOptions:options];
+// 异步方法
+[[EMClient sharedClient] loginWithUsername:@"username"
+ password:@"your password"
+ completion:^(NSString *aUsername, EMError *aError) {
+
+}];
+```
+
+## 自动登录
+
+初始化时,你可以设置 `EMOptions#isAutoLogin` 选项确定是否自动登录。如果设置为自动登录,则登录成功之后,后续初始化 SDK 时会自动登录,并收到以下回调。
+
+```swift
+extension ViewController: EMClientDelegate {
+ func autoLoginDidCompleteWithError(_ aError: EMError?) {
+
+ }
+}
+```
+
+## 获取当前登录的用户
+
+你可以调用 `EMClient.shared().currentUsername` 方法获取当前登录用户的用户 ID。
+
+## 获取登录状态
+
+你可以调用 `EMClient.shared().isLoggedIn` 方法获取当前用户的登录状态。
+
+## 退出登录
+
+你可以调用 `logout` 方法退出登录。退出登录后,你不会再收到其他用户发送的消息。
+
+异步方法:
+
+```swift
+EMClient.shared().logout(true) { aError in
+ if aError == nil {
+ // 退出成功
+ } else {
+ // 退出失败
+ }
+}
+```
+
+:::tip
+
+1. 如果集成了 APNs 等第三方推送,`logout` 方法中 `aIsUnbindDeviceToken` 参数需设为 `true`,退出时会解绑设备 token,否则可能会出现退出了,还能收到消息推送通知的现象。
+有时可能会遇到网络问题而解绑失败,app 处理时可以弹出提示框让用户选择,是否继续退出(弹出框提示继续退出能收到消息的风险),如果用户选择继续退出,传 `false` 再调用 `logout` 方法退出成功。当然也可以失败后还是返回退出成功,然后在后台起个线程不断调用 `logout` 方法直到成功。这样存在风险,即用户杀掉了 app,网络恢复后用户还会继续收到消息。
+
+2. 如果调用异步退出方法,在收到 `completion` 回调后才能去调用 IM 相关方法,例如 `login`。
+:::
+
+## 账号切换
+
+若在 app 中从当前账号切换到其他账号,你需要首先调用 `logout` 方法登出,然后再调用 `login` 方法登录,此时`aIsUnbindDeviceToken`参数需设为`false`。
+
+## 多设备登录
+
+除了单端单设备登录,环信即时通讯 IM 支持同一账号在多端的多个设备上登录。多设备登录时,若同端设备数量超过限制,新登录的设备会将之前登录的设备踢下线。
+
+关于多设备登录场景中的设备数量限制、互踢策略以及信息同步,详见[多设备登录文档](multi_device.html)。
+
+
+## 更多
+
+### 登录被封禁账号的提示
+
+在环信即时通讯控制台或调用 REST API 封禁用户账号后,若仍使用该账号登录,SDK会返回 "service is disabled"(305 错误), 可以根据用户这个返回值来进行相应的提示或者处理。
diff --git a/docs/document/ios/message_receipt.md b/docs/document/ios/message_receipt.md
index a4a9a4599..cc52278ea 100644
--- a/docs/document/ios/message_receipt.md
+++ b/docs/document/ios/message_receipt.md
@@ -38,8 +38,8 @@
- 完成 SDK 初始化,并连接到服务器,详见 [快速开始](quickstart.html)。
- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。
-- 在环信即时通讯云控制台开启群消息已读回执功能。
-
+- 要使用群消息已读回执功能,需在[环信即时通讯云控制台](https://console.easemob.com/user/login)开通,具体费用详见[产品价格](/product/pricing.html#增值服务费用)。
+
## 实现方法
### 单聊消息送达回执
diff --git a/docs/document/ios/multi_device.md b/docs/document/ios/multi_device.md
index 7d7ef7d85..ef31cf156 100644
--- a/docs/document/ios/multi_device.md
+++ b/docs/document/ios/multi_device.md
@@ -97,7 +97,7 @@ iOS SDK 初始化时会生成登录 ID 用于在多设备登录和消息推送
初始化 SDK 时,你可以调用 `initializeSDKWithOptions` 方法时设置 `EMOptions#customDeviceName` 属性自定义登录设备的名称。设置设备名称后,若登录设备时因达到了登录设备数量限制而导致在已登录的设备上强制退出时,被踢设备收到的 `userAccountDidLoginFromOtherDevice` 回调里会包含导致该设备被踢下线的自定义设备名称。
-:::notice
+:::tip
登录成功后才会将该设置发送到服务器。
:::
@@ -122,7 +122,7 @@ option.customDeviceName = @"XXX的iPad";
2. 初始化 SDK 时,调用 `initializeSDKWithOptions` 方法设置 `EMOptions#customOSType` 属性添加自定义平台。确保该属性的值与环信控制台的**新增自定义平台**对话框中设置的**设备平台**的值相同。
-:::notice
+:::tip
登录成功后才会将该设置发送到服务器。
:::
@@ -138,7 +138,7 @@ option.customOSType = 60;
初始化 SDK 时,可通过 `EMOptions#loginExtensionInfo` 属性设置设备扩展信息。设置后,多设备场景下,登录该设备后,若因达到了登录设备数量限制而导致当前登录设备被踢下线(`206` 错误,`EMErrorUserLoginOnAnotherDevice`),被踢设备收到的 `EMClientDelegate#userAccountDidLoginFromOtherDeviceWithInfo` 回调中会包含该设备的自定义扩展信息。
-:::notice
+:::tip
登录成功后才会将该设置发送到服务器。
:::
diff --git a/docs/document/ios/releasenote.md b/docs/document/ios/releasenote.md
index 66624185b..5224555e7 100644
--- a/docs/document/ios/releasenote.md
+++ b/docs/document/ios/releasenote.md
@@ -92,7 +92,7 @@ end
### 新增特性
-- [IM SDK] 新增[从服务器拉取离线消息的开始和结束的事件回调](overview.html#连接状态相关): `EMClientDelegate#onOfflineMessageSyncStart` 和`EMClientDelegate#onOfflineMessageSyncFinish`。
+- [IM SDK] 新增[从服务器拉取离线消息的开始和结束的事件回调](connection.html#监听连接状态): `EMClientDelegate#onOfflineMessageSyncStart` 和`EMClientDelegate#onOfflineMessageSyncFinish`。
- [IM SDK] 新增 `IEMGroupManager#isMemberInMuteListFromServerWithGroupId:completion:` 接口,可以查看当前用户是否在群组禁言名单中。
- [IM SDK] 原消息置顶接口 `IEMChatManager#pinMessage` 和 `IEMChatManager#unpinMessage` [增加对单聊会话中置顶消息的支持](message_pin.html)。接口参数无变化。
- [IM SDK] 新增 `EMRecallMessageInfo#conversationId` 属性,在撤回消息的 `messagesInfoDidRecall` 事件中[返回被撤回的消息所属的会话 ID](message_recall.html#设置消息撤回监听)
diff --git a/docs/document/react-native/connection.md b/docs/document/react-native/connection.md
new file mode 100644
index 000000000..e7b75f2f3
--- /dev/null
+++ b/docs/document/react-native/connection.md
@@ -0,0 +1,80 @@
+# 连接
+
+应用客户端成功连接到环信服务器后,才能使用环信即时通讯 SDK 的收发消息等功能。
+
+你调用 `login` 方法登录后,客户端 SDK 会自动连接环信服务器。关于登录详情,请参见[登录文档](login.html)。
+
+## 监听连接状态
+
+你可以通过注册连接监听确认连接状态。
+
+```typescript
+ChatClient.getInstance().addConnectionListener({
+ onConnected(): void {
+ console.log("onConnected");
+ },
+ onDisconnected(): void {
+ console.log("onDisconnected");
+ },
+ onAppActiveNumberReachLimit(): void {
+ console.log("onAppActiveNumberReachLimit");
+ },
+
+ onUserDidLoginFromOtherDevice(deviceName?: string): void {
+ console.log("onUserDidLoginFromOtherDevice", deviceName);
+ },
+
+ onUserDidLoginFromOtherDeviceWithInfo(params: {
+ deviceName?: string;
+ ext?: string;
+ }): void {
+ console.log("onUserDidLoginFromOtherDeviceWithInfo", params);
+ },
+
+ onUserDidRemoveFromServer(): void {
+ console.log("onUserDidRemoveFromServer");
+ },
+
+ onUserDidForbidByServer(): void {
+ console.log("onUserDidForbidByServer");
+ },
+
+ onUserDidChangePassword(): void {
+ console.log("onUserDidChangePassword");
+ },
+
+ onUserDidLoginTooManyDevice(): void {
+ console.log("onUserDidLoginTooManyDevice");
+ },
+
+ onUserKickedByOtherDevice(): void {
+ console.log("onUserKickedByOtherDevice");
+ },
+
+ onUserAuthenticationFailed(): void {
+ console.log("onUserAuthenticationFailed");
+ },
+
+ onOfflineMessageSyncFinish(): void {
+ console.log("onOfflineMessageSyncFinish");
+ },
+
+ onOfflineMessageSyncStart(): void {
+ console.log("onOfflineMessageSyncStart");
+ },
+} as ChatConnectEventListener);
+```
+
+## 自动重连
+
+登录后,如果由于网络信号弱、切换网络等引起的连接中断,SDK 会自动尝试重连。重连成功或者失败时分别会收到 `onConnected` 和 `onDisconnected` 通知。
+
+不过,SDK 在以下情况下会停止自动重连。你需要调用 `login` 方法登录。
+
+- 用户调用了 SDK 的登出方法 `logout` 主动退出登录。
+- 登录时鉴权错误,例如, token 无效(错误码 104)或已过期(错误码 108)。
+- 用户在其他的设备上更改了密码,导致此设备上自动登录失败,提示错误码 216。
+- 用户的账号被从服务器端删除,提示错误码 207。
+- 用户在另一设备登录,将当前设备上登录的用户踢出,提示错误码 206。
+- 用户登录设备数量超过限制,提示错误码 214。
+- 应用程序的日活跃用户数量(DAU)或月活跃用户数量(MAU)达到上限,提示错误码 8。
diff --git a/docs/document/react-native/conversation_receipt.md b/docs/document/react-native/conversation_receipt.md
new file mode 100644
index 000000000..9f5b4fda4
--- /dev/null
+++ b/docs/document/react-native/conversation_receipt.md
@@ -0,0 +1,74 @@
+# 会话已读回执
+
+会话已读回执指接收方进入会话页面,阅读会话中的所有消息后,调用接口向服务器发送会话已读回执,服务器将该回执回调给消息发送方,消息发送方将会收到会话已读回调。在多端多设备登录下,接收方的其他设备也会收到该回调。
+
+目前,单聊和群组聊天支持会话已读回执。本文介绍如何使用环信即时通讯 IM RN SDK 实现会话已读回执功能。
+
+会话已读回执的效果示例,如下图所示:
+
+
+
+## 技术原理
+
+单聊会话已读回执实现的流程如下:
+
+1. 设置 `ChatOptions#requireAck` 为 `true` 开启已读回执功能。
+2. 消息接收方进入会话页面,阅读消息后,调用 `markAllMessagesAsRead` 方法发送会话已读回执。
+3. 消息发送方通过监听 `onConversationHasRead` 回调接收会话已读回执。
+
+## 前提条件
+
+开始前,请确保满足以下条件:
+
+- 完成 SDK 初始化,并连接到服务器,详见 [快速开始](quickstart.html)。
+- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。
+
+## 实现方法
+
+参考以下步骤在单聊中实现会话已读回执:
+
+1. 开启已读回执功能,即 SDK 初始化时设置 `ChatOptions#requireAck` 为 `true`。
+
+```typescript
+// 设置是否需要接受方已读确认,默认为 true
+options.requireAck = true;
+```
+
+2. 接收方发送会话已读回执。
+
+消息接收方进入会话页面,查看会话中是否有未读消息。若有,调用 `markAllMessagesAsRead` 方法发送会话已读回执,没有则不发送。该方法为异步方法,需要捕捉异常。
+
+若会话中存在多条未读消息,建议调用该方法,因为若调用发送消息已读回执方法 `ackMessageRead`,则需要调用多次。
+
+```typescript
+const convId = ""; // 会话ID。
+const convType = 0; // 会话类型。单聊。
+ChatClient.getInstance()
+ .chatManager.markAllMessagesAsRead(convId, convType)
+ .then(() => {
+ console.log("markAllMessagesAsRead success");
+ })
+ .catch((e) => {
+ console.log(e);
+ });
+```
+
+3. 消息发送方监听会话已读回执的回调。
+
+同一用户 ID 登录多设备的情况下,用户在一台设备上发送会话已读回执,其他设备会收到 `onConversationHasRead` 回调。
+
+:::tip
+对于群组聊天,会话已读回执只用于清空服务端的群组会话的未读数,消息发送方不会通过 `onConversationHasRead` 回调收到会话已读回执。
+:::
+
+```typescript
+ChatClient.getInstance().chatManager.addMessageListener({
+ onConversationRead: (from: string, to?: string) => {
+ console.log(`onConversationRead: `, from, to);
+ },
+});
+```
+
+## 会话已读回执和消息未读数
+
+消息接收方调用 `markAllMessagesAsRead` 方法发送会话已读回执,开发者可调用 `ChatConversation#markAllMessagesAsRead` 方法将所有未读消息设置为已读,即将该会话的未读消息数清零。
diff --git a/docs/document/react-native/group_attributes.md b/docs/document/react-native/group_attributes.md
index c21067291..5a9668295 100644
--- a/docs/document/react-native/group_attributes.md
+++ b/docs/document/react-native/group_attributes.md
@@ -17,7 +17,7 @@
开始前,请确保满足以下条件:
-- 完成 SDK 初始化,详见 [快速开始](quickstart.html) 及 [SDK 集成概述](overview.html)。
+- 完成 SDK 初始化,详见 [初始化](initialization.html)和[快速开始](quickstart.html)。
- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。
- 了解群组和群成员的数量限制,详见 [套餐包详情](https://www.easemob.com/pricing/im)。
diff --git a/docs/document/react-native/group_manage.md b/docs/document/react-native/group_manage.md
index cdc71e469..de253c6c0 100644
--- a/docs/document/react-native/group_manage.md
+++ b/docs/document/react-native/group_manage.md
@@ -21,7 +21,7 @@
开始前,请确保满足以下条件:
-- 完成 SDK 初始化,详见 [快速开始](quickstart.html) 及 [SDK 集成概述](overview.html)。
+- 完成 SDK 初始化,详见 [初始化](initialization.html)及[快速开始](quickstart.html)。
- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。
- 了解群组和群成员的数量限制,详见 [套餐包详情](https://www.easemob.com/pricing/im)。
diff --git a/docs/document/react-native/group_members.md b/docs/document/react-native/group_members.md
index ca043edcb..012ad8870 100644
--- a/docs/document/react-native/group_members.md
+++ b/docs/document/react-native/group_members.md
@@ -21,7 +21,7 @@
开始前,请确保满足以下条件:
-- 完成 SDK 初始化,详见 [快速开始](quickstart.html) 及 [SDK 集成概述](overview.html);
+- 完成 SDK 初始化,详见 [初始化](initialization.html)及[快速开始](quickstart.html);
- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html);
- 了解群成员角色,详见 [群组概述](group_overview.html);
- 了解群组和群成员的数量限制,详见 [套餐包详情](https://www.easemob.com/pricing/im)。
diff --git a/docs/document/react-native/initialization.md b/docs/document/react-native/initialization.md
new file mode 100644
index 000000000..f430dbbd7
--- /dev/null
+++ b/docs/document/react-native/initialization.md
@@ -0,0 +1,32 @@
+# SDK 初始化
+
+初始化是使用 SDK 的必要步骤,需在所有接口方法调用前完成。
+
+如果进行多次初始化操作,只有第一次初始化以及相关的参数生效。
+
+:::tip
+需要在主进程中进行初始化。
+:::
+
+## 前提条件
+
+有效的环信即时通讯 IM 开发者账号和 App key,详见[环信即时通讯云控制台的相关文档](enable_and_configure_IM.html#创建应用)。
+
+## 初始化
+
+初始化示例代码:
+
+```typescript
+ChatClient.getInstance()
+ .init(
+ new ChatOptions({
+ appKey: appKey,
+ }),
+ )
+ .then(() => {
+ console.log("init: success");
+ })
+ .catch((reason) => {
+ console.error(reason);
+ });
+```
diff --git a/docs/document/react-native/integration.md b/docs/document/react-native/integration.md
new file mode 100644
index 000000000..72a9e4fda
--- /dev/null
+++ b/docs/document/react-native/integration.md
@@ -0,0 +1,38 @@
+# 集成 SDK
+
+本文介绍如何将环信即时通讯 IM SDK 集成到你的 RN 项目。
+
+## 开发环境需求
+
+- React Native 0.66.5 or above
+- NodeJs 16 or above (Recommended 18 or above)
+
+## 集成到项目中
+
+打开终端,添加依赖到项目中
+
+```sh
+yarn add react-native-chat-sdk
+```
+
+or
+
+```sh
+npm i --save react-native-chat-sdk
+```
+
+## 添加权限
+
+目前需要基本的网络通讯权限。
+
+对于 ios 平台:内置网络权限。
+
+对于 android 平台:
+
+更新 `AndroidManifest.xml` 文件内容,增加需要的权限。
+
+```xml
+
+
+
+```
diff --git a/docs/document/react-native/log.md b/docs/document/react-native/log.md
new file mode 100644
index 000000000..e30f731e7
--- /dev/null
+++ b/docs/document/react-native/log.md
@@ -0,0 +1,10 @@
+
+# SDK 日志
+
+环信即时通讯 IM 日志记录 SDK 相关的信息和事件。环信技术支持团队帮你排查问题时可能会请你发送 SDK 日志。
+
+如果开启日志调试模式,会通过控制台输出 SDK 日志。`debugModel` 设置为 `true`。
+
+```typescript
+chatlog.log(`${ChatClient.TAG}: login: `, userName, "******", isPassword);
+```
diff --git a/docs/document/react-native/login.md b/docs/document/react-native/login.md
new file mode 100644
index 000000000..bfdfff55e
--- /dev/null
+++ b/docs/document/react-native/login.md
@@ -0,0 +1,95 @@
+# 登录
+
+初始化 IM SDK 后,你需要首先调用接口登录。登录成功后,才能使用 IM 的功能。
+
+## 用户注册
+
+用户注册模式分为以下两种:
+
+- 开放注册:一般在体验 Demo 和测试环境时使用,正式环境中不推荐使用该方式注册环信账号。要使用开放注册,需要在[环信即时通讯云控制台](https://console.easemob.com/user/login)的**即时通讯** > **服务概览**的**设置**区域,将**用户注册模式**设置为**开放注册**。只有打开该开关,才能使用客户端或 [REST API](/document/server-side/account_system.html#开放注册单个用户)开放注册用户。
+
+示例代码如下所示:
+
+```typescript
+ChatClient.getInstance()
+ .createAccount(username, password)
+ .then((value: any) => {
+ console.log("createAccount: success", value);
+ })
+ .catch((reason: any) => {
+ console.log("createAccount: fail", reason);
+ });
+```
+
+- 授权注册:通过环信提供的 REST API 注册环信用户账号,注册后保存到你的服务器或返给客户端。要使用授权注册,你需要在[环信即时通讯云控制台](https://console.easemob.com/user/login)的**即时通讯** > **服务概览**的**设置**区域,将**用户注册模式**设置为**授权注册**。相关的 REST API 介绍,详见[授权注册单个用户](/document/server-side/account_system.html#授权注册单个用户)和[批量授权注册用户](/document/server-side/account_system.html#批量授权注册用户)的接口介绍。
+
+除此以外,可以在[环信即时通讯云控制台](https://console.easemob.com/user/login)创建正式环境下和测试环境下的用户,详见[创建用户相关介绍](/product/enable_and_configure_IM.html#创建-im-用户)。
+
+## 主动登录
+
+测试环境下,你在[环信即时通讯云控制台](https://console.easemob.com/user/login)创建用户后,环信服务器会自动为这些用户分配用户 Token,详见[测试环境下创建用户的介绍](/product/enable_and_configure_IM.html#测试环境)。
+
+使用 token 登录时需要处理 token 过期的问题,比如在每次登录时更新 token 等机制。
+
+```typescript
+// userId: 用户ID
+// userPassword: 用户密码或者token
+// isPassword: 是否使用密码
+ChatClient.getInstance()
+ .login(userId, userPassword, isPassword)
+ .then(() => {
+ console.log("login success.");
+ })
+ .catch((error) => {
+ console.log("login fail: ", error);
+ });
+```
+
+## 自动登录
+
+初始化时,你可以设置 `ChatOptions#autoLogin` 选项确定是否自动登录。如果设置为自动登录,则登录成功之后,后续初始化 SDK 时会自动登录。
+
+## 获取当前登录的用户
+
+你可以调用 `ChatClient#getCurrentUsername` 方法获取当前登录用户的用户 ID。
+
+## 获取登录状态
+
+你可以调用 `ChatClient#isLoginBefore` 方法获取当前用户的登录状态。
+
+## 退出登录
+
+你可以调用 `logout` 方法退出登录。退出登录后,你不会再收到其他用户发送的消息。
+
+```typescript
+// unbindDeviceToken: 是否基础推送token绑定
+ChatClient.getInstance()
+ .logout(unbindDeviceToken)
+ .then(() => {
+ console.log("logout: success.");
+ })
+ .catch((e) => {
+ console.log(e);
+ });
+```
+
+:::tip
+
+1. 如果集成了第三方推送,`logout` 方法中 `unbindDeviceToken` 参数需设为 `true`,退出时会解绑设备 token,否则可能会出现退出了,还能收到消息推送通知的现象。
+2. 有时可能会遇到网络问题而解绑失败,app 处理时可以弹出提示框让用户选择,是否继续退出(弹出框提示继续退出能收到消息的风险),如果用户选择继续退出,传 `false` 再调用 `logout` 方法退出成功。当然也可以失败后还是返回退出成功,然后在后台起个线程不断调用 `logout` 方法直到成功。这样存在风险,即用户杀掉了 app,网络恢复后用户还会继续收到消息。
+
+## 账号切换
+
+若在 app 中从当前账号切换到其他账号,你需要首先调用 `logout` 方法登出,然后再调用 `login` 方法登录。
+
+## 多设备登录
+
+除了单端单设备登录,环信即时通讯 IM 支持同一账号在多端的多个设备上登录。多设备登录时,若同端设备数量超过限制,新登录的设备会将之前登录的设备踢下线。
+
+关于多设备登录场景中的设备数量限制、互踢策略以及信息同步,详见[多设备登录文档](multi_device.html)。
+
+## 更多
+
+### 登录被封禁账号的提示
+
+在环信即时通讯控制台或调用 REST API 封禁用户账号后,若仍使用该账号登录,SDK 会返回 "service is disabled"(305 错误), 可以根据用户这个返回值来进行相应的提示或者处理。
diff --git a/docs/document/react-native/message_delete.md b/docs/document/react-native/message_delete.md
index ecdaadf18..866d60719 100644
--- a/docs/document/react-native/message_delete.md
+++ b/docs/document/react-native/message_delete.md
@@ -18,7 +18,7 @@
开始前,请确保满足以下条件:
-- 完成 SDK 初始化,并连接到服务器,详见 [快速开始](quickstart.html) 及 [SDK 集成概述](overview.html)。
+- 完成 SDK 初始化,并连接到服务器,详见 [初始化](initialization.html)及[连接](connection.html)文档。
- 了解环信即时通讯 IM API 的使用限制,详见 [使用限制](/product/limitation.html)。
## 实现方法
diff --git a/docs/document/react-native/message_import_insert.md b/docs/document/react-native/message_import_insert.md
index c0a0ffcbb..25ad6b436 100644
--- a/docs/document/react-native/message_import_insert.md
+++ b/docs/document/react-native/message_import_insert.md
@@ -14,7 +14,7 @@
开始前,请确保满足以下条件:
-- 完成 SDK 初始化,并连接到服务器,详见 [快速开始](quickstart.html) 及 [SDK 集成概述](overview.html)。
+- 完成 SDK 初始化,并连接到服务器,详见 [初始化](initialization.html)及[连接](connection.html)文档。
- 了解环信即时通讯 IM API 的使用限制,详见 [使用限制](/product/limitation.html)。
## 实现方法
diff --git a/docs/document/react-native/message_modify.md b/docs/document/react-native/message_modify.md
index 9ac328bb4..8226e81f3 100644
--- a/docs/document/react-native/message_modify.md
+++ b/docs/document/react-native/message_modify.md
@@ -27,7 +27,7 @@
开始前,请确保满足以下条件:
-- 完成 SDK 初始化,并连接到服务器,详见 [快速开始](quickstart.html) 及 [SDK 集成概述](overview.html)。
+- 完成 SDK 初始化,并连接到服务器,详见 [初始化](initialization.html)及[连接](connection.html)文档。
- 了解环信即时通讯 IM API 的使用限制,详见 [使用限制](/product/limitation.html)。
## 实现方法
diff --git a/docs/document/react-native/message_receipt.md b/docs/document/react-native/message_receipt.md
index 0a521a644..8550dec6c 100644
--- a/docs/document/react-native/message_receipt.md
+++ b/docs/document/react-native/message_receipt.md
@@ -1,339 +1,235 @@
-# 消息回执
+# 实现消息回执
-单聊会话支持消息送达回执、会话已读回执和消息已读回执,发送方发送消息后可及时了解接收方是否及时收到并阅读了信息,也可以了解整个会话是否已读。
-群聊会话只支持消息已读回执。群成员在发送消息时,可以设置该消息是否需要已读回执。仅专业版及以上版本支持群消息已读回执功能。若要使用该功能,需在[环信即时通讯云控制台](https://console.easemob.com/user/login)开通,具体费用详见[产品价格](/product/pricing.html#增值服务费用)。
+**单聊会话支持消息送达回执和消息已读回执**,发送方发送消息后可及时了解接收方是否及时收到并阅读了消息。
-:::tip
-仅单聊消息支持送达回执,群聊消息不支持。
-:::
+**群聊会话只支持消息已读回执,不支持送达回执**。群成员在发送消息时,可以设置该消息是否需要已读回执。要使用该功能,你需要[在环信即时通讯云控制台上开通该功能](/product/enable_and_configure_IM.html#设置群消息已读回执),具体费用详见[产品价格](/product/pricing.html#增值服务费用)。
-本文介绍如何使用环信即时通讯 IM React Native SDK 实现单聊和群聊的消息回执功能。
+消息送达回执和已读回执的效果示例,如下图所示:
+
+
## 技术原理
-环信即时通讯 IM React Native SDK 通过 `ChatManager` 类提供消息的送达回执和已读回执功能:
+使用环信即时通讯 IM RN SDK 可以实现消息的送达回执与已读回执。
+
+- 单聊消息送达回执的逻辑如下:
+
+ 1. 你可以通过设置 `ChatOptions#requireDeliveryAck` 为 `true` 开启送达回执功能。
+ 2. 消息接收方收到消息后,SDK 自动向发送方触发送达回执。
+ 3. 消息发送方通过监听 `ChatMessageEventListener#onMessagesDelivered` 回调接收消息送达回执。
+
+- 单聊消息已读回执的逻辑如下:
-- 消息送达回执
-- 消息和会话的已读回执
-- 群聊已读回执
-- 获取群组已读回执信息
-- 获取群组已读回执数目
+ 1. 你可以通过设置 `ChatOptions#requireAck` 为 `true` 开启已读回执功能。
+ 2. 消息接收方收到消息后,调用 `ChatManager#markMessageAsRead` 方法发送消息已读回执。
+ 3. 消息发送方通过监听 `ChatMessageEventListener#onMessagesRead` 回调接收消息已读回执。
-实现送达和已读回执的逻辑分别如下:
+- 群聊消息已读回执的逻辑如下:
-- 单聊消息送达回执
- 1. 消息发送方在发送消息前通过 `ChatOptions.requireDeliveryAck` 开启送达回执功能。
- 2. 消息接收方收到消息后,SDK 自动向发送方触发送达回执。
- 3. 消息发送方通过监听 `onMessageDelivered` 回调接收消息送达回执。
-- 单聊会话及消息已读回执
- 1. 消息发送方在发送消息前通话 `ChatOptions.requireAck` 开启已读回执功能。
- 2. 消息接收方收到或阅读消息后,调用 API `ChatManager.sendConversationReadAck` 或 `ChatManager.sendMessageReadAck` 发送会话或消息已读回执。
- 3. 消息发送方通过监听 `onConversationRead` 或 `onMessageRead` 回调接收会话或消息已读回执。
-- 群聊只支持消息已读回执:
- 1. 你可以通过设置 `ChatOptions.NeedGroupAck` 为 `true` 开启群聊消息已读回执功能;
- 2. 消息接收方收到或阅读消息后通过 `ChatManager.sendGroupMessageReadAck` 发送群组消息的已读回执。
+ 1. 你可以通过设置 `ChatOptions#requireAck` 为 `true` 开启消息已读回执功能。
+ 2. 发送方在群组中发送消息时设置 `ChatMessage#needGroupAck` 为 `true` 要求接收方返回消息已读回执。
+ 3. 接收方收到或阅读消息后通过 `ChatManager#markMessageAsRead` 方法发送群组消息的已读回执。
## 前提条件
开始前,请确保满足以下条件:
-- 完成 SDK 初始化,并连接到服务器,详见 [快速开始](quickstart.html) 及 [SDK 集成概述](overview.html)。
+- 完成 SDK 初始化,并连接到服务器,详见 [快速开始](quickstart.html)。
- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。
-- 群消息已读回执功能仅在环信 IM 专业版及以上版本支持该功能。若要使用该功能,需在[环信即时通讯云控制台](https://console.easemob.com/user/login)开通,具体费用详见[产品价格](/product/pricing.html#增值服务费用)。
+- 要使用群消息已读回执功能,需在[环信即时通讯云控制台](https://console.easemob.com/user/login)开通,具体费用详见[产品价格](/product/pricing.html#增值服务费用)。
## 实现方法
-### 消息送达回执
+### 单聊消息送达回执
-1. 发送方开启全局送达回执。当接收方收到消息后,SDK 底层会自动进行消息送达回执。
+1. 开启消息送达功能,即 SDK 初始化时将 `ChatOptions#requireDeliveryAck` 设置为 `true`。
```typescript
-// 设置 app key
-const appKey = "appKey";
-// 开启消息送达回执
-const requireDeliveryAck = true;
-ChatClient.getInstance()
- .init(
- new ChatOptions({
- appKey,
- requireDeliveryAck,
- })
- )
- .then(() => {
- console.log("init sdk success");
- })
- .catch((reason) => {
- console.log("init sdk fail.", reason);
- });
+// 设置是否需要接收方送达确认,默认 `false` 即不需要。
+options.requireDeliveryAck = true;
```
-2. 发送方监听事件 `onMessagesDelivered` 回调,收到接收方的送达回执。
+2. 接收方收到消息后,SDK 自动向发送方触发送达回执。
+
+3. 发送方监听 `ChatMessageEventListener#onMessagesDelivered` 事件,收到接收方的送达回执。你可以在收到该通知时,显示消息的送达状态。
```typescript
-class ChatMessageEvent implements ChatMessageEventListener {
- onMessagesDelivered(messages: ChatMessage[]): void {
- console.log(`onMessagesDelivered: `, messages);
- }
- // ...
-}
-// 添加监听器
-const listener = new ChatMessageEvent();
-ChatClient.getInstance().chatManager.addMessageListener(listener);
+ChatClient.getInstance().chatManager.addMessageListener({
+ onMessagesDelivered: (messages: ChatMessage[]) => {
+ console.log(`onMessagesDelivered:`, messages);
+ },
+});
```
-### 消息和会话的已读回执
+### 单聊消息已读回执
-消息已读回执用于告知单聊或群聊中的用户接收方已阅读其发送的消息。为降低消息已读回执方法的调用次数,SDK 还支持在单聊中使用会话已读回执功能,用于获知接收方是否阅读了会话中的未读消息。
+单聊既支持单条消息已读回执,也支持[会话已读回执](conversation_receipt.html)。我们建议你结合使用这两种回执,见实现步骤的描述。
-#### 单聊
+单聊消息的已读回执有效期与消息在服务端的存储时间一致,即在服务器存储消息期间均可发送已读回执。消息在服务端的存储时间与你订阅的套餐包有关,详见[产品价格](/product/pricing.html#套餐包功能详情)。
-单聊既支持消息已读回执,也支持会话已读回执。我们建议你按照如下逻辑结合使用两种回执结合使用,减少发送消息已读回执数量。
+参考如下步骤在单聊中实现消息已读回执。
-- 聊天页面未打开时,若有未读消息,进入聊天页面,发送会话已读回执;
-- 聊天页面打开时,若收到消息,发送消息已读回执。
+1. App 开启已读回执功能,即 SDK 初始化时将 `ChatOptions#requireAck` 设置为 `true`。
-##### 会话已读回执
+```typescript
+// 设置是否需要接受方已读确认,默认为true
+options.requireAck = true;
+```
-参考如下步骤在单聊中实现会话已读回执。
+2. 接收方发送消息已读回执。
-1. 开启全局的消息已读回执开关。如果全局设置不开启,消息和会话的相应设置也无法生效。
+- 聊天页面打开时,若收到消息,发送单条消息已读回执。
```typescript
-// 设置 app key
-const appKey = "appKey";
-// 开启消息已读回执
-const requireAck = true;
ChatClient.getInstance()
- .init(
- new ChatOptions({
- appKey,
- requireAck,
- requireDeliveryAck,
- })
- )
+ .chatManager.markAllMessagesAsRead(convId, convType)
.then(() => {
- console.log("init sdk success");
+ console.log("markAllMessagesAsRead success.");
})
- .catch((reason) => {
- console.log("init sdk fail.", reason);
+ .catch((e) => {
+ console.log("markAllMessagesAsRead fail.", e);
});
```
-2. 接收方执行会话已读回执操作。进入会话页面,查看会话中是否有未读消息。若有,发送会话已读回执,没有则不再发送。
+- 聊天页面未打开时,若有未读消息,进入聊天页面,发送会话已读回执。这种方式可避免发送多个消息已读回执。
```typescript
-// 会话 ID
-const convId = "convId";
-// 执行操作
-ChatClient.getInstance()
- .chatManager.sendConversationReadAck(convId)
- .then(() => {
- console.log("send conversation read success");
- })
- .catch((reason) => {
- console.log("send conversation read fail.", reason);
- });
+ChatClient.getInstance().chatManager.addMessageListener({
+ onMessagesReceived: (messages: ChatMessage[]) => {
+ console.log(`onMessagesReceived:`, messages);
+ for (const msg of messages) {
+ ChatClient.getInstance()
+ .chatManager.markMessageAsRead(convId, convType, msg.msgId)
+ .then(() => {
+ console.log("markMessageAsRead success.");
+ })
+ .catch((e) => {
+ console.log("markMessageAsRead fail.", e);
+ });
+ }
+ },
+});
```
-3. 发送方监听 `onConversationRead` 回调,接收会话已读回执。
+3. 消息发送方监听消息已读回调。
+
+消息发送方可以通过 `ChatMessageEventListener#onMessageRead` 事件监听指定消息是否已读,示例代码如下:
```typescript
-class ChatMessageEvent implements ChatMessageEventListener {
- onConversationRead(from: string, to?: string): void {
- console.log(`onConversationRead: `, from, to);
- }
- // ...
-}
-// 添加监听器
-const listener = new ChatMessageEvent();
-ChatClient.getInstance().chatManager.addMessageListener(listener);
+ChatClient.getInstance().chatManager.addMessageListener({
+ onMessagesRead: (messages: ChatMessage[]) => {
+ console.log(`onMessagesRead:`, messages);
+ },
+});
```
-> 同一用户 ID 登录多设备的情况下,用户在一台设备上发送会话已读回执,服务器会将会话的未读消息数置为 `0`,同时其他设备会收到 `onConversationRead` 回调。
+### 群聊消息已读回执
-##### 消息已读回执
+对于群聊,群成员发送消息时,可以设置该消息是否需要已读回执。若需要,每个群成员阅读消息后,应该调用`ChatManager#markMessageAsRead` 方法发送已读回执,阅读该消息的群成员数量即为已读回执的数量。
-单聊消息的已读回执有效期与消息在服务端的存储时间一致,即在服务器存储消息期间均可发送已读回执。消息在服务端的存储时间与你订阅的套餐包有关,详见[产品价格](/product/pricing.html#套餐包功能详情)。
+群消息已读回执特性的使用限制如下表所示:
-参考如下步骤在单聊中实现消息已读回执。
+| 使用限制 | 默认 | 描述 |
+| :------------------- | :--------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| 功能开通 | 关闭 | 若要使用该功能,你需要在[环信即时通讯云控制台](https://console.easemob.com/user/login)的**即时通讯** > **功能配置** > **功能配置总览**> **基础功能**页签下,搜索找到 **消息已读回执(群聊)** 开通功能。具体费用详见[产品价格](/product/pricing.html#增值服务费用)。 |
+| 使用权限 | 所有群成员 | 默认情况下,所有群成员发送消息时可要求已读回执。如果仅需群主和群管理员发消息时要求已读回执,可联系商务修改。 |
+| 已读回执有效期 | 3 天 | 群聊已读回执的有效期为 3 天,即群组中的消息发送时间超过 3 天,服务器不记录阅读该条消息的群组成员,也不会发送已读回执。 |
+| 群规模 | 200 人 | 该特性最大支持 200 人的群组。如果超过 200 人/群,群成员发送的消息不会返回已读回执。你可以联系商务提升群成员人数上限。 |
+| 查看返回已读回执数量 | 消息发送方 | 对消息返回的已读回执数量(或返回已读回执的人数),默认仅消息发送方可查看。如需所有群成员均可查看,可联系商务开通。 |
-1. 开启全局的消息已读回执开关。如果全局设置不开启,消息和会话的相应设置也无法生效。
+你可以按以下步骤实现群消息已读回执特性:
-```typescript
-// 设置 app key
-const appKey = "appKey";
-// 开启消息已读回执
-const requireAck = true;
-ChatClient.getInstance()
- .init(
- new ChatOptions({
- appKey,
- requireAck,
- requireDeliveryAck,
- })
- )
- .then(() => {
- console.log("init sdk success");
- })
- .catch((reason) => {
- console.log("init sdk fail.", reason);
- });
-```
+1. 开启已读回执功能,即 SDK 初始化时将 `ChatOptions#requireAck` 设置为 `true`。
-2. 消息发送方监听 `onMessagesRead` 事件。
+该功能开启后,接收方阅读消息后,SDK 底层会自动进行消息已读回执。
```typescript
-class ChatMessageEvent implements ChatMessageEventListener {
- onMessagesRead(messages: ChatMessage[]): void {
- // 收到消息已读
- console.log(`onMessagesRead: `, messages);
- }
- // ...
-}
-// 添加监听器
-const listener = new ChatMessageEvent();
-ChatClient.getInstance().chatManager.addMessageListener(listener);
+// 设置是否需要接受方已读确认,默认为 `true`。
+options.requireAck = true;
```
-3. 消息发送方发送消息,并等待接收方已读。
+2. 发送方发送消息时设置 `ChatMessage#needGroupAck` 属性为 `true`。
+
+与单聊消息的 app 层级设置已读回执功能不同,群聊消息是在发送消息时设置指定消息是否需要已读回执。
```typescript
-// 发送消息
-// 设置消息开启已读回执
-msg.hasReadAck = true;
-// 执行发送消息
-ChatClient.getInstance()
- .chatManager.sendMessage(msg)
- .then(() => {
- // 消息发送动作完成,会在这里打印日志。
- console.log("send message success.");
- })
- .catch((reason) => {
- // 消息发送动作失败,会在这里打印日志。
- console.log("send message fail.", reason);
- });
+const convId; // 会话ID。
+const content; // 会话内容。
+ChatMessage message = ChatMessage.createTextMessage(convId, content);
+message.needGroupAck = true;
```
-4. 接收方查看消息,并调用 `sendMessageReadAck` 方法告知发送方消息已读。成功调用后,消息发送方会收到 `onMessageRead` 回调。
+3. 消息接收方发送群组消息的已读回执。
```typescript
-// 接收的需要已读回执的消息
-const msg;
-// 执行发送已读回执操作
+const convId; // 会话ID。
+const convType; // 会话类型。群组为 1。
+const msgId; // 消息ID。
ChatClient.getInstance()
- .chatManager.sendMessageReadAck(msg)
+ .chatManager.markMessageAsRead(convId, convType, msgId)
.then(() => {
- console.log("send message read success");
+ console.log("markMessageAsRead success.");
})
- .catch((reason) => {
- console.log("send message read fail.", reason);
+ .catch((e) => {
+ console.log("markMessageAsRead fail.", e);
});
```
-### 群聊已读回执
-
-对于群聊,群成员发送消息时,可以设置该消息是否需要已读回执。若需要,每个群成员在阅读消息后,SDK 均会发送已读回执,即阅读该消息的群成员数量即为已读回执的数量。
-
-群消息已读回执特性的使用限制如下表所示:
-
-| 使用限制| 默认 | 描述 |
-| :--------- | :----- | :------- |
-| 功能开通 | 关闭 | 若要使用该功能,你需要在[环信即时通讯云控制台](https://console.easemob.com/user/login)的**即时通讯** > **功能配置** > **功能配置总览**> **基础功能**页签下,搜索找到 **消息已读回执(群聊)** 开通功能。具体费用详见[产品价格](/product/pricing.html#增值服务费用)。 |
-| 使用权限 | 所有群成员 | 默认情况下,所有群成员发送消息时可要求已读回执。如果仅需群主和群管理员发消息时要求已读回执,可联系商务修改。 |
-| 已读回执有效期 | 3 天 | 群聊已读回执的有效期为 3 天,即群组中的消息发送时间超过 3 天,服务器不记录阅读该条消息的群组成员,也不会发送已读回执。 |
-| 群规模 | 200 人 | 该特性最大支持 200 人的群组。如果超过 200 人/群,群成员发送的消息不会返回已读回执。你可以联系商务提升群成员人数上限。 |
-| 查看返回已读回执数量 | 消息发送方 | 对消息返回的已读回执数量(或返回已读回执的人数),默认仅消息发送方可查看。如需所有群成员均可查看,可联系商务开通。 |
+4. 消息发送方监听群组消息已读回调。
-你可以按以下步骤实现群消息已读回执特性:
+群消息已读回调在 `ChatMessageEventListener#onGroupMessageRead` 中实现。
-1. 消息发送方需要知道群组消息是否已读,需要监听 `onGroupMessageRead` 事件。
+发送方接收到群组消息已读回执后,其发出消息的属性 `ChatMessage#groupAckCount` 会有相应变化。
```typescript
-class ChatMessageEvent implements ChatMessageEventListener {
- onGroupMessageRead(groupMessageAcks: ChatGroupMessageAck[]): void {
- // 收到消息已读
- console.log(`onGroupMessageRead: `, messages);
- }
- // ...
-}
-// 添加监听器
-const listener = new ChatMessageEvent();
-ChatClient.getInstance().chatManager.addMessageListener(listener);
+ChatClient.getInstance().chatManager.addMessageListener({
+ onGroupMessageRead: (messages: ChatMessage[]) => {
+ console.log(`onGroupMessageRead:`, messages);
+ },
+});
```
-2. 发送群组消息。并设置 `needGroupAck` 为 `true`,表示需要群组消息已读回执。
+5. 消息发送方获取群组消息的已读回执详情。
+
+你可以调用 `ChatManager#fetchGroupAcks` 方法从服务器获取单条消息的已读回执的详情。
```typescript
-// 发送群组消息
-// 设置本条消息需要群消息回执
-msg.needGroupAck = true;
-// 执行发送消息
+const msgId; // 消息ID。
+const groupId; // 群组ID。
+const startAckId; //回执ID。
+const pageSize; // 每页信息。
ChatClient.getInstance()
- .chatManager.sendMessage(msg)
- .then(() => {
- // 消息发送动作完成,会在这里打印日志。
- console.log("send message success.");
+ .chatManager.fetchGroupAcks(msgId, groupId, startAckId, pageSize)
+ .then((result) => {
+ console.log("fetchGroupAcks success.", result);
})
- .catch((reason) => {
- // 消息发送动作失败,会在这里打印日志。
- console.log("send message fail.", reason);
+ .catch((e) => {
+ console.log("fetchGroupAcks fail.", e);
});
```
-3. 群组里面的接收方收到消息,调用 `sendGroupMessageReadAck` 方法告知消息发送方消息已读。成功发送后,消息发送方会收到 `onMessageRead` 回调。
+### 查看消息送达和已读状态
-```typescript
-// 发送已读回执
-// 需要设置消息已读的 ID
-const msgId;
-// 指定群组
-const groupId;
-// 执行已读回执
-ChatClient.getInstance()
- .chatManager.sendGroupMessageReadAck(msgId, groupId)
- .then(() => {
- // 消息发送动作完成,会在这里打印日志。
- console.log("send message read success.");
- })
- .catch((reason) => {
- // 消息发送动作失败,会在这里打印日志。
- console.log("send message read fail.", reason);
- });
-```
+对于单聊消息,本地通过 `ChatMessage#hasDeliverAck` 字段存储消息送达状态。
-### 获取群组已读回执信息
+对于单聊消息,本地通过以下字段存储消息已读状态:
-所有用户可以调用 `fetchGroupAcks` 方法获取指定范围的群组消息的已读回执。
+| 字段 | 描述 |
+| :--------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `ChatMessage#hasRead` | 用户是否已读了该消息。如果是自己发送的消息,该字段的值固定为 `true`。 |
+| `ChatMessage#hasReadAck` | 是否(消息接收方)已发送或(消息发送方)已收到消息已读回执。如果是自己发送的消息,记录的是对方是否已读。如果是对方的消息,则记录的是自己是否发送过已读回执。 |
-```typescript
-// msgId: 消息 ID
-// groupId:群组 ID
-// startAckId: 查询起始的已读回执 ID。首次调用为空,SDK 从最新的已读回执开始按服务器接收回执时间的逆序获取。后续调用从 ChatCursorResult 中的 cursor 获取。
-// pageSize:期望请求的最大数量,取值范围是 0-400
-ChatClient.getInstance()
- .chatManager.fetchGroupAcks(msgId, groupId, startAckId, pageSize)
- .then((acks) => {
- console.log("get message ack success: ", acks);
- })
- .catch((reason) => {
- console.log("get message ack fail.", reason);
- });
-```
+对于群聊消息,本地数据库通过以下字段存储消息已读状态:
-### 获取群组已读回执数目
+| 字段 | 描述 |
+| :-------------------------- | :-------------------------------------------------------------------- |
+| `ChatMessage#hasRead` | 用户是否已读了该消息。如果是自己发送的消息,该字段的值固定为 `true`。 |
+| `ChatMessage#groupAckCount` | 已阅读消息的群成员数量。 |
-所有用户可以调用 `groupAckCount` 方法通过消息 ID 找到消息,在通过消息获取群组已读回执数量。
+### 已读回执与未读消息数
-```typescript
-// msgId: 消息 ID
-ChatClient.getInstance()
- .chatManager.groupAckCount(msgId)
- .then((count) => {
- console.log("get message ack count success: ", count);
- })
- .catch((reason) => {
- console.log("get message ack count fail.", reason);
- });
-```
\ No newline at end of file
+- 会话已读回执发送后,开发者需要调用 `ChatConversation#markAllMessagesAsRead` 方法将该会话的所有消息置为已读,即会话的未读消息数清零。
+
+- 消息已读回执发送后,开发者需要调用 `ChatConversation#markMessageAsRead` 方法将该条消息置为已读,则消息未读数会有变化。
diff --git a/docs/document/react-native/message_retrieve.md b/docs/document/react-native/message_retrieve.md
index 7f825a001..a30d6c02e 100644
--- a/docs/document/react-native/message_retrieve.md
+++ b/docs/document/react-native/message_retrieve.md
@@ -25,7 +25,7 @@
开始前,请确保满足以下条件:
-- 完成 SDK 初始化,并连接到服务器,详见 [快速开始](quickstart.html) 及 [SDK 集成概述](overview.html)。
+- 完成 SDK 初始化,并连接到服务器,详见 [初始化](initialization.html)及[连接](connection.html)文档。
- 了解环信即时通讯 IM API 的使用限制,详见 [使用限制](/product/limitation.html)。
## 实现方法
diff --git a/docs/document/react-native/message_search.md b/docs/document/react-native/message_search.md
index 8f671a758..610832b43 100644
--- a/docs/document/react-native/message_search.md
+++ b/docs/document/react-native/message_search.md
@@ -17,7 +17,7 @@
开始前,请确保满足以下条件:
-- 完成 SDK 初始化,并连接到服务器,详见 [快速开始](quickstart.html) 及 [SDK 集成概述](overview.html)。
+- 完成 SDK 初始化,并连接到服务器,详见 [初始化](initialization.html)及[连接](connection.html)文档。
- 了解环信即时通讯 IM API 的使用限制,详见 [使用限制](/product/limitation.html)。
## 实现方法
diff --git a/docs/document/react-native/message_translation.md b/docs/document/react-native/message_translation.md
index 7e2d76d1e..5b563582d 100644
--- a/docs/document/react-native/message_translation.md
+++ b/docs/document/react-native/message_translation.md
@@ -11,7 +11,7 @@
开始前,请确保满足以下条件:
-1. 完成 SDK 初始化,详见 [快速开始](quickstart.html) 及 [SDK 集成概述](overview.html)。
+1. 完成 SDK 初始化,详见 [初始化](initialization.html)文档。
2. 了解环信即时通讯 IM API 的 [使用限制](/product/limitation.html)。
3. 已在 [环信即时通讯云控制台](https://console.easemob.com/user/login) 开通翻译功能。
4. 该功能由 Microsoft Azure Translation API 提供,因此开始前请确保你了解该功能支持的目标语言。详见 [翻译语言支持](https://learn.microsoft.com/zh-cn/azure/ai-services/translator/language-support)。
diff --git a/docs/document/react-native/message_update.md b/docs/document/react-native/message_update.md
index 8998d40d8..12d233777 100644
--- a/docs/document/react-native/message_update.md
+++ b/docs/document/react-native/message_update.md
@@ -14,7 +14,7 @@
开始前,请确保满足以下条件:
-- 完成 SDK 初始化,并连接到服务器,详见 [快速开始](quickstart.html) 及 [SDK 集成概述](overview.html)。
+- 完成 SDK 初始化,并连接到服务器,详见 [初始化](initialization.html)及[连接](connection.html)文档。
- 了解环信即时通讯 IM API 的使用限制,详见 [使用限制](/product/limitation.html)。
## 实现方法
diff --git a/docs/document/react-native/moderation.md b/docs/document/react-native/moderation.md
index 2f85a408c..258296781 100644
--- a/docs/document/react-native/moderation.md
+++ b/docs/document/react-native/moderation.md
@@ -19,7 +19,7 @@
开始前,请确保满足以下条件:
-1. 完成 SDK 初始化,详见 [快速开始](quickstart.html) 及 [SDK 集成概述](overview.html)。
+1. 完成 SDK 初始化,详见 [初始化](initialization.html)文档。
2. 了解环信即时通讯 IM API 的 [使用限制](/product/limitation.html)。
3. 已在 [环信即时通讯云控制台开通消息举报功能](/product/enable_and_configure_IM.html#消息举报)。
diff --git a/docs/document/react-native/multi_device.md b/docs/document/react-native/multi_device.md
index f9c324690..8c882773f 100644
--- a/docs/document/react-native/multi_device.md
+++ b/docs/document/react-native/multi_device.md
@@ -51,7 +51,7 @@
## 前提条件
-开始前,请确保满足完成 SDK 初始化,并连接到服务器,详见 [快速开始](quickstart.html) 及 [SDK 集成概述](overview.html)。
+开始前,请确保满足完成 SDK 初始化,并连接到服务器,详见 [初始化](initialization.html)及[连接](connection.html)文档。
## 实现方法
@@ -110,7 +110,7 @@ ChatClient.getInstance()
即时通讯 IM 自 1.2.0 版本开始支持自定义设置登录设备的名称。这样在多设备场景下,若有设备被踢下线,你就能知道是被哪个设备挤下线的。设备名称 `deviceName` 可以通过 `getLoggedInDevicesFromServer` 返回对象 `ChatDeviceInfo` 获取。如果没有设置则返回默认值,即设备型号。
-:::notice
+:::tip
登录成功后才会将该设置发送到服务器。
:::
@@ -145,7 +145,7 @@ ChatClient.getInstance()
2. 初始化 SDK。确保该方法中的 `customOSType` 参数的值与环信控制台的**添加自定义平台**对话框中设置的**设备平台**的值相同。
-:::notice
+:::tip
登录成功后才会将该设置发送到服务器。
:::
@@ -172,7 +172,7 @@ ChatClient.getInstance()
初始化 SDK 时,你可以利用 `ChatOptions#loginExtraInfo` 属性设置登录设备的自定义扩展信息。设置后,若因达到了登录设备数量限制而导致在已登录的设备上强制退出时(`206` 错误,Android 为 `USER_LOGIN_ANOTHER_DEVICE`,iOS 为 `EMErrorUserLoginOnAnotherDevice`),被踢设备收到的 `ChatConnectEventListener#onUserDidLoginFromOtherDeviceWithInfo` 回调会包含导致该设备被踢下线的新登录设备的自定义扩展信息。
-:::notice
+:::tip
登录成功后才会将该设置发送到服务器。
:::
diff --git a/docs/document/react-native/presence.md b/docs/document/react-native/presence.md
index ca635a863..efe716895 100644
--- a/docs/document/react-native/presence.md
+++ b/docs/document/react-native/presence.md
@@ -36,7 +36,7 @@
使用在线状态功能前,请确保满足以下条件:
-1. 完成 `1.0.5 或以上版本` SDK 初始化,详见 [快速开始](quickstart.html) 及 [SDK 集成概述](overview.html)。
+1. 完成 `1.0.5 或以上版本` SDK 初始化,详见 [初始化](initialization.html)文档。
2. 了解环信即时通讯 IM API 的 [使用限制](/product/limitation.html)。
3. 已联系商务开通在线状态订阅功能。
diff --git a/docs/document/react-native/reaction.md b/docs/document/react-native/reaction.md
index 9c9be58a7..5ea4cb591 100644
--- a/docs/document/react-native/reaction.md
+++ b/docs/document/react-native/reaction.md
@@ -23,7 +23,7 @@ Reaction 场景示例如下:
开始前,请确保满足以下条件:
-1. 完成 `1.0.5 或以上版本` SDK 初始化,详见 [快速开始](quickstart.html) 及 [SDK 集成概述](overview.html)。
+1. 完成 `1.0.5 或以上版本` SDK 初始化,详见 [初始化](initialization.html)文档。
2. 了解环信即时通讯 IM API 的 [使用限制](/product/limitation.html)。
3. 已联系商务开通 Reaction 功能。
diff --git a/docs/document/react-native/releasenote.md b/docs/document/react-native/releasenote.md
index 03972894f..f6bf02f0d 100644
--- a/docs/document/react-native/releasenote.md
+++ b/docs/document/react-native/releasenote.md
@@ -7,7 +7,7 @@
### 新增特性
- 依赖的原生 SDK 升级到版本:iOS 4.11.0 和 Android 4.11.0。
-- 更新服务器连接状态监听器 `ChatConnectEventListener`,新增 `onOfflineMessageSyncStart` 和 `onOfflineMessageSyncFinish` 事件,表示[从服务器拉取离线消息的开始和结束](overview.html#连接状态相关)。
+- 更新服务器连接状态监听器 `ChatConnectEventListener`,新增 `onOfflineMessageSyncStart` 和 `onOfflineMessageSyncFinish` 事件,表示[从服务器拉取离线消息的开始和结束](connection.html)。
- 新增 `ChatManager#getMessageCount` 方法,用于获取数据库中的消息总数。
### 优化
@@ -37,7 +37,7 @@
### 优化
- 原生平台优化弱网服务器连接成功率。
-- 作废 `ChatConnectEventListener` 中的 `onUserDidLoginFromOtherDevice` 事件,由 [onUserDidLoginFromOtherDeviceWithInfo](overview.html#连接状态相关) 替代。
+- 作废 `ChatConnectEventListener` 中的 `onUserDidLoginFromOtherDevice` 事件,由 [onUserDidLoginFromOtherDeviceWithInfo](connection.html) 替代。
- 作废 `fetchHistoryMessages` 接口,由 [fetchHistoryMessagesByOptions](message_retrieve.html#从服务器获取指定会话的消息) 替代。
- 作废 `joinChatRoom` 接口,由 [joinChatRoomEx](room_manage.html#加入聊天室) 替代。
diff --git a/docs/document/react-native/room_attributes.md b/docs/document/react-native/room_attributes.md
index 9cd46841c..8380bcfea 100644
--- a/docs/document/react-native/room_attributes.md
+++ b/docs/document/react-native/room_attributes.md
@@ -19,7 +19,7 @@
开始前,请确保满足以下条件:
-- 完成 SDK 初始化,详见 [快速开始](quickstart.html) 及 [SDK 集成概述](overview.html)。
+- 完成 SDK 初始化,详见 [初始化](initialization.html)文档。
- 了解环信即时通讯 IM 的 [使用限制](/product/limitation.html)。
- 了解聊天室的数量限制,详见 [套餐包详情](https://www.easemob.com/pricing/im)。
diff --git a/docs/document/react-native/room_manage.md b/docs/document/react-native/room_manage.md
index 84869390f..f0a473819 100644
--- a/docs/document/react-native/room_manage.md
+++ b/docs/document/react-native/room_manage.md
@@ -23,7 +23,7 @@
开始前,请确保满足以下条件:
-- 完成 SDK 初始化,详见 [快速开始](quickstart.html) 及 [SDK 集成概述](overview.html)。
+- 完成 SDK 初始化,详见 [初始化](initialization.html)文档。
- 了解环信即时通讯 IM 的 [使用限制](/product/limitation.html)。
- 了解环信即时通讯 IM 不同版本的聊天室相关数量限制,详见 [环信即时通讯 IM 价格](https://www.easemob.com/pricing/im)。
- 只有超级管理员才有创建聊天室的权限,因此你还需要确保已调用 RESTful API 添加了超级管理员,详见 [添加聊天室超级管理员](/document/server-side/chatroom_superadmin.html)。
diff --git a/docs/document/react-native/room_members.md b/docs/document/react-native/room_members.md
index ee0226bbb..0a44097d1 100644
--- a/docs/document/react-native/room_members.md
+++ b/docs/document/react-native/room_members.md
@@ -20,7 +20,7 @@
开始前,请确保满足以下条件:
-- 完成 SDK 初始化,详见 [快速开始](quickstart.html) 及 [SDK 集成概述](overview.html)。
+- 完成 SDK 初始化,详见 [初始化](initialization.html)文档。
- 了解环信即时通讯 IM 的 [使用限制](/product/limitation.html)。
- 了解环信即时通讯 IM 聊天室相关限制,详见 [环信即时通讯 IM 价格](https://www.easemob.com/pricing/im)。
diff --git a/docs/document/react-native/thread.md b/docs/document/react-native/thread.md
index 857516fe8..490717968 100644
--- a/docs/document/react-native/thread.md
+++ b/docs/document/react-native/thread.md
@@ -22,7 +22,7 @@
开始前,请确保满足以下条件:
-- 完成 `1.0.5 或以上版本` SDK 初始化,详见 [快速开始](quickstart.html) 及 [SDK 集成概述](overview.html)。
+- 完成 `1.0.5 或以上版本` SDK 初始化,详见 [初始化](initialization.html)文档。
- 了解环信即时通讯 IM API 的 [使用限制](/product/limitation.html)。
- 了解子区和子区成员数量限制,详见 [使用限制](/product/limitation.html)。
- 联系商务开通子区功能。
diff --git a/docs/document/react-native/thread_message.md b/docs/document/react-native/thread_message.md
index 53aacbd73..dc3454a95 100644
--- a/docs/document/react-native/thread_message.md
+++ b/docs/document/react-native/thread_message.md
@@ -29,7 +29,7 @@
开始前,请确保满足以下条件:
-- 已集成 `1.0.5 或以上版本` SDK 的基本功能,完成 SDK 初始化,详见 [快速开始](quickstart.html) 及 [SDK 集成概述](overview.html)。
+- 已集成 `1.0.5 或以上版本` SDK 的基本功能,完成 SDK 初始化,详见 [初始化](initialization.html)文档。
- 了解即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。
- 联系商务开通子区功能。
diff --git a/docs/document/react-native/user_relationship.md b/docs/document/react-native/user_relationship.md
index 272a9cded..ab36cb353 100644
--- a/docs/document/react-native/user_relationship.md
+++ b/docs/document/react-native/user_relationship.md
@@ -29,7 +29,7 @@ SDK 提供用户关系管理功能,包括好友列表管理和黑名单管理
开始前,请确保满足以下条件:
-- 完成 SDK 初始化,并连接到服务器,详见 [快速开始](quickstart.html) 及 [SDK 集成概述](overview.html)。
+- 完成 SDK 初始化,并连接到服务器,详见 [初始化](initialization.html)文档。
- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。
## 实现方法
diff --git a/docs/document/react-native/userprofile.md b/docs/document/react-native/userprofile.md
index 234f158fa..16a5643aa 100644
--- a/docs/document/react-native/userprofile.md
+++ b/docs/document/react-native/userprofile.md
@@ -24,7 +24,7 @@
设置用户属性前,请确保满足以下条件:
-- 完成 SDK 初始化,详见 [快速开始](quickstart.html) 及 [SDK 集成概述](overview.html)。
+- 完成 SDK 初始化,详见 [初始化](initialization.html)文档。
- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。
## 实现方法
diff --git a/docs/document/unity/connection.md b/docs/document/unity/connection.md
new file mode 100644
index 000000000..2f06217e1
--- /dev/null
+++ b/docs/document/unity/connection.md
@@ -0,0 +1,83 @@
+# 连接
+
+应用客户端成功连接到环信服务器后,才能使用环信即时通讯 SDK 的收发消息等功能。
+
+你调用 `loginWithToken` 或 `login` 方法登录后,客户端 SDK 会自动连接环信服务器。关于登录详情,请参见[登录文档](login.html)。
+
+## 监听连接状态
+
+你可以通过注册连接监听确认连接状态。
+
+```csharp
+
+// 监听器建议在初始化完成之后,登录之前设置,这样可确保收到登录通知。
+class ConnectionDelegate : IConnectionDelegate
+{
+ public void OnConnected()
+ {
+ }
+ public void OnDisconnected()
+ {
+ }
+ public void OnAuthFailed()
+ {
+ }
+ public void OnRemovedFromServer()
+ {
+ }
+ public void OnLoginTooManyDevice()
+ {
+ }
+ public void OnChangedIMPwd()
+ {
+ }
+ public void OnKickedByOtherDevice()
+ {
+ }
+ public void OnLoggedOtherDevice(string deviceName)
+ {
+ }
+ public void OnForbidByServer()
+ {
+ }
+ public void OnTokenExpired()
+ {
+ }
+ public void OnTokenWillExpire()
+ {
+ }
+ public void OnAppActiveNumberReachLimitation()
+ {
+ }
+ // 连接成功,开始从服务器拉取离线消息时触发。
+ // 注意:如果本次登录服务器没有离线消息,不会触发该回调。
+ public void OnOfflineMessageSyncStart()
+ {
+ }
+ // 离线用户上线后从服务器拉取离线消息结束时触发。
+ // 注意:如果再拉取离线过程中因网络或其他原因导致连接断开,不会触发该回调。
+ public void OnOfflineMessageSyncFinish()
+ {
+ }
+}
+// 添加连接监听器
+ConnectionDelegate connectionDelegate = new ConnectionDelegate();
+SDKClient.Instance.AddConnectionDelegate(connectionDelegate);
+
+// 移除连接监听器(退出程序时建议移除)
+SDKClient.Instance.DeleteConnectionDelegate(connectionDelegate);
+```
+
+## 自动重连
+
+登录后,如果由于网络信号弱、切换网络等引起的连接中断,SDK 会自动尝试重连。重连成功或者失败时分别会收到 `onConnected` 和 `onDisconnected` 通知。
+
+不过,SDK 在以下情况下会停止自动重连。你需要调用 `login` 方法登录。
+
+- 用户调用了 SDK 的登出方法 `logout` 主动退出登录。
+- 登录时鉴权错误,例如, token 无效(错误码 104)或已过期(错误码 108)。
+- 用户在其他的设备上更改了密码,导致此设备上自动登录失败,提示错误码 216。
+- 用户的账号被从服务器端删除,提示错误码 207。
+- 用户在另一设备登录,将当前设备上登录的用户踢出,提示错误码 206。
+- 用户登录设备数量超过限制,提示错误码 214。
+- 应用程序的日活跃用户数量(DAU)或月活跃用户数量(MAU)达到上限,提示错误码 8。
\ No newline at end of file
diff --git a/docs/document/unity/conversation_receipt.md b/docs/document/unity/conversation_receipt.md
new file mode 100644
index 000000000..c12670254
--- /dev/null
+++ b/docs/document/unity/conversation_receipt.md
@@ -0,0 +1,79 @@
+# 会话已读回执
+
+会话已读回执指接收方进入会话页面,阅读会话中的所有消息后,调用接口向服务器发送会话已读回执,服务器将该回执回调给消息发送方,消息发送方将会收到会话已读回调。在多端多设备登录下,接收方的其他设备也会收到该回调。
+
+目前,单聊和群组聊天支持会话已读回执。本文介绍如何使用环信即时通讯 IM Unity SDK 实现会话已读回执功能。
+
+会话已读回执的效果示例,如下图所示:
+
+
+
+## 技术原理
+
+ 单聊会话已读回执实现的流程如下:
+
+ 1. 设置 `Options#RequireAck` 为 `true` 开启已读回执功能。
+ 2. 消息接收方进入会话页面,阅读消息后,调用 `SendConversationReadAck` 方法发送会话已读回执。
+ 3. 消息发送方通过监听 `OnConversationRead` 回调接收会话已读回执。
+
+## 前提条件
+
+开始前,请确保满足以下条件:
+
+- 完成 SDK 初始化,并连接到服务器,详见 [快速开始](quickstart.html)。
+- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。
+
+ ## 实现方法
+
+ 参考以下步骤在单聊中实现会话已读回执:
+
+ 1. 开启已读回执功能,即 SDK 初始化时设置 `Options#RequireAck` 为 `true`。
+
+ ```csharp
+// 设置是否需要接受方已读确认,默认为 true
+options.RequireAck = true;
+ ```
+
+ 2. 接收方发送会话已读回执。
+
+消息接收方进入会话页面,查看会话中是否有未读消息。若有,调用 `SendConversationReadAck` 方法发送会话已读回执,没有则不发送。该方法为异步方法。
+
+若会话中存在多条未读消息,建议调用该方法,因为若调用发送消息已读回执方法 `SendMessageReadAck`,则需要调用多次。
+
+```csharp
+SDKClient.Instance.ChatManager.SendConversationReadAck(conversationId, new CallBack(
+ onSuccess: () =>
+ {
+ },
+ onError: (code, desc) =>
+ {
+ }
+));
+```
+
+3. 消息发送方监听会话已读回执的回调。
+
+同一用户 ID 登录多设备的情况下,用户在一台设备上发送会话已读回执,其他设备会收到 `OnConversationRead` 回调。
+
+:::tip
+对于群组聊天,会话已读回执只用于清空服务端的群组会话的未读数,消息发送方不会通过 `OnConversationRead` 回调收到会话已读回执。
+:::
+
+```csharp
+public class MyDelegate : IChatManagerDelegate
+{
+ //...
+ public void OnConversationRead(string from, string to)
+ {
+ // 添加刷新页面通知等逻辑
+ }
+ //...
+}
+
+MyDelegate myDelegate = new MyDelegate();
+SDKClient.Instance.ChatManager.AddChatManagerDelegate(myDelegate);
+```
+
+## 会话已读回执和消息未读数
+
+消息接收方调用 `SendConversationReadAck` 方法发送会话已读回执,开发者可调用 `Conversation#MarkAllMessageAsRead` 方法将所有未读消息设置为已读,即将该会话的未读消息数清零。
diff --git a/docs/document/unity/initialization.md b/docs/document/unity/initialization.md
new file mode 100644
index 000000000..5fd987866
--- /dev/null
+++ b/docs/document/unity/initialization.md
@@ -0,0 +1,23 @@
+# SDK 初始化
+
+初始化是使用 SDK 的必要步骤,需在所有接口方法调用前完成。
+
+如果进行多次初始化操作,只有第一次初始化以及相关的参数生效。
+
+:::tip
+需要在主进程中进行初始化。
+:::
+
+## 前提条件
+
+有效的环信即时通讯 IM 开发者账号和 App key,详见[环信即时通讯云控制台的相关文档](enable_and_configure_IM.html#创建应用)。
+
+## 初始化
+
+初始化示例代码:
+
+```csharp
+var options = new Options("appkey"); //将该参数设置为你的 App Key
+//其他 Options 配置。
+SDKClient.Instance.InitWithOptions(options);
+```
diff --git a/docs/document/unity/integration.md b/docs/document/unity/integration.md
new file mode 100644
index 000000000..e37173f54
--- /dev/null
+++ b/docs/document/unity/integration.md
@@ -0,0 +1,20 @@
+# 集成 SDK
+
+本文介绍如何将环信即时通讯 IM SDK 集成到你的 Unity 项目。
+
+## 开发环境要求
+
+- Unity Editor 2019.4.28 或以上版本
+- Unity SDK 1.0.5 或以上
+- 操作系统与编译器要求:
+| 开发平台 | 操作系统版本 | 编译器版本 |
+| --- | --- | --- |
+| Android | Android 5.0 或以上 | Android Studio 3.0 或以上 |
+| iOS | iOS 10 或以上 | Xcode 建议最新版本 |
+| macOS | macOS 10.0 或以上 | Xcode 9.0 或以上、Visual Studio for Mac 2019 或以上 |
+| Windows | Windows 10 或以上 | Microsoft Visual Studio 2019 或以上 |
+
+## 集成 SDK
+1.[下载 Unity SDK](https://www.easemob.com/download/im)。
+在 Unity Editor 中,选择 Assets > Import Package > Custom Package...,然后选择刚下载的 unitypackage 导入。
+在弹出的 Import Unity Package 页面,点击右下角的 Import。
\ No newline at end of file
diff --git a/docs/document/unity/log.md b/docs/document/unity/log.md
new file mode 100644
index 000000000..441c41415
--- /dev/null
+++ b/docs/document/unity/log.md
@@ -0,0 +1,54 @@
+# SDK 日志
+
+环信即时通讯 IM 日志记录 SDK 相关的信息和事件。环信技术支持团队帮你排查问题时可能会请你发送 SDK 日志。
+
+## 输出信息到日志文件
+
+默认情况下,SDK 最多可生成和保存三个文件,`easemob.log` 和两个 `easemob_YYYY-MM-DD_HH-MM-SS.log` 文件。这些文件为 UTF-8 编码,每个不超过 2 MB。SDK 会将最新的日志写入 `easemob.log` 文件,写满时则会将其重命名为对应时间点的 `easemob_YYYY-MM-DD_HH-MM-SS.log` 文件,若日志文件超过三个,则会删除最早的文件。
+
+例如,SDK 在 2024 年 1 月 1 日上午 8:00:00 记录日志时会生成 `easemob.log` 文件,若在 8:30:00 将 `easemob.log` 文件写满则会将其重命名为 `easemob_2024-01-01_08-30-00.log` 文件,随后在 9:30:30 和 10:30:30 分别生成了 `easemob_2024-01-01_09-30-30.log` 和 `easemob_2024-01-01_10-30-30.log` 文件,则此时 `easemob_2024-01-01_08-30-00.log` 文件会被移除。
+
+SDK 默认不输出调试信息(所有日志,包括调试信息、警告和错误),只需输出错误日志。若需调试信息,首先要开启调试模式。
+
+```csharp
+Options options = new Options("YourAppKey");
+options.DebugMode = true;
+SDKClient.Instance.InitWithOptions(options);
+```
+
+## 获取本地日志
+
+Unity 分为 4 个端:Unity Mac、Unity Windows、Unity iOS、Unity Android。
+
+- Unity Mac
+
+日志路径: /Users/XXX/Library/Application Support/YYY/ZZZ/sdkdata/easemobLog 或者 /Users/XXX/Library/Application Support/com.YYY.ZZZ/sdkdata/easemobLog
+
+XXX: Mac 用户名; YYY: Unity 中设置的公司名称,如果没有设置则为 `DefaultCompany`,ZZZ 为 app 名称。
+
+- Unity Windows
+
+日志路径:C:\Users\XXX\AppData\LocalLow\YYY\ZZZ\sdkdata\easemobLog
+
+XXX:Windows 用户名; YYY: Unity 中设置的公司名称,如果没有设置则为 `DefaultCompany`,ZZZ 为 app 名称。
+
+- Unity iOS
+
+本地日志的获取与 iOS 的相同,详见 [iOS 本地日志的获取](/document/ios/log.html#获取本地日志)。
+
+日志路径:沙箱 Library/Application Support/HyphenateSDK/easemobLog。
+
+以真机为例,获取本地日志过程如下:
+
+- 打开 Xcode,连接设备,选择 **Xcode** > **Window** > **Devices and Simulators**。
+- 进入 **Devices** 选项卡,在左侧选择目标设备,例如 Easemob IM,点击设置图标,然后选择 **Download Container**。
+
+
+
+日志文件 `easemob.log` 文件在下载包的 AppData/Library/Application Support/HyphenateSDK/easemobLog 目录下。
+
+- Unity Android
+
+在 Android Studio 中,选择 **View** > **Tool Windows** > **Device File Explorer**,然后浏览设备上的文件夹。
+
+日志路径为 /data/data//sdkdata/easemobLog。
\ No newline at end of file
diff --git a/docs/document/unity/login.md b/docs/document/unity/login.md
new file mode 100644
index 000000000..1204fb2d9
--- /dev/null
+++ b/docs/document/unity/login.md
@@ -0,0 +1,144 @@
+# 登录
+
+初始化 IM SDK 后,你需要首先调用接口登录。登录成功后,才能使用 IM 的功能。
+
+## 用户注册
+
+用户注册模式分为以下两种:
+
+- 开放注册:一般在体验 Demo 和测试环境时使用,正式环境中不推荐使用该方式注册环信账号。要使用开放注册,需要在[环信即时通讯云控制台](https://console.easemob.com/user/login)的**即时通讯** > **服务概览**的**设置**区域,将**用户注册模式**设置为**开放注册**。只有打开该开关,才能使用客户端或 [REST API](/document/server-side/account_system.html#开放注册单个用户)开放注册用户。
+
+示例代码如下所示:
+
+```csharp
+SDKClient.Instance.CreateAccount(username, password,
+ callback: new CallBack(
+
+ onSuccess: () => {
+ Debug.Log("CreateAccount succeed");
+ },
+
+ onError: (code, desc) => {
+ Debug.Log($"CreateAccount failed, code: {code} ; desc: {desc}");
+ }
+ )
+);
+```
+
+- 授权注册:通过环信提供的 REST API 注册环信用户账号,注册后保存到你的服务器或返给客户端。要使用授权注册,你需要在[环信即时通讯云控制台](https://console.easemob.com/user/login)的**即时通讯** > **服务概览**的**设置**区域,将**用户注册模式**设置为**授权注册**。相关的 REST API 介绍,详见[授权注册单个用户](/document/server-side/account_system.html#授权注册单个用户)和[批量授权注册用户](/document/server-side/account_system.html#批量授权注册用户)的接口介绍。
+
+除此以外,可以在[环信即时通讯云控制台](https://console.easemob.com/user/login)创建正式环境下和测试环境下的用户,详见[创建用户相关介绍](/product/enable_and_configure_IM.html#创建-im-用户)。
+
+## 主动登录
+
+1. **用户 ID + token** 是更加安全的登录方式。
+
+测试环境下,你在[环信即时通讯云控制台](https://console.easemob.com/user/login)创建用户后,环信服务器会自动为这些用户分配用户 Token,详见[测试环境下创建用户的介绍](/product/enable_and_configure_IM.html#测试环境)。
+
+使用 token 登录时需要处理 token 过期的问题,比如在每次登录时更新 token 等机制。
+
+```csharp
+SDKClient.Instance.LoginWithToken(username, token, true,
+ callback: new CallBack(
+
+ onSuccess: () =>
+ {
+ Debug.Log("login succeed");
+ },
+
+ onError: (code, desc) =>
+ {
+ if (code == 200)
+ {
+ Debug.Log("Already login.");;
+ }
+ else
+ {
+ Debug.Log($"login failed, code: {code} ; desc: {desc}");
+ }
+ }
+ )
+);
+```
+
+2. **用户 ID + 密码**登录是传统的登录方式。用户名和密码均由你的终端用户自行决定,密码需要符合[密码规则要求](/document/server-side/account_system.html#开放注册单个用户)。
+
+```csharp
+SDKClient.Instance.Login(username, password,
+ callback: new CallBack(
+
+ onSuccess: () =>
+ {
+ Debug.Log("login succeed");
+ },
+
+ onError: (code, desc) =>
+ {
+ if (code == 200)
+ {
+ Debug.Log("Already login.");;
+ }
+ else
+ {
+ Debug.Log($"login failed, code: {code} ; desc: {desc}");
+ }
+ }
+ )
+);
+
+```
+
+## 自动登录
+
+暂时不支持自动登录。
+
+## 获取当前登录的用户
+
+你可以调用 `SDKClient#CurrentUsername` 方法获取当前登录用户的用户 ID。
+
+## 获取登录状态
+
+你可以调用 `SDKClient#IsLoggedIn` 方法获取当前用户的登录状态。
+
+## 退出登录
+
+你可以调用 `Logout` 方法退出登录。退出登录后,你不会再收到其他用户发送的消息。
+
+异步方法:
+
+```csharp
+SDKClient.Instance.Logout(false,
+ callback: new CallBack(
+ onSuccess: () =>
+ {
+ Debug.Log("Logout succeed");
+ },
+
+ onError: (code, desc) =>
+ {
+ Debug.Log($"Logout failed, code:{code}, desc:{desc}");
+ }
+ )
+);
+```
+
+:::tip
+1. 如果调用退出方法,在收到 `onSuccess` 回调后才能去调用 IM 相关方法,例如 `Login`。
+:::
+
+## 账号切换
+
+若在 app 中从当前账号切换到其他账号,你需要首先调用 `Logout` 方法登出,然后再调用 `LoginWithToken` 或 `Login` 方法登录。
+
+## 多设备登录
+
+除了单端单设备登录,环信即时通讯 IM 支持同一账号在多端的多个设备上登录。多设备登录时,若同端设备数量超过限制,新登录的设备会将之前登录的设备踢下线。
+
+关于多设备登录场景中的设备数量限制、互踢策略以及信息同步,详见[多设备登录文档](multi_device.html)。
+
+
+## 更多
+
+### 登录被封禁账号的提示
+
+在环信即时通讯控制台或调用 REST API 封禁用户账号后,若仍使用该账号登录,SDK会返回 "service is disabled"(305 错误), 可以根据用户这个返回值来进行相应的提示或者处理。
diff --git a/docs/document/unity/message_modify.md b/docs/document/unity/message_modify.md
index 034402cca..52f005a74 100644
--- a/docs/document/unity/message_modify.md
+++ b/docs/document/unity/message_modify.md
@@ -27,7 +27,7 @@
开始前,请确保满足以下条件:
-- 完成 SDK 初始化,并连接到服务器,详见 [快速开始](quickstart.html) 及 [SDK 集成概述](overview.html)。
+- 完成 SDK 初始化,并连接到服务器,详见 [初始化](initialization.html)及[连接](connection.html)文档。
- 了解环信即时通讯 IM API 的使用限制,详见 [使用限制](/product/limitation.html)。
## 实现方法
diff --git a/docs/document/unity/message_receipt.md b/docs/document/unity/message_receipt.md
index 14134c509..c9296c464 100644
--- a/docs/document/unity/message_receipt.md
+++ b/docs/document/unity/message_receipt.md
@@ -1,239 +1,195 @@
-# 消息回执
+# 实现消息回执
-单聊会话支持消息送达回执、会话已读回执和消息已读回执,发送方发送消息后可及时了解接收方是否及时收到并阅读了信息,也可以了解整个会话是否已读。
+**单聊会话支持消息送达回执和消息已读回执**,发送方发送消息后可及时了解接收方是否及时收到并阅读了消息。
-群聊会话只支持消息已读回执。群成员在发送消息时,可以设置该消息是否需要已读回执。仅专业版及以上版本支持群消息已读回执功能。若要使用该功能,需在[环信即时通讯云控制台](https://console.easemob.com/user/login)开通,具体费用详见[产品价格](/product/pricing.html#增值服务费用)。
+**群聊会话只支持消息已读回执,不支持送达回执**。群成员在发送消息时,可以设置该消息是否需要已读回执。要使用该功能,你需要[在环信即时通讯云控制台上开通该功能](/product/enable_and_configure_IM.html#设置群消息已读回执),具体费用详见[产品价格](/product/pricing.html#增值服务费用)。
-:::tip
-仅单聊消息支持送达回执,群聊消息不支持。
-:::
+消息送达回执和已读回执的效果示例,如下图所示:
-本文介绍如何使用环信即时通讯 IM Unity SDK 实现单聊和群聊的消息回执功能。
+
## 技术原理
-环信即时通讯 IM Unity SDK 通过 `IChatManager` 类提供消息的送达回执和已读回执功能,包含的核心方法如下:
+使用环信即时通讯 IM Unity/Windows SDK 可以实现消息的送达回执与已读回执。
-- `Options.RequireDeliveryAck` 开启送达回执;
-- `IChatManager.SendConversationReadAck` 发出指定会话的已读回执;
-- `IChatManager.SendMessageReadAck` 发出指定单聊消息的已读回执;
-- `SendReadAckForGroupMessage` 发送群组消息的已读回执。
+- 单聊消息送达回执的逻辑如下:
-实现消息送达和已读回执的逻辑分别如下:
+ 1. 你可以通过设置 `Options#RequireDeliveryAck` 为 `true` 开启送达回执功能。
+ 2. 消息接收方收到消息后,SDK 自动向发送方触发送达回执。
+ 3. 消息发送方通过监听 `IChatManagerDelegate#OnMessagesDelivered` 回调接收消息送达回执。
-- 单聊消息送达回执:
+- 单聊消息已读回执的逻辑如下:
- 1. 消息发送方在发送消息前通过 `ChatOptions.RequireDeliveryAck` 开启送达回执功能;
+ 1. 你可以通过设置 `Options#RequireAck` 为 `true` 开启已读回执功能。
+ 2. 消息接收方收到消息后,调用 `ChatManager#SendMessageReadAck` 方法发送消息已读回执。
+ 3. 消息发送方通过监听 `IChatManagerDelegate#OnMessagesRead` 回调接收消息已读回执。
- 2. 消息接收方收到消息后,SDK 自动向发送方触发送达回执;
+- 群聊消息已读回执的逻辑如下:
- 3. 消息发送方通过监听 `OnMessageDelivered` 回调接收消息送达回执。
-
-- 单聊会话及消息已读回执
-
- 1. 设置 `RequireAck` 为 `true`;
-
- 2. 消息接收方收到或阅读消息后,调用 API `SendConversationReadAck` 或 `SendMessageReadAck` 发送会话或消息已读回执;
-
- 3. 消息发送方通过监听 `OnConversationRead` 或 `OnMessageRead` 回调接收会话或消息已读回执。
-
-- 群聊只支持消息已读回执:
-
- 1. 你可以通过设置 `isNeedGroupAck` 开启群聊消息已读回执功能;
-
- 2. 消息接收方收到或阅读消息后通过 `SendReadAckForGroupMessage` 发送群组消息的已读回执。
+ 1. 你可以通过设置 `Options#RequireAck` 为 `true` 开启消息已读回执功能。
+ 2. 发送方在群组中发送消息时设置 `Message#IsNeedGroupAck` 为 `true` 要求接收方返回消息已读回执。
+ 3. 接收方收到或阅读消息后通过 `ChatManager#SendReadAckForGroupMessage` 方法发送群组消息的已读回执。
## 前提条件
开始前,请确保满足以下条件:
-- 完成 SDK 初始化,并连接到服务器,详见 [快速开始](quickstart.html);
-- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html);
-- 群消息已读回执功能仅在环信 IM 专业版及以上版本支持该功能。若要使用该功能,需在[环信即时通讯云控制台](https://console.easemob.com/user/login)开通,具体费用详见[产品价格](/product/pricing.html#增值服务费用)。
+- 完成 SDK 初始化,并连接到服务器,详见 [快速开始](quickstart.html)。
+- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。
+- 要使用群消息已读回执功能,需在[环信即时通讯云控制台](https://console.easemob.com/user/login)开通,具体费用详见[产品价格](/product/pricing.html#增值服务费用)。
## 实现方法
-### 消息送达回执
+### 单聊消息送达回执
-1. 发送方若要接收消息送达回执,你需要将 `Options` 中的 `RequireDeliveryAck` 设为 `true`。当接收方收到消息后,SDK 底层会自动进行消息送达回执。
+1. 开启消息送达功能,即 SDK 初始化时将 `Options#RequireDeliveryAck` 设置为 `true`。
```csharp
-// 设置是否需要消息送达回执,设为 `true`。
-Options.RequireDeliveryAck = true;
+// 设置是否需要接收方送达确认,默认 `false` 即不需要。
+options.RequireDeliveryAck = true;
```
-2. 发送方监听事件 `OnMessagesDelivered` 回调,收到接收方的送达回执。
+2. 接收方收到消息后,SDK 自动向发送方触发送达回执。
+
+3. 发送方监听 `IChatManagerDelegate#OnMessagesDelivered` 事件,收到接收方的送达回执。你可以在收到该通知时,显示消息的送达状态。
```csharp
-// 继承并实现 `IChatManagerDelegate`。
-public class ChatManagerDelegate : IChatManagerDelegate {
+public class MyDelegate : IChatManagerDelegate
+{
+ //...
- // 收到已送达回执。
- public void OnMessagesDelivered(List messages)
- {
- }
+ // 收到消息。
+ public void OnMessagesReceived(List messages); {
+ }
+ // 收到已送达回执。
+ public void OnMessagesDelivered(List messages); {
}
-// 注册监听器。
-ChatManagerDelegate adelegate = new ChatManagerDelegate();
-SDKClient.Instance.ChatManager.AddChatManagerDelegate(adelegate);
-
-// 移除监听器。
-SDKClient.Instance.ChatManager.RemoveChatManagerDelegate(adelegate);
-```
+ //...
+}
-### 消息和会话的已读回执
+MyDelegate myDelegate = new MyDelegate();
-消息已读回执用于告知单聊或群聊中的用户接收方已阅读其发送的消息。为降低消息已读回执方法的调用次数,SDK 还支持在单聊中使用会话已读回执功能,用于获知接收方是否阅读了会话中的未读消息。
+//注册消息监听
+SDKClient.Instance.ChatManager.AddChatManagerDelegate(myDelegate);
+记得在不需要的时候移除 listener
+SDKClient.Instance.ChatManager.RemoveChatManagerDelegate(myDelegate);
+```
-#### 单聊
+### 单聊消息已读回执
-单聊既支持消息已读回执,也支持会话已读回执。我们建议你按照如下逻辑结合使用两种回执,减少发送消息已读回执数量。
+单聊既支持单条消息已读回执,也支持[会话已读回执](conversation_receipt.html)。我们建议你结合使用这两种回执,见实现步骤的描述。
-- 聊天页面未打开时,若有未读消息,进入聊天页面,发送会话已读回执;
-- 聊天页面打开时,若收到消息,发送消息已读回执。
+单聊消息的已读回执有效期与消息在服务端的存储时间一致,即在服务器存储消息期间均可发送已读回执。消息在服务端的存储时间与你订阅的套餐包有关,详见[产品价格](/product/pricing.html#套餐包功能详情)。
-第一步是在设置中打开已读回执开关:
+参考如下步骤在单聊中实现消息已读回执。
+1. App 开启已读回执功能,即 SDK 初始化时将 `Options#RequireAck` 设置为 `true`。
```csharp
-// 设置是否需要消息已读回执,设为 `true`。
-Options.RequireReadAck = true;
+// 设置是否需要接受方已读确认,默认为true
+options.RequireAck = true;
```
-##### 会话已读回执
-
-参考以下步骤在单聊中实现会话已读回执。
-
-1. 接收方发送会话已读回执。
+1. 接收方发送消息已读回执。
-消息接收方进入会话页面,查看会话中是否有未读消息。若有,发送会话已读回执,没有则不再发送。
+- 聊天页面未打开时,若有未读消息,进入聊天页面,发送会话已读回执。这种方式可避免发送多个消息已读回执。
```csharp
SDKClient.Instance.ChatManager.SendConversationReadAck(conversationId, new CallBack(
- onSuccess: () => {
-
- },
- onError:(code, desc) => {
-
- }
-));
-```
-
-2. 消息发送方监听会话已读回执的回调。
-
-```csharp
-// 继承并实现 `IChatManagerDelegate`。
-public class ChatManagerDelegate : IChatManagerDelegate {
- // 收到已读回执。`from` 表示发送该会话已读回执的消息接收方,`to` 表示收到该会话已读回执的消息发送方。
- public void OnConversationRead(string from, string to)
+ onSuccess: () =>
+ {
+ UIManager.SuccessAlert(transform);
+ },
+ onError: (code, desc) =>
{
+ UIManager.ErrorAlert(transform, code, desc);
}
-}
-
-// 注册监听器。
-ChatManagerDelegate adelegate = new ChatManagerDelegate()
-SDKClient.Instance.ChatManager.AddChatManagerDelegate(adelegate);
-
-// 移除监听器。
-SDKClient.Instance.ChatManager.RemoveChatManagerDelegate(adelegate);
+));
```
-同一用户 ID 登录多设备的情况下,用户在一台设备上发送会话已读回执,服务器会将会话的未读消息数置为 `0`,同时其他设备会收到 `OnConversationRead` 回调。
-
-##### 消息已读回执
-
-单聊消息的已读回执有效期与消息在服务端的存储时间一致,即在服务器存储消息期间均可发送已读回执。消息在服务端的存储时间与你订阅的套餐包有关,详见[产品价格](/product/pricing.html#套餐包功能详情)。
-
-参考如下步骤在单聊中实现消息已读回执。
-
-1. 接收方发送已读回执消息。
-
-消息接收方进入会话时,发送会话已读回执。
+- 聊天页面打开时,若收到消息,发送单条消息已读回执。
```csharp
-SDKClient.Instance.ChatManager.SendConversationReadAck(conversationId, new CallBack(
- onSuccess: () => {
-
- },
- onError:(code, desc) => {
+public class MyDelegate : IChatManagerDelegate
+{
+ //...
+ // 收到消息。
+ public void OnMessagesReceived(List messages); {
+ ......
+ SendReadAck(message);
+ ......
}
-));
-```
-
-2.在会话页面,接收到消息时,根据消息类型发送消息已读回执,如下所示:
-
-```csharp
-// 继承并实现 `IChatManagerDelegate`。
-public class ChatManagerDelegate : IChatManagerDelegate {
- // 收到已送达回执。
- public void OnMessageReceived(List messages)
- {
- ......
- sendReadAck(message);
- ......
- }
+ //...
}
+MyDelegate myDelegate = new MyDelegate();
-// 注册监听器。
-ChatManagerDelegate adelegate = new ChatManagerDelegate()
-SDKClient.Instance.ChatManager.AddChatManagerDelegate(adelegate);
+//注册消息监听
+SDKClient.Instance.ChatManager.AddChatManagerDelegate(myDelegate);
-// 发送已读回执。
-public void sendReadAck(Message message) {
+/**
+* 发送已读回执。
+* @param message
+*/
+public void SendReadAck(Message message)
+{
// 这里是接收的消息,未发送过已读回执且是单聊。
- if(message.Direction == MessageDirection.RECEIVE
- && !message.HasReadAck
- && message.MessageType == MessageType.Chat) {
+ if (message.Direction == MessageDirection.RECEIVE
+ && !message.HasReadAck
+ && message.MessageType == MessageType.Chat)
+ {
MessageBodyType type = message.Body.Type;
- // 视频、语音及文件需要点击后再发送,可根据需求进行调整。
- if(type == MessageBodyType.VIDEO || type == MessageBodyType.VOICE || type == MessageBodyType.FILE) {
+ // 视频,语音及文件需要点击后再发送,可以根据需求进行调整。
+ if (type == MessageBodyType.VIDEO || type == MessageBodyType.VOICE || type == MessageBodyType.FILE)
+ {
return;
}
-
SDKClient.Instance.ChatManager.SendMessageReadAck(message.MsgId, new CallBack(
- onSuccess: () => {
-
- },
- onError: (code, desc) => {
-
- }
- );
+ onSuccess: () =>
+ {
+ },
+ onError: (code, desc) =>
+ {
+ }
+ ));
}
}
```
3. 消息发送方监听消息已读回调。
-你可以调用接口监听指定消息是否已读,示例代码如下:
+消息发送方可以通过 `IChatManagerDelegate#OnMessagesRead` 事件监听指定消息是否已读,示例代码如下:
```csharp
-// 继承并实现 `IChatManagerDelegate`。
-public class ChatManagerDelegate : IChatManagerDelegate {
+public class MyDelegate : IChatManagerDelegate
+{
+ //...
- // 收到消息已读回执。
- public void OnMessagesRead(string from, string to)
- {
- }
+ public void OnMessagesRead(List messages); {
+ // 添加刷新消息等逻辑。
+ }
+
+ //...
}
-// 注册监听器。
-ChatManagerDelegate adelegate = new ChatManagerDelegate()
-SDKClient.Instance.ChatManager.AddChatManagerDelegate(adelegate);
-// 移除监听器。
-SDKClient.Instance.ChatManager.RemoveChatManagerDelegate(adelegate);
+MyDelegate myDelegate = new MyDelegate();
+
+//注册消息监听
+SDKClient.Instance.ChatManager.AddChatManagerDelegate(myDelegate);
+记得在不需要的时候移除 listener
+SDKClient.Instance.ChatManager.RemoveChatManagerDelegate(myDelegate);
```
-#### 群聊
+### 群聊消息已读回执
-对于群聊,群成员发送消息时,可以设置该消息是否需要已读回执。若需要,每个群成员在阅读消息后,SDK 均会发送已读回执,即阅读该消息的群成员数量即为已读回执的数量。
+对于群聊,群成员发送消息时,可以设置该消息是否需要已读回执。若需要,每个群成员阅读消息后,应该调用`ChatManager#SendReadAckForGroupMessage` 方法发送已读回执,阅读该消息的群成员数量即为已读回执的数量。
群消息已读回执特性的使用限制如下表所示:
@@ -247,65 +203,116 @@ SDKClient.Instance.ChatManager.RemoveChatManagerDelegate(adelegate);
你可以按以下步骤实现群消息已读回执特性:
-1. 群成员发送消息时若需已读回执,需设置 `Message` 的 `IsNeedGroupAck` 为 `true`。
+1. 开启已读回执功能,即 SDK 初始化时将 `Options#RequireAck` 设置为 `true`。
+
+该功能开启后,接收方阅读消息后,SDK 底层会自动进行消息已读回执。
+```csharp
+// 设置是否需要接受方已读确认,默认为 `true`。
+options.RequireAck = true;
+```
+
+2. 发送方发送消息时设置 `Message#IsNeedGroupAck` 属性为 `true`。
+
+与单聊消息的 app 层级设置已读回执功能不同,群聊消息是在发送消息时设置指定消息是否需要已读回执。
```csharp
-Message msg = Message.CreateTextSendMessage("to", "hello world");
+Message msg = Message.CreateTextSendMessage(to, content);
msg.IsNeedGroupAck = true;
```
-2. 消息接收方发送群组消息的已读回执。
+3. 消息接收方发送群组消息的已读回执。
```csharp
-void SendReadAckForGroupMessage(string messageId, string ackContent)
-{
- SDKClient.Instance.ChatManager.SendReadAckForGroupMessage(messageId, ackContent,callback: new CallBack(
- onSuccess: () =>
- {
+public void sendAckMessage(EMMessage message) {
- },
- onError: (code, desc) =>
- {
+ if (message.HasReadAck) {
+ return;
+ }
- }
- ));
+ // 多设备登录时,无需再向自己发送的消息发送已读回执。
+ if (SDKClient.Instance.CurrentUsername.CompareTo(message.From)) {
+ return;
}
+
+ if (message.IsNeedGroupAck() && !message.IsRead) {
+ string to = message.ConversationId;
+ string msgId = message.MsgId;
+ SDKClient.Instance.ChatManager.SendReadAckForGroupMessage(message.MsgId, “”, new CallBack(
+ onSuccess: () =>
+ {
+ },
+ onError: (code, desc) =>
+ {
+ }
+ ));
+ message.IsRead = true;
+ }
+}
```
-3. 消息发送方监听群组消息已读回调。
+4. 消息发送方监听群组消息已读回调。
+
+群消息已读回调在 `IChatManagerDelegate#OnGroupMessageRead` 中实现。
-群组消息已读回调在消息监听类 `IChatManagerDelegate` 中实现。
+发送方接收到群组消息已读回执后,其发出消息的属性 `Message#GroupAckCount` 会有相应变化。
```csharp
-// 继承并实现 `IChatManagerDelegate`。
-public class ChatManagerDelegate : IChatManagerDelegate {
+public class MyDelegate : IChatManagerDelegate
+{
+ //...
+ // 接收到群组消息体的已读回执, 表明消息的接收方已经阅读此消息。
+ public void OnGroupMessageRead(List list); {
- // 收到群组消息的已读回执, 表明消息的接收方已阅读此消息。
- public void OnGroupMessageRead(List list)
- {
+ }
- }
+ //...
}
-// 注册监听器。
-ChatManagerDelegate adelegate = new ChatManagerDelegate()
-SDKClient.Instance.ChatManager.AddChatManagerDelegate(adelegate);
+MyDelegate myDelegate = new MyDelegate();
+
+//注册消息监听
+SDKClient.Instance.ChatManager.AddChatManagerDelegate(myDelegate);
+记得在不需要的时候移除 listener
+SDKClient.Instance.ChatManager.RemoveChatManagerDelegate(myDelegate);
```
-4. 消息发送方获取群组消息的已读回执详情。
+5. 消息发送方获取群组消息的已读回执详情。
-你可以调用 `FetchGroupReadAcks` 获取群组消息的已读回执的详情,示例代码如下:
+你可以调用 `ChatManager#FetchGroupReadAcks` 方法从服务器获取单条消息的已读回执的详情。
```csharp
-// startAckId:查询起始的已读回执 ID。首次调用为空,SDK 从最新的已读回执开始按服务器接收回执时间的逆序获取。后续调用从 CursorResult 中的 cursor 获取。
-// pageSize:每页获取群消息已读回执的条数。
-SDKClient.Instance.ChatManager.FetchGroupReadAcks(messageId, groupId, startAckId, pageSize, new ValueCallBack>(
- onSuccess: (list) =>
- {
- // 页面刷新等操作。
- },
- onError: (code, desc) =>
- {
- }
-));
+//messageId 消息 ID。
+//groupId 群组 ID。
+//pageSize 每页获取群消息已读回执的条数。取值范围[1,50]。
+//startAckId 已读回执的 ID,如果为空,从最新的回执向前开始获取。
+//callBack 结果回调,成功执行 {@link ValueCallBack#onSuccess(Object)},失败执行 {@link ValueCallBack#onError(int, String)}。
+public void FetchGroupReadAcks(string messageId, string groupId, int pageSize = 20, string startAckId = null, ValueCallBack> callback = null)
```
+
+### 查看消息送达和已读状态
+
+对于单聊消息,本地通过 `Message#HasDeliverAck` 字段存储消息送达状态。
+
+对于单聊消息,本地通过以下字段存储消息已读状态:
+
+| 字段 | 描述 |
+| :--------- | :----- |
+| `Message#IsRead` | 用户是否已读了该消息。如果是自己发送的消息,该字段的值固定为 `true`。|
+| `Message#HasReadAck` | 是否(消息接收方)已发送或(消息发送方)已收到消息已读回执。如果是自己发送的消息,记录的是对方是否已读。如果是对方的消息,则记录的是自己是否发送过已读回执。 |
+
+对于群聊消息,本地数据库通过以下字段存储消息已读状态:
+
+| 字段 | 描述 |
+| :--------- | :----- |
+| `Message#IsRead` | 用户是否已读了该消息。如果是自己发送的消息,该字段的值固定为 `true`。|
+| `Message#GroupAckCount` | 已阅读消息的群成员数量。 |
+
+### 已读回执与未读消息数
+
+- 会话已读回执发送后,开发者需要调用 `Conversation#MarkAllMessageAsRead` 方法将该会话的所有消息置为已读,即会话的未读消息数清零。
+
+- 消息已读回执发送后,开发者需要调用 `Conversation#MarkMessageAsRead` 方法将该条消息置为已读,则消息未读数会有变化。
+
+
+
+
diff --git a/docs/document/unity/overview.md b/docs/document/unity/overview.md
index 3df164f3e..c8408cc35 100644
--- a/docs/document/unity/overview.md
+++ b/docs/document/unity/overview.md
@@ -279,7 +279,7 @@ XXX:Windows 用户名; YYY: Unity 中设置的公司名称,如果没有设
- Unity iOS
-本地日志的获取与 iOS 的相同,详见 [iOS 本地日志的获取](/document/ios/overview.html#获取本地日志)。
+本地日志的获取与 iOS 的相同,详见 [iOS 本地日志的获取](/document/ios/log.html#获取本地日志)。
日志路径:沙箱 Library/Application Support/HyphenateSDK/easemobLog。
diff --git a/docs/document/web/connection.md b/docs/document/web/connection.md
new file mode 100644
index 000000000..a9b2867f6
--- /dev/null
+++ b/docs/document/web/connection.md
@@ -0,0 +1,45 @@
+# 连接
+
+应用客户端成功连接到环信服务器后,才能使用环信即时通讯 SDK 的收发消息等功能。
+
+你调用 `open` 方法登录后,客户端 SDK 会自动连接环信服务器。关于登录详情,请参见[登录文档](login.html)。
+
+## 监听连接状态
+
+```javascript
+conn.addEventHandler("connectionListener", {
+ onConnected: () => {
+ console.log("连接成功");
+ },
+ // 自 4.8.0 版本,`onDisconnected` 事件新增断开原因回调参数, 告知用户触发 `onDisconnected` 的原因。
+ onDisconnected: () => {
+ console.log("连接断开");
+ },
+ onReconnecting: () => {
+ console.log("重连中");
+ };
+});
+```
+
+## 自动重连
+
+登录后,SDK 在以下情况下会尝试自动重连:
+
+- 网络断开
+
+- 网络切换
+
+- 非主动调用登出
+
+登录后,如果由于网络信号弱、切换网络等引起的连接中断,SDK 会自动尝试重连。
+
+不过,SDK 在以下情况下会停止自动重连。你需要调用 `open` 方法登录。
+
+- 用户调用了 SDK 的登出方法 `close` 主动退出登录。
+- 登录时鉴权错误,例如, token 无效(错误码 104)或已过期(错误码 108)。
+- 用户在其他的设备上更改了密码,导致此设备上自动登录失败,提示错误码 216。
+- 用户的账号被从服务器端删除,提示错误码 207。
+- 用户在另一设备登录,将当前设备上登录的用户踢出,提示错误码 206。
+- 用户登录设备数量超过限制,提示错误码 214。
+- 应用程序的日活跃用户数量(DAU)或月活跃用户数量(MAU)达到上限,提示错误码 8。
+```
diff --git a/docs/document/web/conversation_local.md b/docs/document/web/conversation_local.md
index ef0c6025b..f43b4ff16 100644
--- a/docs/document/web/conversation_local.md
+++ b/docs/document/web/conversation_local.md
@@ -22,7 +22,7 @@
开始前,请确保满足以下条件:
-- 完成 SDK 4.2.1 或以上版本初始化,详见 [SDK 集成概述](overview.html#sdk-初始化);
+- 完成 SDK 4.2.1 或以上版本初始化,详见 [初始化](initialization.html)文档;
- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html);
- [按需导入 SDK](import_sdk_minicore.html),[集成本地存储插件](#集成本地存储插件)。
diff --git a/docs/document/web/initialization.md b/docs/document/web/initialization.md
new file mode 100644
index 000000000..5e5d236b5
--- /dev/null
+++ b/docs/document/web/initialization.md
@@ -0,0 +1,21 @@
+# SDK 初始化
+
+初始化是使用 SDK 的必要步骤,需在所有接口方法调用前完成。
+
+## 前提条件
+
+有效的环信即时通讯 IM 开发者账号和 App key,详见[环信即时通讯云控制台的相关文档](enable_and_configure_IM.html#创建应用)。
+
+## 初始化参数说明
+
+```javascript
+import ChatSDK from "easemob-websdk";
+const conn = new ChatSDK.connection({
+ appKey: "Your appKey",
+});
+```
+
+| 参数 | 类型 | 是否必需 | 描述 |
+| ------------- | ------ | -------- | -------------------------- |
+| appKey | String | 是 | 环信应用的唯一标识 |
+
diff --git a/docs/document/web/integration.md b/docs/document/web/integration.md
new file mode 100644
index 000000000..6d5d8147b
--- /dev/null
+++ b/docs/document/web/integration.md
@@ -0,0 +1,213 @@
+# 集成 SDK
+
+本文介绍如何将环信即时通讯 IM SDK 集成到你的 Web 项目。
+
+## 开发环境要求
+
+- 支持的浏览器:
+ - Chrome 54+
+ - Firefox 10+
+ - Safari 6+
+
+## 1. 使用 npm 安装 SDK
+
+```bash
+npm install easemob-websdk
+```
+
+## 2. 引入 SDK
+
+你可以通过以下方式引入 SDK,**推荐按需导入 SDK 文件,从而减少 SDK 体积**。
+
+### (推荐)按需导入 SDK
+
+SDK 提供了灵活的模块化设计,允许开发者根据需求引入功能模块,并将其注册到 miniCore 中使用。
+
+miniCore 是一个基座,支持登录登出和发送消息等[基础功能](https://doc.easemob.com/jsdoc/classes/Connection.Connection-1.html),而且包含消息对象。因此,若只使用收发消息功能,则只需引入 miniCore。若使用其他功能,miniCore 支持使用插件的方式引入其他功能模块。按需引入模块的方式实现了不同模块的灵活组合,从而避免不必要的代码加载,减小了应用程序的体积。
+
+:::tip
+1. 只有按需导入 SDK 的方式才支持[本地会话管理功能](conversation_local.html)。
+2. 小程序 uniapp 不支持使用 miniCore 的集成方式。
+:::
+
+#### 支持按需导入的 SDK 模块
+
+| 功能 | 导入文件 | 使用方式 |
+| :--------------- | :--------------------------- | :---------------- |
+| 联系人和消息管理 | import \* as contactPlugin from "easemob-websdk/contact/contact"; | miniCore.usePlugin(contactPlugin, "contact"); |
+| 群组 | import \* as groupPlugin from "easemob-websdk/group/group"; | miniCore.usePlugin(groupPlugin, "group"); |
+| 聊天室 | import \* as chatroomPlugin from "easemob-websdk/chatroom/chatroom"; | miniCore.usePlugin(chatroomPlugin, "chatroom"); |
+| 子区 | import \* as threadPlugin from "easemob-websdk/thread/thread"; | miniCore.usePlugin(threadPlugin, "thread"); |
+| 翻译 | import \* as translationPlugin from "easemob-websdk/translation/translation"; | miniCore.usePlugin(translationPlugin, "translation"); |
+| 在线状态订阅 | import \* as presencePlugin from "easemob-websdk/presence/presence"; | miniCore.usePlugin(presencePlugin, "presence"); |
+| 会话免打扰 | import \* as silentPlugin from "easemob-websdk/silent/silent"; | miniCore.usePlugin(silentPlugin, "silent"); |
+
+#### 按需导入 SDK 模块
+
+##### 1. 安装 SDK
+
+首先,通过 npm、yarn 或者其他包管理工具进行安装 SDK。
+
+```bash
+# npm
+npm install easemob-websdk
+
+# yarn
+yarn add easemob-websdk
+```
+
+##### 2. 引入 SDK 和所需模块
+
+根据项目需求引入相应的功能模块。例如,引入用户关系模块:
+
+```javascript
+import MiniCore from "easemob-websdk/miniCore/miniCore";
+import * as contactPlugin from "easemob-websdk/contact/contact";
+```
+
+##### 3. 注册模块到 miniCore
+
+将引入的功能模块注册到 miniCore 中:
+
+```javascript
+const miniCore = new MiniCore({
+ appKey: "your appKey",
+});
+
+// "contact" 为固定值
+miniCore.usePlugin(contactPlugin, "contact");
+```
+
+##### 4. 使用注册的模块
+
+注册所需模块后,即可在项目中使用这些模块提供的功能:
+
+```javascript
+// 获取联系人列表
+miniCore.contact.getContacts();
+```
+
+#### 与整体导入的接口差别
+
+通过按需导入的 SDK 与通过 [JavaScript](#通过-javascript-导入-sdk)和 [TavaScript](#通过-typescript-导入-sdk)导入的 SDK 在接口使用方面类似,唯一差别是后者将所有方法都挂载到 `connection` 类, 而使用 miniCore 时,基础的登录登出方法挂载在 miniCore 上,其他功能模块上的方法挂载在相应的模块上。
+
+本节以登录/登出、事件监听和发送消息为例进行说明。
+
+##### 登录与登出
+
+示例代码如下:
+
+```javascript
+// 登录
+miniCore.open({
+ username: "username",
+ password: "password",
+ // accessToken: 'token'
+});
+
+// 登出
+miniCore.close();
+```
+
+##### 事件监听
+
+示例代码如下:
+
+```javascript
+miniCore.addEventHandler("handlerId", {
+ onTextMessage: (message) => {
+ console.log(message);
+ },
+});
+```
+
+##### 发送消息
+
+示例代码如下:
+
+```javascript
+import { EasemobChat } from "easemob-websdk";
+//发送文本消息
+const sendTextMsg = () => {
+ const option: EasemobChat.CreateTextMsgParameters = {
+ chatType: "singleChat",
+ type: "txt",
+ to: "to",
+ msg: "hello",
+ };
+ const msg = miniCore.Message.create(option);
+ miniCore
+ .send(msg)
+ .then((res: any) => {
+ console.log("发送成功", res, msg);
+ })
+ .catch((err: any) => {
+ console.log("发送失败", err);
+ });
+};
+```
+
+### 引入 JavaScript SDK
+
+```javascript
+import EC from "easemob-websdk";
+```
+
+### 引入 TypeScript SDK
+
+在下面的导入代码中,`EasemobChat` 是 SDK 类型的命名空间。
+
+```javascript
+import EC, { EasemobChat } from "easemob-websdk";
+```
+
+### 从官网获取并导入 SDK
+
+1. 下载 [Easemob Chat SDK for Web](https://www.easemob.com/download/im)。将 Web SDK 中的 `Easemob-chat.js` 文件保存到你的项目下。
+
+2. 在 `index.html` 文件中,对 `index.js` 文件进行引用。
+
+```JavaScript
+
+```
+
+### Nuxt 或 Next 项目中引入 SDK
+
+对于服务端渲染框架, 如 Nuxt、Next 等,需要在客户端渲染阶段引入 SDK。
+
+1. Nuxt 项目, 你可以在 mounted 生命周期动态导入 SDK:
+
+```javascript
+export default {
+ mounted: () => {
+ import("easemob-websdk").then((res) => {
+ const EC = res.default;
+ console.log(EC, "easemob websdk");
+ const conn = new EC.connection({
+ appKey: "your appkey"
+ });
+ });
+ }
+};
+```
+
+2. 对于 Next 项目, 要使用客户端组件,你可以在文件顶部的导入上方添加 `use client` 指令。
+
+```tsx
+'use client'
+
+import { useEffect } from 'react'
+
+export default function Home() {
+ useEffect(() => {
+ import('easemob-websdk').then((res)=>{
+ const EC = res.default;
+ console.log(EC, "easemob websdk");
+ const conn = new EC.connection({
+ appKey: "your appkey"
+ });
+ })
+ }, [])
+}
+```
+
diff --git a/docs/document/web/log.md b/docs/document/web/log.md
new file mode 100644
index 000000000..870f3c0e6
--- /dev/null
+++ b/docs/document/web/log.md
@@ -0,0 +1,58 @@
+# SDK 日志
+
+环信即时通讯 IM 日志记录 SDK 相关的信息和事件。环信技术支持团队帮你排查问题时可能会请你发送 SDK 日志。
+
+## 输出信息到日志文件
+
+开启日志输出:
+
+```javascript
+logger.enableAll();
+```
+- 设置日志不输出到控制台:
+
+```javascript
+logger.setConsoleLogVisibility(false)
+```
+
+- 监听 SDK 日志事件:
+
+```javascript
+logger.onLog = (log)=>{
+ console.log('im logger', log)
+}
+```
+
+关闭日志输出:
+
+```javascript
+logger.disableAll();
+```
+
+设置日志输出等级:
+
+```javascript
+// 0 - 5 或者 'TRACE','DEBUG','INFO','WARN','ERROR','SILENT';
+logger.setLevel(0);
+```
+
+设置缓存日志:
+
+```javascript
+logger.setConfig({
+ useCache: false, // 是否缓存
+ maxCache: 3 * 1024 * 1024, // 最大缓存字节
+});
+// 缓存全部等级日志
+logger.setLevel(0);
+```
+
+下载日志:
+
+```javascript
+logger.download();
+```
+
+## 日志上报
+
+自 4.8.1 版本,Web SDK 支持日志上报功能, 即将日志会上传到环信的服务器。该功能默认关闭,如有需要, 可联系商务开通。
\ No newline at end of file
diff --git a/docs/document/web/login.md b/docs/document/web/login.md
new file mode 100644
index 000000000..938bd0cca
--- /dev/null
+++ b/docs/document/web/login.md
@@ -0,0 +1,73 @@
+# 登录
+
+初始化 IM SDK 后,你需要首先调用接口登录。登录成功后,才能使用 IM 的功能。
+
+## 用户注册
+
+用户注册支持以下方式:
+
+- 开放注册:一般在体验 Demo 和测试环境时使用,正式环境中不推荐使用该方式注册环信账号。要使用开放注册,需要在[环信即时通讯云控制台](https://console.easemob.com/user/login)的**即时通讯** > **服务概览**的**设置**区域,将**用户注册模式**设置为**开放注册**。只有打开该开关,才能使用客户端或 [REST API](/document/server-side/account_system.html#开放注册单个用户)开放注册用户。
+
+示例代码如下所示:
+
+```javascript
+conn.registerUser({
+ username: "user1",
+ password: "xxx",
+});
+```
+
+- 授权注册:通过环信提供的 REST API 注册环信用户账号,注册后保存到你的服务器或返给客户端。要使用授权注册,你需要在[环信即时通讯云控制台](https://console.easemob.com/user/login)的**即时通讯** > **服务概览**的**设置**区域,将**用户注册模式**设置为**授权注册**。相关的 REST API 介绍,详见[授权注册单个用户](/document/server-side/account_system.html#授权注册单个用户)和[批量授权注册用户](/document/server-side/account_system.html#批量授权注册用户)的接口介绍。
+
+除此以外,可以在[环信即时通讯云控制台](https://console.easemob.com/user/login)创建正式环境下和测试环境下的用户,详见[创建用户相关介绍](/product/enable_and_configure_IM.html#创建-im-用户)。
+
+## 登录方式
+
+### **用户 ID + token** 是更加安全的登录方式。
+
+测试环境下,你在[环信即时通讯云控制台](https://console.easemob.com/user/login)创建用户后,环信服务器会自动为这些用户分配用户 Token,详见[测试环境下创建用户的介绍](/product/enable_and_configure_IM.html#测试环境)。
+
+使用 token 登录时需要处理 token 过期的问题,比如在每次登录时更新 token 等机制。
+
+```javascript
+conn
+ .open({
+ user: "username",
+ accessToken: "token",
+ })
+ .then(() => {
+ console.log("login success");
+ })
+ .catch((reason) => {
+ console.log("login fail", reason);
+ });
+```
+
+### **用户 ID + 密码**登录是传统的登录方式。用户 ID 和密码均由你的终端用户自行决定,密码需要符合[密码规则要求](/document/server-side/account_system.html#开放注册单个用户)。
+
+```javascript
+conn
+ .open({
+ user: "username",
+ pwd: "password",
+ })
+ .then(() => {
+ console.log("login success");
+ })
+ .catch((reason) => {
+ console.log("login fail", reason);
+ });
+```
+
+## 退出登录
+
+```javascript
+conn.close();
+```
+
+## 多设备登录
+
+除了单端单设备登录,环信即时通讯 IM 支持同一账号在多端的多个设备上登录。多设备登录时,若同端设备数量超过限制,新登录的设备会将之前登录的设备踢下线。
+
+关于多设备登录场景中的设备数量限制、互踢策略以及信息同步,详见[多设备登录文档](multi_device.html)。
+
diff --git a/docs/document/web/message_modify.md b/docs/document/web/message_modify.md
index b0dec98d5..9f8836c75 100644
--- a/docs/document/web/message_modify.md
+++ b/docs/document/web/message_modify.md
@@ -27,7 +27,7 @@
开始前,请确保满足以下条件:
-- 完成 SDK 初始化,并连接到服务器,详见 [快速开始](quickstart.html) 及 [SDK 集成概述](overview.html)。
+- 完成 SDK 初始化,并连接到服务器,详见 [快速开始](quickstart.html) 及 [初始化](initialization.html)文档。
- 了解环信即时通讯 IM API 的使用限制,详见 [使用限制](/product/limitation.html)。
## 实现方法
diff --git a/docs/document/web/multi_device.md b/docs/document/web/multi_device.md
index ab13d456a..a19a666db 100644
--- a/docs/document/web/multi_device.md
+++ b/docs/document/web/multi_device.md
@@ -56,7 +56,7 @@ conn.getSelfIdsOnOtherPlatform().then((res) => {
初始化 SDK 时,你可以调用 `setLoginInfoCustomExt` 方法设置登录设备的自定义扩展信息。设置后,若因达到了登录设备数量限制而导致在已登录的设备上强制退出时(`206` 错误,`WEBIM_CONNCTION_USER_LOGIN_ANOTHER_DEVICE`),被踢设备收到的 `onDisconnected` 回调会包含导致该设备被踢下线的新登录设备的自定义扩展信息。
-:::notice
+:::tip
登录成功后才会将该设置发送到服务器。
:::
diff --git a/docs/document/web/quickstart.md b/docs/document/web/quickstart.md
index e98b54ff6..49a5e4b51 100644
--- a/docs/document/web/quickstart.md
+++ b/docs/document/web/quickstart.md
@@ -291,45 +291,4 @@ $ npm run build
$ npm run start:dev
```
-项目启动后,在页面输入用户名和密码进行注册,然后利用该用户名和密码登录。登录成功后,输入对方的用户名和要发送的消息,点击**发送**按钮发送消息,可同时打开另一页面相互收发消息。
-
-### 6. 参考信息
-
-可通过以下两种方式集成 SDK:
-
-#### 方法一:通过 npm 安装并导入 SDK
-
-1. 在 `package.json` 中的 `dependencies` 字段中加入 `easemob-websdk` 及对应版本:
-
-```json
-{
- "name": "web",
- "version": "1.0.0",
- "description": "",
- "main": "index.js",
- "scripts": {
- "test": "echo \"Error: no test specified\" && exit 1"
- },
- "dependencies": {
- "easemob-websdk": "latest"
- },
- "author": "",
- "license": "ISC"
-}
-```
-
-2. 在你的 `index.js` 文件中导入 `easemob-websdk` 模块:
-
-```JavaScript
-import WebIM from 'easemob-websdk'
-```
-
-#### 方法二:从官网获取并导入 SDK
-
-1. 下载 [Easemob Chat SDK for Web](https://www.easemob.com/download/im)。将 `demo/src/config` 中的 Easemob-chat 文件保存到你的项目下。
-
-2. 在 `index.html` 文件中,对 `index.js` 文件进行引用。
-
-```JavaScript
-
-```
+项目启动后,在页面输入用户名和密码进行注册,然后利用该用户名和密码登录。登录成功后,输入对方的用户名和要发送的消息,点击**发送**按钮发送消息,可同时打开另一页面相互收发消息。
\ No newline at end of file
diff --git a/docs/document/web/releasenote.md b/docs/document/web/releasenote.md
index 68635d65b..020efc42e 100644
--- a/docs/document/web/releasenote.md
+++ b/docs/document/web/releasenote.md
@@ -48,7 +48,7 @@
### 新增特性
- [IM SDK] 新增 `getSilentModeRemindTypeConversations` 方法,用于分页获取所有设置了推送通知方式的会话。
-- [IM SDK] 新增[从服务器拉取离线消息的开始和结束的事件回调](overview.html#连接状态相关): `onOfflineMessageSyncStart` 和 `onOfflineMessageSyncFinish`。
+- [IM SDK] 新增[从服务器拉取离线消息的开始和结束的事件回调](connection.html): `onOfflineMessageSyncStart` 和 `onOfflineMessageSyncFinish`。
- [IM SDK] 原消息置顶接口 `pinMessage` 和 `unpinMessage` [增加对单聊会话中置顶消息的支持](message_pin.html)。接口无变化。
- [IM SDK] `onMultiDeviceEvent` 新增以下两个离线推送相关的多设备通知事件:
- `setSilentModeForConversation`:若你调用了 `setSilentModeForConversation` API [设置指定会话的推送通知方式或免打扰时间](/document/web/push/push_notification_mode_dnd.html#设置单个会话的推送通知),其他设备会收到该事件。
@@ -69,13 +69,13 @@
### 新增特性
-- [IM SDK] 新增[日志上报](overview.html#日志上报)功能, 即将日志会上传到环信的服务器。该功能默认关闭,如有需要, 可联系商务开通。
+- [IM SDK] 新增[日志上报](log.html#日志上报)功能, 即将日志会上传到环信的服务器。该功能默认关闭,如有需要, 可联系商务开通。
## 版本 V4.8.0 Dev 2024-07-01
### 新增特性
-- [IM SDK] [`onDisconnected` 事件](overview.html#连接状态相关)新增断开原因回调参数, 告知用户触发 `onDisconnected` 的原因。
+- [IM SDK] [`onDisconnected` 事件](connection.html)新增断开原因回调参数, 告知用户触发 `onDisconnected` 的原因。
- [IM SDK] 新增[设备登录时允许携带自定义消息,并将其传递给被踢的设备](multi_device.html#设置登录设备的扩展信息):
- `setLoginInfoCustomExt`:设置登录设备的扩展信息。
- `onDisconnected`:多设备登录场景下,若当前设备被新登录设备踢下线,被踢设备收到的事件中会携带新设备的扩展信息。
@@ -96,7 +96,7 @@
- [IM SDK] 新增 `getJoinedChatRooms` 方法,用于[获取当前用户加入的聊天室列表](room_manage.html#获取当前用户加入的聊天室列表)。
- [IM SDK] [撤回消息](message_recall.html#实现方法)接口 `recallMessage` 中新增 `ext` 参数,支持传入自定义字符串,设置扩展信息。
-- [IM SDK] SDK logger 中新增 `setConsoleLogVisibility` 方法,用于[设置日志是否输出到控制台](overview.html#输出信息到日志文件)。
+- [IM SDK] SDK logger 中新增 `setConsoleLogVisibility` 方法,用于[设置日志是否输出到控制台](log.html#输出信息到日志文件)。
### 修复
diff --git a/docs/document/windows/connection.md b/docs/document/windows/connection.md
new file mode 100644
index 000000000..2f06217e1
--- /dev/null
+++ b/docs/document/windows/connection.md
@@ -0,0 +1,83 @@
+# 连接
+
+应用客户端成功连接到环信服务器后,才能使用环信即时通讯 SDK 的收发消息等功能。
+
+你调用 `loginWithToken` 或 `login` 方法登录后,客户端 SDK 会自动连接环信服务器。关于登录详情,请参见[登录文档](login.html)。
+
+## 监听连接状态
+
+你可以通过注册连接监听确认连接状态。
+
+```csharp
+
+// 监听器建议在初始化完成之后,登录之前设置,这样可确保收到登录通知。
+class ConnectionDelegate : IConnectionDelegate
+{
+ public void OnConnected()
+ {
+ }
+ public void OnDisconnected()
+ {
+ }
+ public void OnAuthFailed()
+ {
+ }
+ public void OnRemovedFromServer()
+ {
+ }
+ public void OnLoginTooManyDevice()
+ {
+ }
+ public void OnChangedIMPwd()
+ {
+ }
+ public void OnKickedByOtherDevice()
+ {
+ }
+ public void OnLoggedOtherDevice(string deviceName)
+ {
+ }
+ public void OnForbidByServer()
+ {
+ }
+ public void OnTokenExpired()
+ {
+ }
+ public void OnTokenWillExpire()
+ {
+ }
+ public void OnAppActiveNumberReachLimitation()
+ {
+ }
+ // 连接成功,开始从服务器拉取离线消息时触发。
+ // 注意:如果本次登录服务器没有离线消息,不会触发该回调。
+ public void OnOfflineMessageSyncStart()
+ {
+ }
+ // 离线用户上线后从服务器拉取离线消息结束时触发。
+ // 注意:如果再拉取离线过程中因网络或其他原因导致连接断开,不会触发该回调。
+ public void OnOfflineMessageSyncFinish()
+ {
+ }
+}
+// 添加连接监听器
+ConnectionDelegate connectionDelegate = new ConnectionDelegate();
+SDKClient.Instance.AddConnectionDelegate(connectionDelegate);
+
+// 移除连接监听器(退出程序时建议移除)
+SDKClient.Instance.DeleteConnectionDelegate(connectionDelegate);
+```
+
+## 自动重连
+
+登录后,如果由于网络信号弱、切换网络等引起的连接中断,SDK 会自动尝试重连。重连成功或者失败时分别会收到 `onConnected` 和 `onDisconnected` 通知。
+
+不过,SDK 在以下情况下会停止自动重连。你需要调用 `login` 方法登录。
+
+- 用户调用了 SDK 的登出方法 `logout` 主动退出登录。
+- 登录时鉴权错误,例如, token 无效(错误码 104)或已过期(错误码 108)。
+- 用户在其他的设备上更改了密码,导致此设备上自动登录失败,提示错误码 216。
+- 用户的账号被从服务器端删除,提示错误码 207。
+- 用户在另一设备登录,将当前设备上登录的用户踢出,提示错误码 206。
+- 用户登录设备数量超过限制,提示错误码 214。
+- 应用程序的日活跃用户数量(DAU)或月活跃用户数量(MAU)达到上限,提示错误码 8。
\ No newline at end of file
diff --git a/docs/document/windows/conversation_receipt.md b/docs/document/windows/conversation_receipt.md
new file mode 100644
index 000000000..cb856a118
--- /dev/null
+++ b/docs/document/windows/conversation_receipt.md
@@ -0,0 +1,79 @@
+# 会话已读回执
+
+会话已读回执指接收方进入会话页面,阅读会话中的所有消息后,调用接口向服务器发送会话已读回执,服务器将该回执回调给消息发送方,消息发送方将会收到会话已读回调。在多端多设备登录下,接收方的其他设备也会收到该回调。
+
+目前,单聊和群组聊天支持会话已读回执。本文介绍如何使用环信即时通讯 IM Windows SDK 实现会话已读回执功能。
+
+会话已读回执的效果示例,如下图所示:
+
+
+
+## 技术原理
+
+ 单聊会话已读回执实现的流程如下:
+
+ 1. 设置 `Options#RequireAck` 为 `true` 开启已读回执功能。
+ 2. 消息接收方进入会话页面,阅读消息后,调用 `SendConversationReadAck` 方法发送会话已读回执。
+ 3. 消息发送方通过监听 `OnConversationRead` 回调接收会话已读回执。
+
+## 前提条件
+
+开始前,请确保满足以下条件:
+
+- 完成 SDK 初始化,并连接到服务器,详见 [快速开始](quickstart.html)。
+- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。
+
+ ## 实现方法
+
+ 参考以下步骤在单聊中实现会话已读回执:
+
+ 1. 开启已读回执功能,即 SDK 初始化时设置 `Options#RequireAck` 为 `true`。
+
+ ```csharp
+// 设置是否需要接受方已读确认,默认为 true
+options.RequireAck = true;
+ ```
+
+ 2. 接收方发送会话已读回执。
+
+消息接收方进入会话页面,查看会话中是否有未读消息。若有,调用 `SendConversationReadAck` 方法发送会话已读回执,没有则不发送。该方法为异步方法。
+
+若会话中存在多条未读消息,建议调用该方法,因为若调用发送消息已读回执方法 `SendMessageReadAck`,则需要调用多次。
+
+```csharp
+SDKClient.Instance.ChatManager.SendConversationReadAck(conversationId, new CallBack(
+ onSuccess: () =>
+ {
+ },
+ onError: (code, desc) =>
+ {
+ }
+));
+```
+
+3. 消息发送方监听会话已读回执的回调。
+
+同一用户 ID 登录多设备的情况下,用户在一台设备上发送会话已读回执,其他设备会收到 `OnConversationRead` 回调。
+
+:::tip
+对于群组聊天,会话已读回执只用于清空服务端的群组会话的未读数,消息发送方不会通过 `OnConversationRead` 回调收到会话已读回执。
+:::
+
+```csharp
+public class MyDelegate : IChatManagerDelegate
+{
+ //...
+ public void OnConversationRead(string from, string to)
+ {
+ // 添加刷新页面通知等逻辑
+ }
+ //...
+}
+
+MyDelegate myDelegate = new MyDelegate();
+SDKClient.Instance.ChatManager.AddChatManagerDelegate(myDelegate);
+```
+
+## 会话已读回执和消息未读数
+
+消息接收方调用 `SendConversationReadAck` 方法发送会话已读回执,开发者可调用 `Conversation#MarkAllMessageAsRead` 方法将所有未读消息设置为已读,即将该会话的未读消息数清零。
diff --git a/docs/document/windows/initialization.md b/docs/document/windows/initialization.md
new file mode 100644
index 000000000..5fd987866
--- /dev/null
+++ b/docs/document/windows/initialization.md
@@ -0,0 +1,23 @@
+# SDK 初始化
+
+初始化是使用 SDK 的必要步骤,需在所有接口方法调用前完成。
+
+如果进行多次初始化操作,只有第一次初始化以及相关的参数生效。
+
+:::tip
+需要在主进程中进行初始化。
+:::
+
+## 前提条件
+
+有效的环信即时通讯 IM 开发者账号和 App key,详见[环信即时通讯云控制台的相关文档](enable_and_configure_IM.html#创建应用)。
+
+## 初始化
+
+初始化示例代码:
+
+```csharp
+var options = new Options("appkey"); //将该参数设置为你的 App Key
+//其他 Options 配置。
+SDKClient.Instance.InitWithOptions(options);
+```
diff --git a/docs/document/windows/integration.md b/docs/document/windows/integration.md
new file mode 100644
index 000000000..0812a41d6
--- /dev/null
+++ b/docs/document/windows/integration.md
@@ -0,0 +1,21 @@
+# 集成 SDK
+
+本文介绍如何将环信即时通讯 IM SDK 集成到你的 Windows 项目。
+
+## 开发环境要求
+
+- Windows SDK 1.0.5 或以上;
+- Visual Studio IDE 2019 或以上;
+- .Net Framework 4.5.2 或以上;
+- 目前 Windows SDK 仅支持 64 位运行模式;
+
+## 集成 SDK
+
+1.下载:点击 [Windows SDK](https://www.easemob.com/download/im) 进行下载,下载的 NuGet 包一般存放在 C:\Users\XXX\Downloads (XXX 为本机用户名);
+2.将下载的 NuGet 包拷贝到自己的工作目录,比如 D:\workspace\WinSDK 下,以下说明以此目录举例;
+3.在 Visual Studio 开发环境里,右键点击 windows-example 项目,选择 管理 NuGet 程序包 (N)...;
+4.在弹出的 NuGet:windows-example tab 页面里,点击右上角的小齿轮会弹出 NuGet 程序包源的设置窗体,点击窗体右上角的 + 按钮,在 包源 的文本框内会出现 Package source 这一栏,点击选中,并修改文本框下的 名称 和 源。例如 名称 可以设置为 Local Package source,源 则设置为第 2 步中的目录, D:\workspace\WinSDK,点击确定;
+5.在 NuGet:windows-example tab 页面,在右上角的 “程序包源” 处点击下拉菜单,选中刚刚配置的包源名称 Local Package source;
+6.在 NuGet:windows-example tab 页面上部,选中 浏览,在下面搜索框的右边,勾选 包括预发行版,此时下面的区域会出现 agora_chat_sdk (如果没有出现,点击搜索框右侧的刷新按),选中这一栏,右边会出现一个向下的小箭头,点击进行安装,或者点击右侧栏最右边的 安装 按钮;
+7.在弹出的 预览更改 窗体中,点击确定按钮;
+8.到此 Windows SDK 的 NuGet 包集成完毕。
\ No newline at end of file
diff --git a/docs/document/windows/log.md b/docs/document/windows/log.md
new file mode 100644
index 000000000..a66c613e5
--- /dev/null
+++ b/docs/document/windows/log.md
@@ -0,0 +1,21 @@
+# SDK 日志
+
+环信即时通讯 IM 日志记录 SDK 相关的信息和事件。环信技术支持团队帮你排查问题时可能会请你发送 SDK 日志。
+
+## 输出信息到日志文件
+
+默认情况下,SDK 最多可生成和保存三个文件,`easemob.log` 和两个 `easemob_YYYY-MM-DD_HH-MM-SS.log` 文件。这些文件为 UTF-8 编码,每个不超过 2 MB。SDK 会将最新的日志写入 `easemob.log` 文件,写满时则会将其重命名为对应时间点的 `easemob_YYYY-MM-DD_HH-MM-SS.log` 文件,若日志文件超过三个,则会删除最早的文件。
+
+例如,SDK 在 2024 年 1 月 1 日上午 8:00:00 记录日志时会生成 `easemob.log` 文件,若在 8:30:00 将 `easemob.log` 文件写满则会将其重命名为 `easemob_2024-01-01_08-30-00.log` 文件,随后在 9:30:30 和 10:30:30 分别生成了 `easemob_2024-01-01_09-30-30.log` 和 `easemob_2024-01-01_10-30-30.log` 文件,则此时 `easemob_2024-01-01_08-30-00.log` 文件会被移除。
+
+SDK 默认不输出调试信息(所有日志,包括调试信息、警告和错误),只需输出错误日志。若需调试信息,首先要开启调试模式。
+
+```csharp
+Options options = new Options("YourAppKey");
+options.DebugMode = true;
+SDKClient.Instance.InitWithOptions(options);
+```
+
+## 获取本地日志
+
+Windows SDK 日志位于可执行程序同级目录下的 `sdkdata\easemobLog` 目录中。
\ No newline at end of file
diff --git a/docs/document/windows/login.md b/docs/document/windows/login.md
new file mode 100644
index 000000000..48bc78e95
--- /dev/null
+++ b/docs/document/windows/login.md
@@ -0,0 +1,143 @@
+# 登录
+
+初始化 IM SDK 后,你需要首先调用接口登录。登录成功后,才能使用 IM 的功能。
+
+## 用户注册
+
+用户注册模式分为以下两种:
+
+- 开放注册:一般在体验 Demo 和测试环境时使用,正式环境中不推荐使用该方式注册环信账号。要使用开放注册,需要在[环信即时通讯云控制台](https://console.easemob.com/user/login)的**即时通讯** > **服务概览**的**设置**区域,将**用户注册模式**设置为**开放注册**。只有打开该开关,才能使用客户端或 [REST API](/document/server-side/account_system.html#开放注册单个用户)开放注册用户。
+
+示例代码如下所示:
+
+```csharp
+SDKClient.Instance.CreateAccount(username, password,
+ callback: new CallBack(
+
+ onSuccess: () => {
+ Debug.Log("CreateAccount succeed");
+ },
+
+ onError: (code, desc) => {
+ Debug.Log($"CreateAccount failed, code: {code} ; desc: {desc}");
+ }
+ )
+);
+```
+
+- 授权注册:通过环信提供的 REST API 注册环信用户账号,注册后保存到你的服务器或返给客户端。要使用授权注册,你需要在[环信即时通讯云控制台](https://console.easemob.com/user/login)的**即时通讯** > **服务概览**的**设置**区域,将**用户注册模式**设置为**授权注册**。相关的 REST API 介绍,详见[授权注册单个用户](/document/server-side/account_system.html#授权注册单个用户)和[批量授权注册用户](/document/server-side/account_system.html#批量授权注册用户)的接口介绍。
+
+除此以外,可以在[环信即时通讯云控制台](https://console.easemob.com/user/login)创建正式环境下和测试环境下的用户,详见[创建用户相关介绍](/product/enable_and_configure_IM.html#创建-im-用户)。
+
+## 主动登录
+
+1. **用户 ID + token** 是更加安全的登录方式。
+
+测试环境下,你在[环信即时通讯云控制台](https://console.easemob.com/user/login)创建用户后,环信服务器会自动为这些用户分配用户 Token,详见[测试环境下创建用户的介绍](/product/enable_and_configure_IM.html#测试环境)。
+
+使用 token 登录时需要处理 token 过期的问题,比如在每次登录时更新 token 等机制。
+
+```csharp
+SDKClient.Instance.LoginWithToken(username, token, true,
+ callback: new CallBack(
+
+ onSuccess: () =>
+ {
+ Debug.Log("login succeed");
+ },
+
+ onError: (code, desc) =>
+ {
+ if (code == 200)
+ {
+ Debug.Log("Already login.");;
+ }
+ else
+ {
+ Debug.Log($"login failed, code: {code} ; desc: {desc}");
+ }
+ }
+ )
+);
+```
+
+2. **用户 ID + 密码**登录是传统的登录方式。用户名和密码均由你的终端用户自行决定,密码需要符合[密码规则要求](/document/server-side/account_system.html#开放注册单个用户)。
+
+```csharp
+SDKClient.Instance.Login(username, password,
+ callback: new CallBack(
+
+ onSuccess: () =>
+ {
+ Debug.Log("login succeed");
+ },
+
+ onError: (code, desc) =>
+ {
+ if (code == 200)
+ {
+ Debug.Log("Already login.");;
+ }
+ else
+ {
+ Debug.Log($"login failed, code: {code} ; desc: {desc}");
+ }
+ }
+ )
+);
+
+```
+
+## 自动登录
+
+暂时不支持自动登录。
+
+## 获取当前登录的用户
+
+你可以调用 `SDKClient#CurrentUsername` 方法获取当前登录用户的用户 ID。
+
+## 获取登录状态
+
+你可以调用 `SDKClient#IsLoggedIn` 方法获取当前用户的登录状态。
+
+## 退出登录
+
+你可以调用 `Logout` 方法退出登录。退出登录后,你不会再收到其他用户发送的消息。
+
+异步方法:
+
+```csharp
+SDKClient.Instance.Logout(false,
+ callback: new CallBack(
+ onSuccess: () =>
+ {
+ Debug.Log("Logout succeed");
+ },
+
+ onError: (code, desc) =>
+ {
+ Debug.Log($"Logout failed, code:{code}, desc:{desc}");
+ }
+ )
+);
+```
+
+:::tip
+如果调用退出方法,在收到 `onSuccess` 回调后才能去调用 IM 相关方法,例如 `Login`。
+:::
+
+## 账号切换
+
+若在 app 中从当前账号切换到其他账号,你需要首先调用 `Logout` 方法登出,然后再调用 `LoginWithToken` 或 `Login` 方法登录。
+
+## 多设备登录
+
+除了单端单设备登录,环信即时通讯 IM 支持同一账号在多端的多个设备上登录。多设备登录时,若同端设备数量超过限制,新登录的设备会将之前登录的设备踢下线。
+
+关于多设备登录场景中的设备数量限制、互踢策略以及信息同步,详见[多设备登录文档](multi_device.html)。
+
+## 更多
+
+### 登录被封禁账号的提示
+
+在环信即时通讯控制台或调用 REST API 封禁用户账号后,若仍使用该账号登录,SDK会返回 "service is disabled"(305 错误), 可以根据用户这个返回值来进行相应的提示或者处理。
diff --git a/docs/document/windows/message_modify.md b/docs/document/windows/message_modify.md
index 034402cca..7bbd613a6 100644
--- a/docs/document/windows/message_modify.md
+++ b/docs/document/windows/message_modify.md
@@ -27,7 +27,7 @@
开始前,请确保满足以下条件:
-- 完成 SDK 初始化,并连接到服务器,详见 [快速开始](quickstart.html) 及 [SDK 集成概述](overview.html)。
+- 完成 SDK 初始化,并连接到服务器,详见 [初始化](initialization.html) 及 [连接](connection.html)。
- 了解环信即时通讯 IM API 的使用限制,详见 [使用限制](/product/limitation.html)。
## 实现方法
diff --git a/docs/document/windows/message_receipt.md b/docs/document/windows/message_receipt.md
index 89de77057..926e74438 100644
--- a/docs/document/windows/message_receipt.md
+++ b/docs/document/windows/message_receipt.md
@@ -1,239 +1,195 @@
-# 消息回执
+# 实现消息回执
-单聊会话支持消息送达回执、会话已读回执和消息已读回执,发送方发送消息后可及时了解接收方是否及时收到并阅读了信息,也可以了解整个会话是否已读。
+**单聊会话支持消息送达回执和消息已读回执**,发送方发送消息后可及时了解接收方是否及时收到并阅读了消息。
-群聊会话只支持消息已读回执。群成员在发送消息时,可以设置该消息是否需要已读回执。仅专业版及以上版本支持群消息已读回执功能。若要使用该功能,需在[环信即时通讯云控制台](https://console.easemob.com/user/login)开通,具体费用详见[产品价格](/product/pricing.html#增值服务费用)。
+**群聊会话只支持消息已读回执,不支持送达回执**。群成员在发送消息时,可以设置该消息是否需要已读回执。要使用该功能,你需要[在环信即时通讯云控制台上开通该功能](/product/enable_and_configure_IM.html#设置群消息已读回执),具体费用详见[产品价格](/product/pricing.html#增值服务费用)。
-:::tip
-仅单聊消息支持送达回执,群聊消息不支持。
-:::
+消息送达回执和已读回执的效果示例,如下图所示:
-本文介绍如何使用环信即时通讯 IM Windows SDK 实现单聊和群聊的消息回执功能。
+
## 技术原理
-环信即时通讯 IM Windows SDK 通过 `IChatManager` 类提供消息的送达回执和已读回执功能,包含的核心方法如下:
+使用环信即时通讯 IM Unity/Windows SDK 可以实现消息的送达回执与已读回执。
-- `Options.RequireDeliveryAck` 开启送达回执;
-- `IChatManager.SendConversationReadAck` 发出指定会话的已读回执;
-- `IChatManager.SendMessageReadAck` 发出指定单聊消息的已读回执;
-- `SendReadAckForGroupMessage` 发送群组消息的已读回执。
+- 单聊消息送达回执的逻辑如下:
-实现消息送达和已读回执的逻辑分别如下:
+ 1. 你可以通过设置 `Options#RequireDeliveryAck` 为 `true` 开启送达回执功能。
+ 2. 消息接收方收到消息后,SDK 自动向发送方触发送达回执。
+ 3. 消息发送方通过监听 `IChatManagerDelegate#OnMessagesDelivered` 回调接收消息送达回执。
-- 单聊消息送达回执
+- 单聊消息已读回执的逻辑如下:
- 1. 消息发送方在发送消息前通过 `ChatOptions.RequireDeliveryAck` 开启送达回执功能;
+ 1. 你可以通过设置 `Options#RequireAck` 为 `true` 开启已读回执功能。
+ 2. 消息接收方收到消息后,调用 `ChatManager#SendMessageReadAck` 方法发送消息已读回执。
+ 3. 消息发送方通过监听 `IChatManagerDelegate#OnMessagesRead` 回调接收消息已读回执。
- 2. 消息接收方收到消息后,SDK 自动向发送方触发送达回执;
+- 群聊消息已读回执的逻辑如下:
- 3. 消息发送方通过监听 `OnMessageDelivered` 回调接收消息送达回执。
-
-- 单聊会话及消息已读回执
-
- 1. 设置 `RequireAck` 为 `true`;
-
- 2. 消息接收方收到消息后,调用 API `SendConversationReadAck` 或 `SendMessageReadAck` 发送会话或消息已读回执;
-
- 3. 消息发送方通过监听 `OnConversationRead` 或 `OnMessageRead` 回调接收会话或消息已读回执。
-
-- 群聊只支持消息已读回执
-
- 1. 你可以通过设置 `isNeedGroupAck` 开启群聊消息已读回执功能;
-
- 2. 消息接收方收到消息后通过 `SendReadAckForGroupMessage` 发送群组消息的已读回执。
+ 1. 你可以通过设置 `Options#RequireAck` 为 `true` 开启消息已读回执功能。
+ 2. 发送方在群组中发送消息时设置 `Message#IsNeedGroupAck` 为 `true` 要求接收方返回消息已读回执。
+ 3. 接收方收到或阅读消息后通过 `ChatManager#SendReadAckForGroupMessage` 方法发送群组消息的已读回执。
## 前提条件
开始前,请确保满足以下条件:
-- 完成 SDK 初始化,并连接到服务器,详见 [快速开始](quickstart.html);
-- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html);
-- 群消息已读回执功能仅在环信 IM 专业版及以上版本支持该功能。若要使用该功能,需在[环信即时通讯云控制台](https://console.easemob.com/user/login)开通,具体费用详见[产品价格](/product/pricing.html#增值服务费用)。
+- 完成 SDK 初始化,并连接到服务器,详见 [快速开始](quickstart.html)。
+- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。
+- 要使用群消息已读回执功能,需在[环信即时通讯云控制台](https://console.easemob.com/user/login)开通,具体费用详见[产品价格](/product/pricing.html#增值服务费用)。
## 实现方法
-### 消息送达回执
+### 单聊消息送达回执
-1. 发送方若要接收消息送达回执,你需要将 `Options` 中的 `RequireDeliveryAck` 设为 `true`。当接收方收到消息后,SDK 底层会自动进行消息送达回执。
+1. 开启消息送达功能,即 SDK 初始化时将 `Options#RequireDeliveryAck` 设置为 `true`。
```csharp
-// 设置是否需要消息送达回执,设为 `true`。
-Options.RequireDeliveryAck = true;
+// 设置是否需要接收方送达确认,默认 `false` 即不需要。
+options.RequireDeliveryAck = true;
```
-2. 发送方监听事件 `OnMessagesDelivered` 回调,收到接收方的送达回执。
+2. 接收方收到消息后,SDK 自动向发送方触发送达回执。
+
+3. 发送方监听 `IChatManagerDelegate#OnMessagesDelivered` 事件,收到接收方的送达回执。你可以在收到该通知时,显示消息的送达状态。
```csharp
-// 继承并实现 `IChatManagerDelegate`。
-public class ChatManagerDelegate : IChatManagerDelegate {
+public class MyDelegate : IChatManagerDelegate
+{
+ //...
- // 收到已送达回执。
- public void OnMessagesDelivered(List messages)
- {
- }
+ // 收到消息。
+ public void OnMessagesReceived(List messages); {
+ }
+ // 收到已送达回执。
+ public void OnMessagesDelivered(List messages); {
}
-// 注册监听器。
-ChatManagerDelegate adelegate = new ChatManagerDelegate();
-SDKClient.Instance.ChatManager.AddChatManagerDelegate(adelegate);
-
-// 移除监听器。
-SDKClient.Instance.ChatManager.RemoveChatManagerDelegate(adelegate);
-```
+ //...
+}
-### 消息和会话的已读回执
+MyDelegate myDelegate = new MyDelegate();
-消息已读回执用于告知单聊或群聊中的用户接收方已阅读其发送的消息。为降低消息已读回执方法的调用次数,SDK 还支持在单聊中使用会话已读回执功能,用于获知接收方是否阅读了会话中的未读消息。
+//注册消息监听
+SDKClient.Instance.ChatManager.AddChatManagerDelegate(myDelegate);
+记得在不需要的时候移除 listener
+SDKClient.Instance.ChatManager.RemoveChatManagerDelegate(myDelegate);
+```
-#### 单聊
+### 单聊消息已读回执
-单聊既支持消息已读回执,也支持会话已读回执。我们建议你按照如下逻辑结合使用两种回执,减少发送消息已读回执数量。
+单聊既支持单条消息已读回执,也支持[会话已读回执](conversation_receipt.html)。我们建议你结合使用这两种回执:
-- 聊天页面未打开时,若有未读消息,进入聊天页面,发送会话已读回执;
-- 聊天页面打开时,若收到消息,发送消息已读回执。
+单聊消息的已读回执有效期与消息在服务端的存储时间一致,即在服务器存储消息期间均可发送已读回执。消息在服务端的存储时间与你订阅的套餐包有关,详见[产品价格](/product/pricing.html#套餐包功能详情)。
-第一步是在设置中打开已读回执开关:
+参考如下步骤在单聊中实现消息已读回执。
+1. App 开启已读回执功能,即 SDK 初始化时将 `Options#RequireAck` 设置为 `true`。
```csharp
-// 设置是否需要消息已读回执,设为 `true`。
-Options.RequireReadAck = true;
+// 设置是否需要接受方已读确认,默认为true
+options.RequireAck = true;
```
-##### 会话已读回执
-
-参考以下步骤在单聊中实现会话已读回执。
-
-1. 接收方发送会话已读回执。
+2. 接收方发送消息已读回执。
-消息接收方进入会话页面,查看会话中是否有未读消息。若有,发送会话已读回执,没有则不再发送。
+- 聊天页面未打开时,若有未读消息,进入聊天页面,发送会话已读回执。这种方式可避免发送多个消息已读回执。
```csharp
SDKClient.Instance.ChatManager.SendConversationReadAck(conversationId, new CallBack(
- onSuccess: () => {
-
- },
- onError:(code, desc) => {
-
- }
-));
-```
-
-2. 消息发送方监听会话已读回执的回调。
-
-```csharp
-// 继承并实现 `IChatManagerDelegate`。
-public class ChatManagerDelegate : IChatManagerDelegate {
- // 收到已读回执。`from` 表示发送该会话已读回执的消息接收方,`to` 表示收到该会话已读回执的消息发送方。
- public void OnConversationRead(string from, string to)
+ onSuccess: () =>
+ {
+ UIManager.SuccessAlert(transform);
+ },
+ onError: (code, desc) =>
{
+ UIManager.ErrorAlert(transform, code, desc);
}
-}
-
-// 注册监听器。
-ChatManagerDelegate adelegate = new ChatManagerDelegate()
-SDKClient.Instance.ChatManager.AddChatManagerDelegate(adelegate);
-
-// 移除监听器。
-SDKClient.Instance.ChatManager.RemoveChatManagerDelegate(adelegate);
+));
```
-同一用户 ID 登录多设备的情况下,用户在一台设备上发送会话已读回执,服务器会将会话的未读消息数置为 `0`,同时其他设备会收到 `OnConversationRead` 回调。
-
-##### 消息已读回执
-
-单聊消息的已读回执有效期与消息在服务端的存储时间一致,即在服务器存储消息期间均可发送已读回执。消息在服务端的存储时间与你订阅的套餐包有关,详见[产品价格](/product/pricing.html#套餐包功能详情)。
-
-参考如下步骤在单聊中实现消息已读回执。
-
-1. 接收方发送已读回执消息。
-
-消息接收方进入会话时,发送会话已读回执。
+- 聊天页面打开时,若收到消息,发送单条消息已读回执。
```csharp
-SDKClient.Instance.ChatManager.SendConversationReadAck(conversationId, new CallBack(
- onSuccess: () => {
-
- },
- onError:(code, desc) => {
+public class MyDelegate : IChatManagerDelegate
+{
+ //...
+ // 收到消息。
+ public void OnMessagesReceived(List messages); {
+ ......
+ SendReadAck(message);
+ ......
}
-));
-```
-
-2.在会话页面,接收到消息时,根据消息类型发送消息已读回执,如下所示:
-
-```csharp
-// 继承并实现 `IChatManagerDelegate`。
-public class ChatManagerDelegate : IChatManagerDelegate {
- // 收到已送达回执。
- public void OnMessageReceived(List messages)
- {
- ......
- sendReadAck(message);
- ......
- }
+ //...
}
+MyDelegate myDelegate = new MyDelegate();
-// 注册监听器。
-ChatManagerDelegate adelegate = new ChatManagerDelegate()
-SDKClient.Instance.ChatManager.AddChatManagerDelegate(adelegate);
+//注册消息监听
+SDKClient.Instance.ChatManager.AddChatManagerDelegate(myDelegate);
-// 发送已读回执。
-public void sendReadAck(Message message) {
+/**
+* 发送已读回执。
+* @param message
+*/
+public void SendReadAck(Message message)
+{
// 这里是接收的消息,未发送过已读回执且是单聊。
- if(message.Direction == MessageDirection.RECEIVE
- && !message.HasReadAck
- && message.MessageType == MessageType.Chat) {
+ if (message.Direction == MessageDirection.RECEIVE
+ && !message.HasReadAck
+ && message.MessageType == MessageType.Chat)
+ {
MessageBodyType type = message.Body.Type;
- // 视频、语音及文件需要点击后再发送,可根据需求进行调整。
- if(type == MessageBodyType.VIDEO || type == MessageBodyType.VOICE || type == MessageBodyType.FILE) {
+ // 视频,语音及文件需要点击后再发送,可以根据需求进行调整。
+ if (type == MessageBodyType.VIDEO || type == MessageBodyType.VOICE || type == MessageBodyType.FILE)
+ {
return;
}
-
SDKClient.Instance.ChatManager.SendMessageReadAck(message.MsgId, new CallBack(
- onSuccess: () => {
-
- },
- onError: (code, desc) => {
-
- }
- );
+ onSuccess: () =>
+ {
+ },
+ onError: (code, desc) =>
+ {
+ }
+ ));
}
}
```
3. 消息发送方监听消息已读回调。
-你可以调用接口监听指定消息是否已读,示例代码如下:
+消息发送方可以通过 `IChatManagerDelegate#OnMessagesRead` 事件监听指定消息是否已读,示例代码如下:
```csharp
-// 继承并实现 `IChatManagerDelegate`。
-public class ChatManagerDelegate : IChatManagerDelegate {
+public class MyDelegate : IChatManagerDelegate
+{
+ //...
- // 收到消息已读回执。
- public void OnMessagesRead(string from, string to)
- {
- }
+ public void OnMessagesRead(List messages); {
+ // 添加刷新消息等逻辑。
+ }
+
+ //...
}
-// 注册监听器。
-ChatManagerDelegate adelegate = new ChatManagerDelegate()
-SDKClient.Instance.ChatManager.AddChatManagerDelegate(adelegate);
-// 移除监听器。
-SDKClient.Instance.ChatManager.RemoveChatManagerDelegate(adelegate);
+MyDelegate myDelegate = new MyDelegate();
+
+//注册消息监听
+SDKClient.Instance.ChatManager.AddChatManagerDelegate(myDelegate);
+记得在不需要的时候移除 listener
+SDKClient.Instance.ChatManager.RemoveChatManagerDelegate(myDelegate);
```
-#### 群聊
+### 群聊消息已读回执
-对于群聊,群成员发送消息时,可以设置该消息是否需要已读回执。若需要,每个群成员在阅读消息后,SDK 均会发送已读回执,即阅读该消息的群成员数量即为已读回执的数量。
+对于群聊,群成员发送消息时,可以设置该消息是否需要已读回执。若需要,每个群成员阅读消息后,应该调用`ChatManager#SendReadAckForGroupMessage` 方法发送已读回执,阅读该消息的群成员数量即为已读回执的数量。
群消息已读回执特性的使用限制如下表所示:
@@ -243,69 +199,120 @@ SDKClient.Instance.ChatManager.RemoveChatManagerDelegate(adelegate);
| 使用权限 | 所有群成员 | 默认情况下,所有群成员发送消息时可要求已读回执。如果仅需群主和群管理员发消息时要求已读回执,可联系商务修改。 |
| 已读回执有效期 | 3 天 | 群聊已读回执的有效期为 3 天,即群组中的消息发送时间超过 3 天,服务器不记录阅读该条消息的群组成员,也不会发送已读回执。 |
| 群规模 | 200 人 | 该特性最大支持 200 人的群组。如果超过 200 人/群,群成员发送的消息不会返回已读回执。你可以联系商务提升群成员人数上限。 |
-| 查看返回已读回执数量 | 消息发送方 | 对消息返回的已读回执数量(或返回已读回执的人数),默认仅消息发送方可查看。如需所有群成员均可查看,可联系商务开通。 |
+| 查看返回已读回执数量 | 消息发送方 | 对消息返回的已读回执数量(或返回已读回执的人数),默认仅消息发送方可查看。如需所有群成员均可查看,可联系商务开通。 |
你可以按以下步骤实现群消息已读回执特性:
-1. 群成员发送消息时若需已读回执,需设置 `Message` 的 `IsNeedGroupAck` 为 `true`。
+1. 开启已读回执功能,即 SDK 初始化时将 `Options#RequireAck` 设置为 `true`。
+
+该功能开启后,接收方阅读消息后,SDK 底层会自动进行消息已读回执。
+```csharp
+// 设置是否需要接受方已读确认,默认为 `true`。
+options.RequireAck = true;
+```
+
+2. 发送方发送消息时设置 `Message#IsNeedGroupAck` 属性为 `true`。
+
+与单聊消息的 app 层级设置已读回执功能不同,群聊消息是在发送消息时设置指定消息是否需要已读回执。
```csharp
-Message msg = Message.CreateTextSendMessage("to", "hello world");
+Message msg = Message.CreateTextSendMessage(to, content);
msg.IsNeedGroupAck = true;
```
-2. 消息接收方发送群组消息的已读回执。
+3. 消息接收方发送群组消息的已读回执。
```csharp
-void SendReadAckForGroupMessage(string messageId, string ackContent)
-{
- SDKClient.Instance.ChatManager.SendReadAckForGroupMessage(messageId, ackContent,callback: new CallBack(
- onSuccess: () =>
- {
+public void sendAckMessage(EMMessage message) {
- },
- onError: (code, desc) =>
- {
+ if (message.HasReadAck) {
+ return;
+ }
- }
- ));
+ // 多设备登录时,无需再向自己发送的消息发送已读回执。
+ if (SDKClient.Instance.CurrentUsername.CompareTo(message.From)) {
+ return;
}
+
+ if (message.IsNeedGroupAck() && !message.IsRead) {
+ string to = message.ConversationId;
+ string msgId = message.MsgId;
+ SDKClient.Instance.ChatManager.SendReadAckForGroupMessage(message.MsgId, “”, new CallBack(
+ onSuccess: () =>
+ {
+ },
+ onError: (code, desc) =>
+ {
+ }
+ ));
+ message.IsRead = true;
+ }
+}
```
-3. 消息发送方监听群组消息已读回调。
+4. 消息发送方监听群组消息已读回调。
+
+群消息已读回调在 `IChatManagerDelegate#OnGroupMessageRead` 中实现。
-群组消息已读回调在消息监听类 `IChatManagerDelegate` 中实现。
+发送方接收到群组消息已读回执后,其发出消息的属性 `Message#GroupAckCount` 会有相应变化。
```csharp
-// 继承并实现 `IChatManagerDelegate`。
-public class ChatManagerDelegate : IChatManagerDelegate {
+public class MyDelegate : IChatManagerDelegate
+{
+ //...
+ // 接收到群组消息体的已读回执, 表明消息的接收方已经阅读此消息。
+ public void OnGroupMessageRead(List list); {
- // 收到群组消息的已读回执, 表明消息的接收方已阅读此消息。
- public void OnGroupMessageRead(List list)
- {
+ }
- }
+ //...
}
-// 注册监听器。
-ChatManagerDelegate adelegate = new ChatManagerDelegate()
-SDKClient.Instance.ChatManager.AddChatManagerDelegate(adelegate);
+MyDelegate myDelegate = new MyDelegate();
+
+//注册消息监听
+SDKClient.Instance.ChatManager.AddChatManagerDelegate(myDelegate);
+记得在不需要的时候移除 listener
+SDKClient.Instance.ChatManager.RemoveChatManagerDelegate(myDelegate);
```
-4. 消息发送方获取群组消息的已读回执详情。
+5. 消息发送方获取群组消息的已读回执详情。
-你可以调用 `FetchGroupReadAcks` 获取群组消息的已读回执的详情,示例代码如下:
+你可以调用 `ChatManager#FetchGroupReadAcks` 方法从服务器获取单条消息的已读回执的详情。
```csharp
-// startAckId:查询起始的已读回执 ID。首次调用为空,SDK 从最新的已读回执开始按服务器接收回执时间的逆序获取。后续调用从 CursorResult 中的 cursor 获取。
-// pageSize:每页获取群消息已读回执的条数。
-SDKClient.Instance.ChatManager.FetchGroupReadAcks(messageId, groupId, startAckId, pageSize, new ValueCallBack>(
- onSuccess: (list) =>
- {
- // 页面刷新等操作。
- },
- onError: (code, desc) =>
- {
- }
-));
+//messageId 消息 ID。
+//groupId 群组 ID。
+//pageSize 每页获取群消息已读回执的条数。取值范围[1,50]。
+//startAckId 已读回执的 ID,如果为空,从最新的回执向前开始获取。
+//callBack 结果回调,成功执行 {@link ValueCallBack#onSuccess(Object)},失败执行 {@link ValueCallBack#onError(int, String)}。
+public void FetchGroupReadAcks(string messageId, string groupId, int pageSize = 20, string startAckId = null, ValueCallBack> callback = null)
```
+
+### 查看消息送达和已读状态
+
+对于单聊消息,本地通过 `Message#HasDeliverAck` 字段存储消息送达状态。
+
+对于单聊消息,本地通过以下字段存储消息已读状态:
+
+| 字段 | 描述 |
+| :--------- | :----- |
+| `Message#IsRead` | 用户是否已读了该消息。如果是自己发送的消息,该字段的值固定为 `true`。|
+| `Message#HasReadAck` | 是否(消息接收方)已发送或(消息发送方)已收到消息已读回执。如果是自己发送的消息,记录的是对方是否已读。如果是对方的消息,则记录的是自己是否发送过已读回执。 |
+
+对于群聊消息,本地数据库通过以下字段存储消息已读状态:
+
+| 字段 | 描述 |
+| :--------- | :----- |
+| `Message#IsRead` | 用户是否已读了该消息。如果是自己发送的消息,该字段的值固定为 `true`。|
+| `Message#GroupAckCount` | 已阅读消息的群成员数量。 |
+
+### 已读回执与未读消息数
+
+- 会话已读回执发送后,开发者需要调用 `Conversation#MarkAllMessageAsRead` 方法将该会话的所有消息置为已读,即会话的未读消息数清零。
+
+- 消息已读回执发送后,开发者需要调用 `Conversation#MarkMessageAsRead` 方法将该条消息置为已读,则消息未读数会有变化。
+
+
+
+
diff --git a/docs/product/circle/category_mgmt_android.md b/docs/product/circle/category_mgmt_android.md
index 149f8d521..91b3ebdf8 100644
--- a/docs/product/circle/category_mgmt_android.md
+++ b/docs/product/circle/category_mgmt_android.md
@@ -24,7 +24,7 @@
开始前,请确保满足以下条件:
-- 完成 Circle SDK 的初始化,即完成 IM SDK 3.9.9.2 版本的初始化,详见 [IM SDK 初始化](/document/android/overview.html#sdk-初始化)
+- 完成 Circle SDK 的初始化,即完成 IM SDK 3.9.9.2 版本的初始化,详见 [IM SDK 初始化](/document/android/initialization.html)
- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。
- 了解 Circle 的使用限制,详见 [使用限制](circle_overview.html#限制条件)。
diff --git a/docs/product/circle/category_mgmt_ios.md b/docs/product/circle/category_mgmt_ios.md
index a9e367280..c1e831663 100644
--- a/docs/product/circle/category_mgmt_ios.md
+++ b/docs/product/circle/category_mgmt_ios.md
@@ -24,7 +24,7 @@
开始前,请确保满足以下条件:
-- 完成 Circle SDK 的初始化,即完成 IM SDK 3.9.9.1 版本的初始化,详见 [IM SDK 初始化](/document/ios/overview.html#sdk-初始化)。
+- 完成 Circle SDK 的初始化,即完成 IM SDK 3.9.9.1 版本的初始化,详见 [IM SDK 初始化](/document/ios/initialization.html)。
- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。
- 了解 Circle 的使用限制,详见 [使用限制](circle_overview.html#限制条件)。
diff --git a/docs/product/circle/category_mgmt_web.md b/docs/product/circle/category_mgmt_web.md
index 9df312ad5..30d362979 100644
--- a/docs/product/circle/category_mgmt_web.md
+++ b/docs/product/circle/category_mgmt_web.md
@@ -24,7 +24,7 @@
开始前,请确保满足以下条件:
-- 完成环信即时通讯 IM Web Circle SDK 的初始化。Circle SDK 初始化与 IM SDK 相同,详见 [IM SDK 初始化](/document/web/overview.html#sdk-初始化)。
+- 完成环信即时通讯 IM Web Circle SDK 的初始化。Circle SDK 初始化与 IM SDK 相同,详见 [IM SDK 初始化](/document/web/initialization.html)。
- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。
- 了解 Circle 的使用限制,详见 [使用限制](circle_overview.html#限制条件)。
diff --git a/docs/product/circle/channel_mgmt_android.md b/docs/product/circle/channel_mgmt_android.md
index 0048621d7..3f87feeee 100644
--- a/docs/product/circle/channel_mgmt_android.md
+++ b/docs/product/circle/channel_mgmt_android.md
@@ -23,7 +23,7 @@
开始前,请确保满足以下条件:
-- 完成 Circle SDK 的初始化,即完成 IM SDK 3.9.9.2 版本的初始化,详见 [IM SDK 初始化](/document/android/overview.html#sdk-初始化)。
+- 完成 Circle SDK 的初始化,即完成 IM SDK 3.9.9.2 版本的初始化,详见 [IM SDK 初始化](/document/android/initialization.html)。
- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。
- 了解 Circle 的使用限制,详见 [使用限制](circle_overview.html#限制条件)。
diff --git a/docs/product/circle/channel_mgmt_ios.md b/docs/product/circle/channel_mgmt_ios.md
index 3ed57bd18..8488472b1 100644
--- a/docs/product/circle/channel_mgmt_ios.md
+++ b/docs/product/circle/channel_mgmt_ios.md
@@ -23,7 +23,7 @@
开始前,请确保满足以下条件:
-- 完成 Circle SDK 的初始化,即完成 IM SDK 3.9.9.1 版本的初始化,详见 [IM SDK 初始化](/document/ios/overview.html#sdk-初始化)。
+- 完成 Circle SDK 的初始化,即完成 IM SDK 3.9.9.1 版本的初始化,详见 [IM SDK 初始化](/document/ios/initialization.html)。
- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。
- 了解 Circle 的使用限制,详见 [使用限制](circle_overview.html#限制条件)。
diff --git a/docs/product/circle/channel_mgmt_web.md b/docs/product/circle/channel_mgmt_web.md
index 2beb08c1e..a1fcac4ed 100644
--- a/docs/product/circle/channel_mgmt_web.md
+++ b/docs/product/circle/channel_mgmt_web.md
@@ -23,7 +23,7 @@
开始前,请确保满足以下条件:
-- 完成环信即时通讯 Web Circle SDK 的初始化。Circle SDK 初始化与 IM SDK 相同,详见 [IM SDK 初始化](/document/web/overview.html#sdk-初始化)。
+- 完成环信即时通讯 Web Circle SDK 的初始化。Circle SDK 初始化与 IM SDK 相同,详见 [IM SDK 初始化](/document/web/initialization.html)。
- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。
- 了解 Circle 的使用限制,详见 [使用限制](circle_overview.html#限制条件)。
diff --git a/docs/product/circle/server_mgmt_android.md b/docs/product/circle/server_mgmt_android.md
index 43c82a53e..57ebbc3f8 100644
--- a/docs/product/circle/server_mgmt_android.md
+++ b/docs/product/circle/server_mgmt_android.md
@@ -23,7 +23,7 @@
开始前,请确保满足以下条件:
-- 完成 Circle SDK 的初始化,即完成 IM SDK 3.9.9.2 版本的初始化,详见 [IM SDK 初始化](/document/android/overview.html#sdk-初始化)
+- 完成 Circle SDK 的初始化,即完成 IM SDK 3.9.9.2 版本的初始化,详见 [IM SDK 初始化](/document/android/initialization.html)
- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。
- 了解 Circle 的使用限制,详见 [使用限制](circle_overview.html#限制条件)。
diff --git a/docs/product/circle/server_mgmt_ios.md b/docs/product/circle/server_mgmt_ios.md
index 8614df223..d47e24cc7 100644
--- a/docs/product/circle/server_mgmt_ios.md
+++ b/docs/product/circle/server_mgmt_ios.md
@@ -23,7 +23,7 @@
开始前,请确保满足以下条件:
-- 完成 Circle SDK 的初始化,即完成 IM SDK 3.9.9.1 版本的初始化,详见 [IM SDK 初始化](/document/ios/overview.html#sdk-初始化)。
+- 完成 Circle SDK 的初始化,即完成 IM SDK 3.9.9.1 版本的初始化,详见 [IM SDK 初始化](/document/ios/initialization.html)。
- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。
- 了解 Circle 的使用限制,详见 [使用限制](circle_overview.html#限制条件)。
diff --git a/docs/product/circle/server_mgmt_web.md b/docs/product/circle/server_mgmt_web.md
index 009c1503c..6d5bc5e40 100644
--- a/docs/product/circle/server_mgmt_web.md
+++ b/docs/product/circle/server_mgmt_web.md
@@ -23,7 +23,7 @@
开始前,请确保满足以下条件:
-- 完成环信即时通讯 IM Web Circle SDK 的初始化。Circle SDK 初始化与 IM SDK 相同,详见 [IM SDK 初始化](/document/web/overview.html#sdk-初始化)。
+- 完成环信即时通讯 IM Web Circle SDK 的初始化。Circle SDK 初始化与 IM SDK 相同,详见 [IM SDK 初始化](/document/web/initialization.html)。
- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。
- 了解 Circle 的使用限制,详见 [使用限制](circle_overview.html#限制条件)。
diff --git a/docs/product/introduction.md b/docs/product/introduction.md
index f12b6163e..2f051c41f 100644
--- a/docs/product/introduction.md
+++ b/docs/product/introduction.md
@@ -20,7 +20,7 @@
| :--------- | :----- |
| 服务端集成 | [环信即时通讯 REST API 概览](/document/server-side/overview.html)。 |
| 客户端 Demo 体验 |
- [Android Demo(EaseIM App)](/document/android/demo.html)
- [iOS Demo(EaseIM App)](/document/ios/demo.html)
- [React Demo(WebIM)](/document/web/demo_react.html)
- [Vue Demo(WebIM)](/document/web/demo_vue.html) |
-| 客户端集成|
- [Android 快速开始](/document/android/quickstart.html) 和 [集成概述](/document/android/overview.html)
- [iOS 快速开始](/document/ios/quickstart.html)和 [集成概述](/document/ios/overview.html)
- [Web 快速开始](/document/web/quickstart.html)和[集成概述](/document/web/overview.html)
- [Windows 快速开始](/document/windows/quickstart.html)和 [集成概述](/document/windows/overview.html)
- [Linux 集成概述](/document/linux/overview.html)
- [Unity 快速开始](/document/unity/quickstart.html)和[集成概述](/document/unity/overview.html)
- [Flutter 快速开始](/document/flutter/quickstart.html)和[集成概述](/document/flutter/overview.html);
- [React Native 快速开始](/document/react-native/quickstart.html)和[集成概述](/document/react-native/overview.html)
- [Electron 集成概述](/document/electron/overview.html)
- [uni-app 集成概述](/document/applet/uniapp.html)|
+| 客户端集成|
- [Android 快速开始](/document/android/quickstart.html) 和 [集成概述](/document/android/integration.html)
- [iOS 快速开始](/document/ios/quickstart.html)和 [集成概述](/document/ios/integration.html)
- [Web 快速开始](/document/web/quickstart.html)和[集成概述](/document/web/integration.html)
- [Windows 快速开始](/document/windows/quickstart.html)和 [集成概述](/document/windows/integration.html)
- [Linux 集成概述](/document/linux/overview.html)
- [Unity 快速开始](/document/unity/quickstart.html)和[集成概述](/document/unity/integration.html)
- [Flutter 快速开始](/document/flutter/quickstart.html)和[集成概述](/document/flutter/integration.html);
- [React Native 快速开始](/document/react-native/quickstart.html)和[集成概述](/document/react-native/integration.html)
- [Electron 集成概述](/document/electron/overview.html)
- [uni-app 集成概述](/document/applet/uniapp.html)|
## 功能概述
diff --git a/docs/product/product_dynamics.md b/docs/product/product_dynamics.md
index a858d5432..08acae933 100644
--- a/docs/product/product_dynamics.md
+++ b/docs/product/product_dynamics.md
@@ -15,14 +15,14 @@
| 动态名称 | 动态描述 | 发布时间 | 相关文档 |
| :----- | :------- | :---------------- | :---------------- |
-| HarmonyOS SDK 1.4.0 开发版发布 | **新增特性**:
- 新增[置顶消息功能](/document/harmonyos/message_pin.html#消息置顶)。
- 新增[根据单个或多个消息类型,搜索本地数据库中所有会话或单个会话中的消息](/document/harmonyos/message_search.html#根据消息类型搜索会话消息)。
- 支持[获取 SDK 本地数据库中会话某个时间段内的全部消息数](/document/harmonyos/message_retrieve.html#获取会话在一定时间内的消息数)。
- 支持[会话推送通知方式的本地存储](/document/harmonyos/push/push_notification_mode_dnd.html#从服务器获取所有会话的推送通知方式设置),并支持从服务器获取所有会话的推送通知方式的设置。
- 支持[设备登录时携带自定义扩展信息并传递给被踢的设备](/document/harmonyos/multi_device.html#设置登录设备的扩展信息),应用于被踢设备展示提示信息或进行业务判断。
- 支持用户上线后从服务端拉取离线消息时[收到拉取开始和结束的通知](/document/harmonyos/overview.html#连接状态相关)。
- 支持[查看当前用户是否在群组禁言列表中](/document/harmonyos/group_members.html#检查自己是否在禁言列表中)。
- 支持[错误码 213 ChatError#USER_BIND_ANOTHER_DEVICE](/document/harmonyos/error.html),用于当用户达到登录设备上线时,当前设备无法登录的场景。
- 支持在撤回消息的事件中[返回被撤回的消息所属的会话 ID](/document/harmonyos/message_recall.html#设置消息撤回监听)。
- 支持[加入聊天室时携带扩展信息,并指定是否退出之前加入的全部聊天室](/document/harmonyos/room_manage.html#加入聊天室)。当用户加入聊天室携带了扩展信息时,聊天室内其他人可以在用户加入聊天室的回调中,获取到扩展信息。
- 支持[从服务端单向删除聊天室漫游消息](/document/harmonyos/message_delete.html#单向删除服务端的历史消息)。| 2024-09-30 | [HarmonyOS 1.4.0 更新日志](/document/harmonyos/releasenote.html#版本-v1-4-0-dev-2024-09-30-开发版) |
+| HarmonyOS SDK 1.4.0 开发版发布 | **新增特性**:
- 新增[置顶消息功能](/document/harmonyos/message_pin.html#消息置顶)。
- 新增[根据单个或多个消息类型,搜索本地数据库中所有会话或单个会话中的消息](/document/harmonyos/message_search.html#根据消息类型搜索会话消息)。
- 支持[获取 SDK 本地数据库中会话某个时间段内的全部消息数](/document/harmonyos/message_retrieve.html#获取会话在一定时间内的消息数)。
- 支持[会话推送通知方式的本地存储](/document/harmonyos/push/push_notification_mode_dnd.html#从服务器获取所有会话的推送通知方式设置),并支持从服务器获取所有会话的推送通知方式的设置。
- 支持[设备登录时携带自定义扩展信息并传递给被踢的设备](/document/harmonyos/multi_device.html#设置登录设备的扩展信息),应用于被踢设备展示提示信息或进行业务判断。
- 支持用户上线后从服务端拉取离线消息时[收到拉取开始和结束的通知](/document/harmonyos/connection.html)。
- 支持[查看当前用户是否在群组禁言列表中](/document/harmonyos/group_members.html#检查自己是否在禁言列表中)。
- 支持[错误码 213 ChatError#USER_BIND_ANOTHER_DEVICE](/document/harmonyos/error.html),用于当用户达到登录设备上线时,当前设备无法登录的场景。
- 支持在撤回消息的事件中[返回被撤回的消息所属的会话 ID](/document/harmonyos/message_recall.html#设置消息撤回监听)。
- 支持[加入聊天室时携带扩展信息,并指定是否退出之前加入的全部聊天室](/document/harmonyos/room_manage.html#加入聊天室)。当用户加入聊天室携带了扩展信息时,聊天室内其他人可以在用户加入聊天室的回调中,获取到扩展信息。
- 支持[从服务端单向删除聊天室漫游消息](/document/harmonyos/message_delete.html#单向删除服务端的历史消息)。| 2024-09-30 | [HarmonyOS 1.4.0 更新日志](/document/harmonyos/releasenote.html#版本-v1-4-0-dev-2024-09-30-开发版) |
| HarmonyOS SDK 1.3.0 开发版发布 | **新增特性**:
- HarmonyOS 端新增[群成员自定义属性](/document/harmonyos/group_members.html#管理群成员的自定义属性)功能。
- HarmonyOS 端新增[设置推送通知的显示内容](/document/harmonyos/push/push_display.html) 、[推送通知方式和免打扰模式功能](/document/harmonyos/push/push_notification_mode_dnd.html)。
- HarmonyOS 端新增[用户在线状态订阅](/document/harmonyos/presence.html)功能。
- 新增[聊天室自定义属性](/document/harmonyos/room_attributes.html#管理聊天室自定义属性-key-value)功能。 | 2024-09-09 | [HarmonyOS 1.3.0 更新日志](/document/harmonyos/releasenote.html#版本-v1-3-0-dev-2024-09-10-开发版) |
## 2024-08
| 动态名称 | 动态描述 | 发布时间 | 相关文档 |
| :----- | :------- | :---------------- | :---------------- |
-| SDK 4.9.0 开发版发布 | **新增特性**:
- 用户上线后从服务端拉取离线消息时,会[收到拉取开始和结束的通知](/document/android/overview.html#连接状态相关)。
- 单聊会话支持[消息置顶](/document/android/message_pin.html)。
- 移动端支持查看当前用户是否在指定的群组的禁言列表中。
- 移动端撤回消息后,你[收到的通知中会体现消息所属的会话 ID](/document/android/message_recall.html#设置消息撤回监听)。
- Web 端可[查看 app 下设置了推送通知方式(接收所有人通知、只接收 @ 我的通知和不接收任何通知)的所有会话](/document/web/push/push_notification_mode_dnd.html#获取设置了推送通知方式的所有会话)。
- 对于 Web 端,你若设置了指定会话的推送通知方式或免打扰时长或时间段,[其他设备会收到事件通知](/document/web/push/push_notification_mode_dnd.html#设置单个会话的推送通知)。
- 对于 Web 端,你若清除了会话的推送通知方式,[其他设备会收到事件通知](/document/web/push/push_notification_mode_dnd.html#清除单个会话的推送通知方式的设置)。| 2024-08-30 |
- [Android 4.9.0 更新日志](/document/android/releasenote.html#版本-v4-9-0-dev-2024-08-30-开发版)
- [iOS 4.9.0 更新日志](/document/ios/releasenote.html#版本-v4-9-0-dev-2024-08-30-开发版)
- [Web 4.9.0 更新日志](/document/web/releasenote.html#版本-v4-9-0-dev-2024-08-30-开发版) |
+| SDK 4.9.0 开发版发布 | **新增特性**:
- 用户上线后从服务端拉取离线消息时,会[收到拉取开始和结束的通知](/document/android/connection.html)。
- 单聊会话支持[消息置顶](/document/android/message_pin.html)。
- 移动端支持查看当前用户是否在指定的群组的禁言列表中。
- 移动端撤回消息后,你[收到的通知中会体现消息所属的会话 ID](/document/android/message_recall.html#设置消息撤回监听)。
- Web 端可[查看 app 下设置了推送通知方式(接收所有人通知、只接收 @ 我的通知和不接收任何通知)的所有会话](/document/web/push/push_notification_mode_dnd.html#获取设置了推送通知方式的所有会话)。
- 对于 Web 端,你若设置了指定会话的推送通知方式或免打扰时长或时间段,[其他设备会收到事件通知](/document/web/push/push_notification_mode_dnd.html#设置单个会话的推送通知)。
- 对于 Web 端,你若清除了会话的推送通知方式,[其他设备会收到事件通知](/document/web/push/push_notification_mode_dnd.html#清除单个会话的推送通知方式的设置)。| 2024-08-30 |
- [Android 4.9.0 更新日志](/document/android/releasenote.html#版本-v4-9-0-dev-2024-08-30-开发版)
- [iOS 4.9.0 更新日志](/document/ios/releasenote.html#版本-v4-9-0-dev-2024-08-30-开发版)
- [Web 4.9.0 更新日志](/document/web/releasenote.html#版本-v4-9-0-dev-2024-08-30-开发版) |
## 2024-07
@@ -33,7 +33,7 @@
| 动态名称 | 动态描述 | 发布时间 | 相关文档 |
| :----- | :------- | :---------------- | :---------------- |
| HarmonyOS SDK 1.2.0 开发版发布 |**新增特性**:
- HarmonyOS 端新增[表情回复 Reaction](/document/harmonyos/reaction.html)功能。
- HarmonyOS 端新增[会话标记](/document/harmonyos/conversation_mark.html)功能。
- HarmonyOS 端新增[会话置顶](/document/harmonyos/conversation_pin.html)功能。
- HarmonyOS 端新增[用户属性](/document/harmonyos/userprofile.html)功能。 | 2024-07-11 | [HarmonyOS 1.2.0 更新日志](/document/harmonyos/releasenote.html#版本-v1-2-0-dev-2024-07-11-开发版) |
-| HarmonyOS SDK 1.1.0 开发版发布 |**新增特性**:
- HarmonyOS 端新增[修改消息](/document/harmonyos/message_modify.html)功能。
- HarmonyOS 端新增[自定义消息](/document/harmonyos/message_send_receive.html#发送自定义类型消息)功能。
- HarmonyOS 端新增[合并转发消息](/document/harmonyos/message_send_receive.html#发送和接收合并消息)功能。
- HarmonyOS 端新增[离线推送](/document/harmonyos/overview.html)功能。 | 2024-07-01 | [HarmonyOS 1.1.0 更新日志](/document/harmonyos/releasenote.html#版本-v1-1-0-dev-2024-07-01-开发版) |
+| HarmonyOS SDK 1.1.0 开发版发布 |**新增特性**:
- HarmonyOS 端新增[修改消息](/document/harmonyos/message_modify.html)功能。
- HarmonyOS 端新增[自定义消息](/document/harmonyos/message_send_receive.html#发送自定义类型消息)功能。
- HarmonyOS 端新增[合并转发消息](/document/harmonyos/message_send_receive.html#发送和接收合并消息)功能。
- HarmonyOS 端新增[离线推送](/document/harmonyos/push/push_overview.html)功能。 | 2024-07-01 | [HarmonyOS 1.1.0 更新日志](/document/harmonyos/releasenote.html#版本-v1-1-0-dev-2024-07-01-开发版) |
## 2024-06
@@ -45,7 +45,7 @@
| 动态名称 | 动态描述 | 发布时间 | 相关文档 |
| :----- | :------- | :---------------- | :---------------- |
-| SDK 4.6.0 开发版发布 | **新增特性**:
- 客户端[消息撤回时支持携带自定义信息](/document/android/message_recall.html#实现方法)。
- 客户端支持离线期间撤回的消息通知给接收方。
- 移动端支持[自定义筛选获取本地会话列表](/document/android/conversation_list.html#获取本地所有或筛选的会话)。
- 移动端支持[清除内存中的会话](/document/android/conversation_list.html#清除内存中的会话),并举例说明如何[降低会话占用内存](/document/android/conversation_list.html#降低会话占用内存的实例)。
- Android 端添加绑定推送 token 成功与否的回调。
- Web/小程序端增加接口支持[获取当前用户加入和创建的聊天室](/document/web/room_manage.html#获取当前用户加入的聊天室列表)。
- Web/小程序 端支持 [logger 日志不显示在控制台](/document/web/overview.html#输出信息到日志文件)。
**重大变更**
1. **Android**:
从 V4.6.0 版本开始会启用 Kotlin 语言编写的新的 EaseIM App 项目与 EaseIMKIt 项目,老版本的项目将逐渐不再维护,请参考:
- [EaseIMKIt 文档](https://doc.easemob.com/uikit/chatuikit/android/chatuikit_overview.html)
- [EaseIM App 项目](https://github.com/easemob/chat-android-kotlin)
2. **iOS**:
从 V4.6.0 版本开始会启用 Swift 语言编写的新的 `EaseChatUIKit` 与 `EaseChatDemo`,老版本 Demo 和 UIKit 逐渐不再维护,请参考:
- [UIKit 文档](https://doc.easemob.com/uikit/chatuikit/ios/chatuikit_overview.html)
- [Demo 源码](https://github.com/easemob/chat-ios/tree/SwiftDemo) | 2024-04-30 |
- [Android 4.6.0 更新日志](/document/android/releasenote.html#版本-v4-6-0-dev-2024-04-30-开发版)
- [iOS 4.6.0 更新日志](/document/ios/releasenote.html#版本-v4-6-0-dev-2024-04-30-开发版)
- [Web 4.7.0 更新日志](/document/web/releasenote.html#版本-v4-7-0-dev-2024-04-30-开发版)
- [小程序 4.7.0 更新日志](/document/applet/releasenote.html#版本-v4-7-0-dev-2024-04-30-开发版)。 |
+| SDK 4.6.0 开发版发布 | **新增特性**:
- 客户端[消息撤回时支持携带自定义信息](/document/android/message_recall.html#实现方法)。
- 客户端支持离线期间撤回的消息通知给接收方。
- 移动端支持[自定义筛选获取本地会话列表](/document/android/conversation_list.html#获取本地所有或筛选的会话)。
- 移动端支持[清除内存中的会话](/document/android/conversation_list.html#清除内存中的会话),并举例说明如何[降低会话占用内存](/document/android/conversation_list.html#降低会话占用内存的实例)。
- Android 端添加绑定推送 token 成功与否的回调。
- Web/小程序端增加接口支持[获取当前用户加入和创建的聊天室](/document/web/room_manage.html#获取当前用户加入的聊天室列表)。
- Web/小程序 端支持 [logger 日志不显示在控制台](/document/web/log.html#输出信息到日志文件)。
**重大变更**
1. **Android**:
从 V4.6.0 版本开始会启用 Kotlin 语言编写的新的 EaseIM App 项目与 EaseIMKIt 项目,老版本的项目将逐渐不再维护,请参考:
- [EaseIMKIt 文档](https://doc.easemob.com/uikit/chatuikit/android/chatuikit_overview.html)
- [EaseIM App 项目](https://github.com/easemob/chat-android-kotlin)
2. **iOS**:
从 V4.6.0 版本开始会启用 Swift 语言编写的新的 `EaseChatUIKit` 与 `EaseChatDemo`,老版本 Demo 和 UIKit 逐渐不再维护,请参考:
- [UIKit 文档](https://doc.easemob.com/uikit/chatuikit/ios/chatuikit_overview.html)
- [Demo 源码](https://github.com/easemob/chat-ios/tree/SwiftDemo) | 2024-04-30 |
- [Android 4.6.0 更新日志](/document/android/releasenote.html#版本-v4-6-0-dev-2024-04-30-开发版)
- [iOS 4.6.0 更新日志](/document/ios/releasenote.html#版本-v4-6-0-dev-2024-04-30-开发版)
- [Web 4.7.0 更新日志](/document/web/releasenote.html#版本-v4-7-0-dev-2024-04-30-开发版)
- [小程序 4.7.0 更新日志](/document/applet/releasenote.html#版本-v4-7-0-dev-2024-04-30-开发版)。 |
| 动态名称 | 动态描述 | 发布时间 | 相关文档 |
| :----- | :------- | :---------------- | :---------------- |
diff --git a/docs/push/push_integration_note_android.md b/docs/push/push_integration_note_android.md
index 7da02ef29..a22124283 100644
--- a/docs/push/push_integration_note_android.md
+++ b/docs/push/push_integration_note_android.md
@@ -8,7 +8,7 @@
SDK 导入:[Android SDK 导入](/document/android/quickstart.html#_2-集成-sdk)
-注册登录:[注册登录](/document/android/overview.html#注册用户)
+注册登录:[注册登录](/document/android/login.html#用户注册)
**手机权限**
diff --git a/docs/uikit/chatuikit/web/chatuikit_conversation.md b/docs/uikit/chatuikit/web/chatuikit_conversation.md
index 943226bd7..44834cf90 100644
--- a/docs/uikit/chatuikit/web/chatuikit_conversation.md
+++ b/docs/uikit/chatuikit/web/chatuikit_conversation.md
@@ -302,8 +302,6 @@ const Conversation = () => {
};
```
-
-
diff --git a/docs/uikit/chatuikit/web/chatuikit_login.md b/docs/uikit/chatuikit/web/chatuikit_login.md
index 8a1c4f007..392707807 100644
--- a/docs/uikit/chatuikit/web/chatuikit_login.md
+++ b/docs/uikit/chatuikit/web/chatuikit_login.md
@@ -20,7 +20,7 @@ const App = () => {
};
```
-若要手动登录登出,你可以获取即时通讯 IM SDK connection 实例,然后[调用 SDK 的 API 进行登录登出](/document/web/overview.html#手动登录)。
+若要手动登录登出,你可以获取即时通讯 IM SDK connection 实例,然后[调用 SDK 的 API 进行登录登出](/document/web/login.html#登录方式)。
```javascript
import { useClient } from "easemob-chat-uikit";