mirror of
https://github.com/WuKongIM/WuKongIMDocs
synced 2025-06-03 07:42:48 +00:00
fix:update docs
This commit is contained in:
parent
431f565a44
commit
06031432a4
@ -130,7 +130,24 @@ export const sidebar: DefaultTheme.Sidebar = {
|
||||
"/sdk": [
|
||||
{ text: "概述", link: "/sdk/" },
|
||||
{ text: "iOS", link: "/sdk/ios" },
|
||||
{ text: "Android", link: "/sdk/android" },
|
||||
{
|
||||
text: "Android",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: "说明", link: "/sdk/android/intro" },
|
||||
{ text: "集成", link: "/sdk/android/integration" },
|
||||
{ text: "基础", link: "/sdk/android/base" },
|
||||
{ text: "消息管理", link: "/sdk/android/message" },
|
||||
{ text: "最近会话管理", link: "/sdk/android/conversation" },
|
||||
{ text: "频道管理", link: "/sdk/android/channel" },
|
||||
{ text: "频道成员管理", link: "/sdk/android/channel_member" },
|
||||
{ text: "提醒项管理", link: "/sdk/android/reminder" },
|
||||
{ text: "数据源管理", link: "/sdk/android/datasource" },
|
||||
{ text: "命令管理", link: "/sdk/android/cmd" },
|
||||
{ text: "高级功能", link: "/sdk/android/advance" },
|
||||
{ text: "示例代码", link: "https://github.com/WuKongIM/WuKongIMAndroidSDK" },
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "Javascript",
|
||||
collapsed: true,
|
||||
@ -146,7 +163,43 @@ export const sidebar: DefaultTheme.Sidebar = {
|
||||
]
|
||||
},
|
||||
{ text: "Uniapp", link: "/sdk/uniapp" },
|
||||
{ text: "Flutter", link: "/sdk/flutter" },
|
||||
{
|
||||
text: "Flutter",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: "说明", link: "/sdk/flutter/intro" },
|
||||
{ text: "集成", link: "/sdk/flutter/integration" },
|
||||
{ text: "基础", link: "/sdk/flutter/base" },
|
||||
{ text: "消息管理", link: "/sdk/flutter/message" },
|
||||
{ text: "最近会话管理", link: "/sdk/flutter/conversation" },
|
||||
{ text: "频道管理", link: "/sdk/flutter/channel" },
|
||||
{ text: "频道成员管理", link: "/sdk/flutter/channel_member" },
|
||||
{ text: "提醒项管理", link: "/sdk/flutter/reminder" },
|
||||
{ text: "数据源管理", link: "/sdk/flutter/datasource" },
|
||||
{ text: "命令管理", link: "/sdk/flutter/cmd" },
|
||||
{ text: "高级功能", link: "/sdk/flutter/advance" },
|
||||
{ text: "示例代码", link: "https://github.com/WuKongIM/WuKongIMFlutterSDK" },
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "HarmonyOS",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: "说明", link: "/sdk/harmonyos/intro" },
|
||||
{ text: "集成", link: "/sdk/harmonyos/integration" },
|
||||
{ text: "基础", link: "/sdk/harmonyos/base" },
|
||||
{ text: "消息管理", link: "/sdk/harmonyos/message" },
|
||||
{ text: "最近会话管理", link: "/sdk/harmonyos/conversation" },
|
||||
{ text: "频道管理", link: "/sdk/harmonyos/channel" },
|
||||
{ text: "频道成员管理", link: "/sdk/harmonyos/channel_member" },
|
||||
{ text: "提醒项管理", link: "/sdk/harmonyos/reminder" },
|
||||
{ text: "数据源管理", link: "/sdk/harmonyos/datasource" },
|
||||
{ text: "命令管理", link: "/sdk/harmonyos/cmd" },
|
||||
{ text: "高级功能", link: "/sdk/harmonyos/advance" },
|
||||
{ text: "示例代码", link: "https://github.com/WuKongIM/WuKongIMHarmonyOSSDK/tree/main/entry" },
|
||||
]
|
||||
},
|
||||
{ text: "c", link: "/sdk/c" },
|
||||
]
|
||||
};
|
||||
|
540
src/sdk/android/advance.md
Normal file
540
src/sdk/android/advance.md
Normal file
@ -0,0 +1,540 @@
|
||||
# 高级功能
|
||||
|
||||
### 自定义消息
|
||||
在WuKongIM 中所有的消息类型都是自定义消息
|
||||
#### 自定义普通消息
|
||||
下面我们以名片消息举例
|
||||
|
||||
##### 第一步 定义消息
|
||||
|
||||
定义消息对象并继承 `WKMessageContent` 并在构造方法中指定消息类型
|
||||
|
||||
- <font color='#999' size=2>SDK 内置消息类型可通过 `WKMsgContentType` 查看</font>
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
public class WKCardContent extends WKMessageContent {
|
||||
|
||||
public WKCardContent() {
|
||||
type = 3; //指定消息类型
|
||||
}
|
||||
// 定义需发送给对方的字段
|
||||
public String uid; // 用户ID
|
||||
public String name; // 名称
|
||||
public String avatar; // 头像
|
||||
}
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
class WKCardContent : WKMessageContent() {
|
||||
var uid: String = ""
|
||||
var name: String = ""
|
||||
var avatar: String = ""
|
||||
|
||||
init {
|
||||
type = 3; //指定消息类型
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- <strong><font color='red'>注意:自定义消息对象必须提供无参数的构造方法</font></strong>
|
||||
|
||||
##### 第二步 编码和解码
|
||||
|
||||
我们需要将`uid`,`name`,`avatar`三个字段信息发送给对方,最终传递的消息内容为
|
||||
|
||||
```json
|
||||
{
|
||||
"type": 3,
|
||||
"uid": "xxxx",
|
||||
"name": "xxx",
|
||||
"avatar": "xxx"
|
||||
}
|
||||
```
|
||||
|
||||
重写`WKMessageContent`的`encodeMsg`方法开始编码
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
@Override
|
||||
public JSONObject encodeMsg() {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
try {
|
||||
jsonObject.put("uid", uid);
|
||||
jsonObject.put("name", name);
|
||||
jsonObject.put("avatar", avatar);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return jsonObject;
|
||||
}
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
override fun encodeMsg(): JSONObject {
|
||||
val jsonObject = JSONObject()
|
||||
jsonObject.put("uid", uid)
|
||||
jsonObject.put("name", name)
|
||||
jsonObject.put("avatar", avatar)
|
||||
return jsonObject
|
||||
}
|
||||
```
|
||||
|
||||
重写`WKMessageContent`的`decodeMsg`方法开始解码
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
@Override
|
||||
public WKMessageContent decodeMsg(JSONObject jsonObject) {
|
||||
uid = jsonObject.optString("uid");
|
||||
name = jsonObject.optString("name");
|
||||
avatar = jsonObject.optString("avatar");
|
||||
return this;
|
||||
}
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
override fun decodeMsg(jsonObject: JSONObject): WKMessageContent {
|
||||
this.uid = jsonObject.optString("uid")
|
||||
this.name = jsonObject.optString("name")
|
||||
this.avatar = jsonObject.optString("avatar")
|
||||
return this
|
||||
}
|
||||
```
|
||||
|
||||
- <font color='#999' size=2>解码和编码消息时无需将 `type` 字段考虑其中,sdk 内部会自动处理</font>
|
||||
|
||||
如果您想控制该自定义消息在获取时显示的内容可重写 `getDisplayContent` 方法
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
@Override
|
||||
public String getDisplayContent() {
|
||||
return "[名片消息]";
|
||||
}
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
override fun getDisplayContent(): String {
|
||||
return "[名片消息]"
|
||||
}
|
||||
```
|
||||
|
||||
如果你想在全局搜索时能搜索到该类型的消息,可重写`getSearchableWord` 方法
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
@Override
|
||||
public String getSearchableWord() {
|
||||
return "[名片]";
|
||||
}
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```
|
||||
override fun getSearchableWord(): String {
|
||||
return "[名片]"
|
||||
}
|
||||
```
|
||||
|
||||
##### 第三步 注册消息
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
WKIM.getInstance().getMsgManager().registerContentMsg(WKCardContent.class);
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
WKIM.getInstance().msgManager.registerContentMsg(WKCardContent::class.java)
|
||||
```
|
||||
|
||||
对此通过这三步自定义普通消息就已完成。在收到消息时`WKMsg`中的type为3就表示该消息是名片消息,其中`baseContentMsgModel`则为自定义的`WKCardContent`,这时可将`baseContentMsgModel`强转为`WKCardContent`并渲染到UI上
|
||||
|
||||
#### 自定义附件消息
|
||||
|
||||
我们在发送消息的时候有时需发送带附件的消息。WuKongIM 也提供自定义附件消息,自定义附件消息和普通消息区别不大。下面我们已地理位置消息举例
|
||||
|
||||
##### 第一步 定义消息
|
||||
|
||||
值得注意的是自定义附件消息需继承`WKMediaMessageContent`而不是`WKMessageContent`
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
public class WKLocationContent extends WKMediaMessageContent {
|
||||
// 定义需发送给对方的字段
|
||||
public double longitude; // 经度
|
||||
public double latitude; // 纬度
|
||||
public String address; // 地址详细信息
|
||||
public WKLocationContent(double longitude, double latitude, String address) {
|
||||
type = 6;
|
||||
this.longitude = longitude;
|
||||
this.latitude = latitude;
|
||||
this.address = address;
|
||||
}
|
||||
// 这里必须提供无参数的构造方法
|
||||
public WKLocationContent() {
|
||||
type = 6;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
|
||||
class WKLocationContent(var longitude: Double, var latitude: Double, var address: String) :
|
||||
WKMediaMessageContent() {
|
||||
|
||||
init {
|
||||
type = 6 //指定消息类型
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- <font color='#999' size=2>`WKMediaMessageContent`提供了`url`,`localPath`字段,自定义消息无需在定义网络地址和本地地址字段</font>
|
||||
|
||||
##### 第二步 编码和解码
|
||||
|
||||
我们需要将`longitude`,`latitude`,`address`,`url`信息发送给对方,最终传递的消息内容为
|
||||
|
||||
```json
|
||||
{
|
||||
"type": 6,
|
||||
"longitude": 115.25,
|
||||
"latitude": 39.26,
|
||||
"url": "xxx",
|
||||
"address": "xxx"
|
||||
}
|
||||
```
|
||||
|
||||
重写`WKMessageContent`的`encodeMsg`方法开始编码
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
@Override
|
||||
public JSONObject encodeMsg() {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
try {
|
||||
jsonObject.put("address", address);
|
||||
jsonObject.put("latitude", latitude);
|
||||
jsonObject.put("longitude", longitude);
|
||||
jsonObject.put("url", url); // 位置截图
|
||||
jsonObject.put("localPath", localPath);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return jsonObject;
|
||||
}
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
override fun encodeMsg(): JSONObject {
|
||||
val jsonObject = JSONObject()
|
||||
jsonObject.put("longitude", longitude)
|
||||
jsonObject.put("latitude", latitude)
|
||||
jsonObject.put("address", address)
|
||||
jsonObject.put("url", url)
|
||||
jsonObject.put("localPath", localPath)
|
||||
return jsonObject
|
||||
}
|
||||
```
|
||||
|
||||
- <font color='#999' size=2>编码消息可以写入`localPath`本地字段,sdk 在保存完消息时发送给对方的消息是不包含该字段的</font>
|
||||
|
||||
重写`WKMessageContent`的`decodeMsg`方法开始解码
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
@Override
|
||||
public WKMessageContent decodeMsg(JSONObject jsonObject) {
|
||||
latitude = jsonObject.optDouble("latitude");
|
||||
longitude = jsonObject.optDouble("longitude");
|
||||
address = jsonObject.optString("address");
|
||||
url = jsonObject.optString("url");
|
||||
if (jsonObject.has("localPath"))
|
||||
localPath = jsonObject.optString("localPath");
|
||||
return this;
|
||||
}
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
override fun decodeMsg(jsonObject: JSONObject): WKMessageContent {
|
||||
this.latitude = jsonObject.optDouble("latitude")
|
||||
this.longitude = jsonObject.optDouble("longitude")
|
||||
this.address = jsonObject.optString("address")
|
||||
this.url = jsonObject.optString("url")
|
||||
if (jsonObject.has("localPath"))
|
||||
this.localPath = jsonObject.optString("localPath")
|
||||
return this
|
||||
}
|
||||
```
|
||||
|
||||
- <font color='#999' size=2>在解码消息时如果是解码本地字段需判断该字段是否存在,因为收到的消息并没有本地字段。如`localPath`在收到消息时是没有的</font>
|
||||
|
||||
##### 第三步 注册消息
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
WKIM.getInstance().getMsgManager().registerContentMsg(WKLocationContent.class);
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
WKIM.getInstance().msgManager.registerContentMsg(WKLocationContent::class.java)
|
||||
```
|
||||
|
||||
### 消息扩展
|
||||
|
||||
随着业务的发展应用在聊天中的功能也日益增多,为了满足绝大部分的需求 WuKongIM 中增加了消息扩展功能。消息扩展分`本地扩展`和`远程扩展`,本地扩展只针对 app 本地使用卸载 app 后将丢失,远程扩展是服务器保存卸载重装后数据将恢复
|
||||
|
||||
#### 本地扩展
|
||||
|
||||
本地扩展就是消息对象`WKMsg`中的`localExtraMap`字段
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
/**
|
||||
* 修改消息本地扩展
|
||||
*
|
||||
* @param clientMsgNo 客户端ID
|
||||
* @param hashExtra 扩展字段
|
||||
*/
|
||||
WKIM.getInstance().getMsgManager().updateLocalExtraWithClientMsgNo(String clientMsgNo, HashMap<String, Object> hashExtra);
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
WKIM.getInstance().msgManager.updateLocalExtraWithClientMsgNo( clientMsgNo,hashExtra)
|
||||
```
|
||||
|
||||
- <font color='#999' size=2>更新成功后 sdk 会触发刷新消息回调</font>
|
||||
|
||||
#### 远程扩展
|
||||
|
||||
远程扩展就是消息对象`WKMsg`中的`remoteExtra`字段
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
/**
|
||||
* 保存远程扩展
|
||||
* @param channel 某个channel信息
|
||||
* @param list 远程扩展数据
|
||||
*/
|
||||
WKIM.getInstance().getMsgManager().saveRemoteExtraMsg(WKChannel channel, List<WKSyncExtraMsg> list);
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
WKIM.getInstance().msgManager.saveRemoteExtraMsg(channel, list)
|
||||
```
|
||||
|
||||
- <font color='#999' size=2>更新成功后 sdk 会触发刷新消息回调</font>
|
||||
##### 数据结构说明
|
||||
```java
|
||||
public class WKMsgExtra {
|
||||
public String messageID; // 消息ID
|
||||
public String channelID; // 频道ID
|
||||
public byte channelType; // 频道类型
|
||||
public int readed; // 是否已读
|
||||
public int readedCount; // 消息已读数量
|
||||
public int unreadCount; // 消息未读数量
|
||||
public int revoke; // 消息是否撤回
|
||||
public int isMutualDeleted; // 是否删除
|
||||
public String revoker; // 消息撤回者uid
|
||||
public long extraVersion; // 版本号
|
||||
public long editedAt; // 消息编辑时间
|
||||
public String contentEdit; // 消息编辑内容
|
||||
public int needUpload; // 是否需要上传(这里指业务服务器)
|
||||
public int isPinned; // 是否置顶
|
||||
public WKMessageContent contentEditMsgModel; // 消息编辑内容体
|
||||
}
|
||||
```
|
||||
### 消息已读未读
|
||||
|
||||
消息的已读未读又称消息回执。消息回执功能可通过 setting 进行设置
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
WKMsgSetting setting = new WKMsgSetting();
|
||||
setting.receipt = 1; // 开启回执
|
||||
|
||||
WKSendOptions options = new WKSendOptions();
|
||||
options.setting = setting;
|
||||
// 发送消息
|
||||
WKIM.getInstance().getMsgManager().sendWithOptions(@NonNull WKMessageContent contentModel, @NonNull WKChannel channel, @NonNull WKSendOptions options);
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
val setting = WKMsgSetting()
|
||||
setting.receipt = 1 // 开启回执
|
||||
val options = WKSendOptions()
|
||||
options.setting = setting
|
||||
// 发送消息
|
||||
WKIM.getInstance().msgManager.sendWithOptions(
|
||||
wkBaseContentMsgModel,channel,options
|
||||
)
|
||||
```
|
||||
|
||||
当登录用户浏览过对方发送的消息时,如果对方开启了消息回执这时需将查看过的消息上传到服务器标记该消息已读。当对方或者自己上传过已读消息这时服务器会下发同步消息扩展的 cmd(命令)消息`syncMessageExtra`,此时需同步最新消息扩展保存到 sdk 中
|
||||
|
||||
|
||||
### 消息编辑
|
||||
当我们给对方发送消息发现发送内容有错误时,这时无需撤回重发只需要将消息编辑即可
|
||||
|
||||
<video controls height='30%' width='30%' src="/video/msgedit.mp4"></video>
|
||||
|
||||
|
||||
#### 设置编辑内容
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
/**
|
||||
* 修改编辑内容
|
||||
* @param msgID 消息服务器ID
|
||||
* @param channelID 频道ID
|
||||
* @param channelType 频道类型
|
||||
* @param content 编辑后的内容
|
||||
*/
|
||||
WKIM.getInstance().getMsgManager().updateMsgEdit(String msgID, String channelID, byte channelType, String content);
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
WKIM.getInstance().msgManager.updateMsgEdit(msgID,channelID,channelType,content)
|
||||
```
|
||||
|
||||
更改 sdk 消息编辑内容后需将编辑后的内容上传到服务器,则需要监听上传消息扩展
|
||||
|
||||
#### 监听上传消息扩展
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
//监听上传消息扩展
|
||||
WKIM.getInstance().getMsgManager().addOnUploadMsgExtraListener(new IUploadMsgExtraListener() {
|
||||
@Override
|
||||
public void onUpload(WKMsgExtra msgExtra) {
|
||||
// 上传到自己的服务器
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
WKIM.getInstance().msgManager.addOnUploadMsgExtraListener(object :IUploadMsgExtraListener{
|
||||
override fun onUpload(msgExtra: WKMsgExtra) {
|
||||
// 上传到服务器
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
### 消息回复
|
||||
|
||||
在聊天中如果消息过多,发送消息回复就会显得消息很乱无章可循。这时就需要对某条消息进行特定的回复,即消息回复,如以下效果 <img src='./msg_reply.jpg' width=30%/>
|
||||
|
||||
在发送消息时,只需将消息正文`WKMessageContent`中的`WKReply`对象赋值就能对达到消息回复效果
|
||||
|
||||
`WKReply` 对象核心字段
|
||||
|
||||
```java
|
||||
public class WKReply {
|
||||
// 被回复的消息根ID,多级回复时的第一次回复的消息ID
|
||||
public String root_mid;
|
||||
// 被回复的消息ID
|
||||
public String message_id;
|
||||
// 被回复的MessageSeq
|
||||
public long message_seq;
|
||||
// 被回复者uid
|
||||
public String from_uid;
|
||||
// 被回复者名称
|
||||
public String from_name;
|
||||
// 被回复的消息体
|
||||
public WKMessageContent payload;
|
||||
// 被回复消息编辑后的内容
|
||||
public String contentEdit;
|
||||
// 被回复消息编辑后的消息实体
|
||||
public WKMessageContent contentEditMsgModel;
|
||||
// 编辑时间
|
||||
public long editAt;
|
||||
}
|
||||
```
|
||||
|
||||
### 消息回应(点赞)
|
||||
|
||||
#### 保存
|
||||
`java`
|
||||
```java
|
||||
// 保存消息回应
|
||||
WKIM.getInstance().getMsgManager().saveMessageReactions(List<WKSyncMsgReaction> list)
|
||||
```
|
||||
`kotlin`
|
||||
```kotlin
|
||||
// 保存消息回应
|
||||
WKIM.getInstance().msgManager.saveMessageReactions(list)
|
||||
```
|
||||
|
||||
- <font color='#999' size=2>同一个用户对同一条消息只能做出一条回应。重复进行消息不同 emoji 的回应会做为修改回应,重复进行相同 emoji 的回应则做为删除回应</font> sdk 更新消息回应后会触发消息刷新的事件。app 需监听此事件并对 UI 进行刷新
|
||||
|
||||
#### 获取
|
||||
`java`
|
||||
```java
|
||||
// 获取某条消息的回应
|
||||
WKIM.getInstance().getMsgManager().getMsgReactions(String messageID);
|
||||
```
|
||||
`kotlin`
|
||||
```kotlin
|
||||
// 获取某条消息的回应
|
||||
WKIM.getInstance().msgManager.getMsgReactions(messageID)
|
||||
```
|
||||
|
||||
#### 数据结构说明
|
||||
```java
|
||||
|
||||
public class WKMsgReaction {
|
||||
public String messageID; // 消息ID
|
||||
public String channelID; // 频道ID
|
||||
public byte channelType; // 频道类型
|
||||
public String uid; // 用户ID
|
||||
public long seq; // 消息序列号
|
||||
public String emoji; // 表情
|
||||
public int isDeleted; // 是否删除
|
||||
public String createdAt; // 创建时间
|
||||
}
|
||||
```
|
||||
|
113
src/sdk/android/base.md
Normal file
113
src/sdk/android/base.md
Normal file
@ -0,0 +1,113 @@
|
||||
# 基础
|
||||
|
||||
### 初始化
|
||||
|
||||
在 Application 的 onCreate 方法中初始化 SDK
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
/**
|
||||
* 初始化IM
|
||||
* @param context Application Context
|
||||
* @param uid 登录用户ID(业务服务端在IM通讯端登记了的uid))
|
||||
* @param token 登录用户token(业务服务端在IM通讯端登记了的token)
|
||||
*/
|
||||
WKIM.getInstance().init(context, uid, token);
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
WKIM.getInstance().init(context,uid,token)
|
||||
```
|
||||
|
||||
监听获取连接服务器 IP 和 Port 的事件
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
WKIM.getInstance().getConnectionManager().addOnGetIpAndPortListener(new IGetIpAndPort() {
|
||||
@Override
|
||||
public void getIP(IGetSocketIpAndPortListener iGetSocketIpAndPortListener) {
|
||||
// 返回连接IP和端口
|
||||
iGetSocketIpAndPortListener.onGetSocketIpAndPort("xxx",xxx);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
WKIM.getInstance().connectionManager.addOnGetIpAndPortListener { p0 ->
|
||||
p0!!.onGetSocketIpAndPort(
|
||||
"172.0.0.0",
|
||||
6666
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
- <font color="#999" font-size=2>返回 IM 通信端的 IP 和 IM 通信端的 TCP 端口。<font color="#FF0000">分布式可调用接口获取 IP 和 Port 后返回</font></font>
|
||||
|
||||
### 连接与断开
|
||||
|
||||
#### 连接与断开 IM
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
// 连接IM
|
||||
WKIM.getInstance().getConnectionManager().connection();
|
||||
|
||||
// 断开IM
|
||||
WKIM.getInstance().getConnectionManager().disconnect(isLogout);
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
// 连接IM
|
||||
WKIM.getInstance().connectionManager.connection()
|
||||
|
||||
// 断开IM
|
||||
WKIM.getInstance().connectionManager.disconnect(isLogout)
|
||||
```
|
||||
|
||||
- <font color='#999'>isLogout: true:SDK 将不再进行重连 false:SDK 保持重连机制</font>
|
||||
|
||||
#### 连接状态监听
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
WKIM.getInstance().getConnectionManager().addOnConnectionStatusListener("key", new IConnectionStatus() {
|
||||
@Override
|
||||
public void onStatus(int status, String reason) {
|
||||
if(status == WKConnectStatus.success){
|
||||
// 连接成功
|
||||
}else if(status == WKConnectStatus.failed){
|
||||
// 连接失败
|
||||
}else if(status == WKConnectStatus.connecting){
|
||||
// 连接中
|
||||
} else if(status == WKConnectStatus.syncMsg){
|
||||
// 同步消息中
|
||||
}else if(status == WKConnectStatus.noNetwork){
|
||||
// 无网络
|
||||
}else if(status == WKConnectStatus.kicked){
|
||||
// 被踢下线 需退出应用回到登录页面
|
||||
}
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
WKIM.getInstance().connectionManager.addOnConnectionStatusListener(
|
||||
"key"
|
||||
) { code, reason ->
|
||||
if (code == WKConnectStatus.success){
|
||||
// 连接成功
|
||||
}
|
||||
}
|
||||
```
|
188
src/sdk/android/channel.md
Normal file
188
src/sdk/android/channel.md
Normal file
@ -0,0 +1,188 @@
|
||||
# 频道管理
|
||||
|
||||
频道(Channel)WuKongIM 中是一个比较抽象的概念。发送消息都是先发送给频道,频道根据自己的配置规则进行投递消息,频道分频道和频道详情。 更多介绍请移步[什么是频道](/guide/initialize#频道)
|
||||
|
||||
### 数据源
|
||||
|
||||
`需要实现获取频道资料的数据源` [获取频道资料数据源](/sdk/android/datasource.html#频道资料数据源)
|
||||
### 频道资料
|
||||
#### 获取频道资料
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
// 获取channel信息 先获取内存 如果没有再从数据库获取
|
||||
WKIM.getInstance().getChannelManager().getChannel(String channelID, byte channelType)
|
||||
|
||||
// 从远程服务器获取channel信息
|
||||
WKIM.getInstance().getChannelManager().fetchChannelInfo(String channelID, byte channelType)
|
||||
|
||||
// 批量导入频道信息 该方法会触发channel刷新事件
|
||||
WKIM.getInstance().getChannelManager().addOrUpdateChannels(List<WKChannel> list);
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
// 获取channel信息 先获取内存 如果没有再从数据库获取
|
||||
WKIM.getInstance().channelManager.getChannel(channelID,channelType)
|
||||
|
||||
// 从远程服务器获取channel信息
|
||||
WKIM.getInstance().channelManager.fetchChannelInfo(channelID,channelType)
|
||||
|
||||
// 批量导入频道信息 该方法会触发channel刷新事件
|
||||
WKIM.getInstance().channelManager.addOrUpdateChannels(list)
|
||||
```
|
||||
#### 强制刷新频道资料
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
// 从远程服务器获取channel信息
|
||||
WKIM.getInstance().getChannelManager().fetchChannelInfo(String channelID, byte channelType)
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
// 从远程服务器获取channel信息
|
||||
WKIM.getInstance().channelManager.fetchChannelInfo(channelID,channelType)
|
||||
```
|
||||
|
||||
### 事件
|
||||
#### 刷新频道资料
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
// 监听channel刷新事件
|
||||
WKIM.getInstance().getChannelManager().addOnRefreshChannelInfo("key", new IRefreshChannel() {
|
||||
@Override
|
||||
public void onRefreshChannel(WKChannel channel, boolean isEnd) {
|
||||
//
|
||||
}
|
||||
});
|
||||
// 移除监听
|
||||
WKIM.getInstance().getChannelManager().removeRefreshChannelInfo("key");
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
// 监听channel刷新事件
|
||||
WKIM.getInstance().channelManager.addOnRefreshChannelInfo("key", object : IRefreshChannel {
|
||||
override fun onRefreshChannel(channel: WKChannel, isEnd: Boolean) {
|
||||
//
|
||||
}
|
||||
})
|
||||
|
||||
// 移除监听
|
||||
WKIM.getInstance().channelManager.removeRefreshChannelInfo("key");
|
||||
```
|
||||
|
||||
- <font color='#999' size=2>注:key为监听的唯一标识,可以为任意字符串,添加监听和移出监听时需要传入相同的key</font>
|
||||
|
||||
#### 频道头像更新
|
||||
`java`
|
||||
```java
|
||||
// 监听频道头像更新事件
|
||||
WKIM.getInstance().getChannelManager().addOnRefreshChannelAvatar( new IRefreshChannelAvatar() {
|
||||
@Override
|
||||
public void onRefreshChannelAvatar(String channelID, byte channelType) {
|
||||
// 头像需要本地修改
|
||||
String key = UUID.randomUUID().toString().replace("-", "");
|
||||
WKIM.getInstance().getChannelManager().updateAvatarCacheKey(s, b, key);
|
||||
}
|
||||
});
|
||||
```
|
||||
`kotlin`
|
||||
```kotlin
|
||||
// 监听频道头像更新事件
|
||||
WKIM.getInstance().channelManager.addOnUpdateChannelAvatar("key", object : IRefreshChannelAvatar {
|
||||
override fun onRefreshChannelAvatar(channelID: String, channelType: Int) {
|
||||
//
|
||||
}
|
||||
})
|
||||
|
||||
// 移除监听
|
||||
WKIM.getInstance().channelManager.removeUpdateChannelAvatar("key");
|
||||
```
|
||||
|
||||
### 常用方法
|
||||
#### 修改备注
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
// 修改频道备注
|
||||
WKIM.getInstance().getChannelManager().updateRemark(String channelID, byte channelType, String remark)
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
// 修改频道备注
|
||||
WKIM.getInstance().channelManager.updateRemark(channelID, channelType, remark)
|
||||
```
|
||||
|
||||
#### 置顶/取消置顶
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
// 置顶频道 1.置顶 0.取消置顶
|
||||
WKIM.getInstance().getChannelManager().updateTop(String channelID, byte channelType, int isTop)
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
// 置顶频道
|
||||
WKIM.getInstance().channelManager.setTopChannel(channelID, channelType, isTop)
|
||||
```
|
||||
#### 保存频道资料
|
||||
`java`
|
||||
```java
|
||||
// 保存频道资料
|
||||
WKIM.getInstance().getChannelManager().saveOrUpdateChannel(WKChannel channel)
|
||||
|
||||
// 批量保存频道资料
|
||||
WKIM.getInstance().getChannelManager().saveOrUpdateChannels(List<WKChannel> list)
|
||||
```
|
||||
`kotlin`
|
||||
```kotlin
|
||||
// 保存频道资料
|
||||
WKIM.getInstance().channelManager.saveOrUpdateChannel(channel)
|
||||
|
||||
// 批量保存频道资料
|
||||
WKIM.getInstance().channelManager.saveOrUpdateChannels( list)
|
||||
```
|
||||
|
||||
### 数据结构说明
|
||||
|
||||
#### 频道属性
|
||||
|
||||
```java
|
||||
public class WKChannel {
|
||||
// 频道ID
|
||||
public String channelID;
|
||||
// 频道类型 1.为单聊 2.为群聊
|
||||
public byte channelType;
|
||||
// 频道名称
|
||||
public String channelName;
|
||||
// 频道备注(频道的备注名称,个人的话就是个人备注,群的话就是群别名)
|
||||
public String channelRemark;
|
||||
// 频道头像
|
||||
public String avatar;
|
||||
// 是否置顶
|
||||
public int top;
|
||||
// 免打扰
|
||||
public int mute;
|
||||
// 是否禁言
|
||||
public int forbidden;
|
||||
// 远程扩展
|
||||
public HashMap remoteExtraMap;
|
||||
// 本地扩展字段
|
||||
public HashMap extraMap;
|
||||
}
|
||||
```
|
108
src/sdk/android/channel_member.md
Normal file
108
src/sdk/android/channel_member.md
Normal file
@ -0,0 +1,108 @@
|
||||
# 频道成员管理
|
||||
|
||||
### 获取频道成员列表
|
||||
#### 获取成员
|
||||
`java`
|
||||
```java
|
||||
// 获取频道内所有成员
|
||||
WKIM.getInstance().getChannelMembersManager().getMembers(channelId,channelType);
|
||||
|
||||
// 单个频道成员
|
||||
WKIM.getInstance().getChannelMembersManager().getMembers(channelId,channelType,uid);
|
||||
```
|
||||
`kotlin`
|
||||
```kotlin
|
||||
// 获取频道内所有成员
|
||||
WKIM.getInstance().channelMembersManager().getMembers(channelId,channelType);
|
||||
|
||||
// 单个频道成员
|
||||
WKIM.getInstance().channelMembersManager().getMembers(channelId,channelType,uid);
|
||||
|
||||
```
|
||||
#### 搜索成员
|
||||
|
||||
`需要实现频道成员数据源` [频道成员数据源](/sdk/android/datasource.html#频道成员数据源)
|
||||
|
||||
`java`
|
||||
```java
|
||||
// 搜索频道成员列表
|
||||
WKIM.getInstance().getChannelMembersManager().getWithPageOrSearch(channelId, channelType, "keyword", 1, 20, (list, isRemote) -> {
|
||||
// list 成员列表
|
||||
// isRemote 是否为远端数据
|
||||
});
|
||||
```
|
||||
`kotlin`
|
||||
|
||||
```kotlin
|
||||
// 搜索频道成员列表
|
||||
WKIM.getInstance().channelMembersManager().getWithPageOrSearch(channelId, channelType, "keyword", 1, 20, (list, isRemote) -> {
|
||||
// list 成员列表
|
||||
// isRemote 是否为远端数据
|
||||
});
|
||||
```
|
||||
### 常用方法
|
||||
#### 保存频道成员
|
||||
`java`
|
||||
```java
|
||||
// 批量保存成员
|
||||
WKIM.getInstance().getChannelMembersManager().save(List<WKChannelMember> list);
|
||||
```
|
||||
`kotlin`
|
||||
```kotlin
|
||||
// 批量保存成员
|
||||
WKIM.getInstance().channelMembersManager().save(list)
|
||||
```
|
||||
#### 修改备注
|
||||
`java`
|
||||
```java
|
||||
// 修改备注
|
||||
WKIM.getInstance().getChannelMembersManager().updateRemarkName(channelId, channelType, uid, remark);
|
||||
```
|
||||
`kotlin`
|
||||
```kotlin
|
||||
// 修改备注
|
||||
WKIM.getInstance().channelMembersManager().updateRemarkName(channelId, channelType, uid, remark)
|
||||
```
|
||||
|
||||
### 数据结构说明
|
||||
```java
|
||||
public class WKChannelMember{
|
||||
//自增ID
|
||||
public long id;
|
||||
//频道id
|
||||
public String channelID;
|
||||
//频道类型
|
||||
public byte channelType;
|
||||
//成员id
|
||||
public String memberUID;
|
||||
//成员名称
|
||||
public String memberName;
|
||||
//成员备注
|
||||
public String memberRemark;
|
||||
//成员头像
|
||||
public String memberAvatar;
|
||||
//成员角色
|
||||
public int role;
|
||||
//成员状态黑名单等1:正常2:黑名单
|
||||
public int status;
|
||||
//是否删除
|
||||
public int isDeleted;
|
||||
//创建时间
|
||||
public String createdAt;
|
||||
//修改时间
|
||||
public String updatedAt;
|
||||
//版本
|
||||
public long version;
|
||||
// 机器人0否1是
|
||||
public int robot;
|
||||
//扩展字段
|
||||
public HashMap extraMap;
|
||||
// 用户备注
|
||||
public String remark;
|
||||
// 邀请者uid
|
||||
public String memberInviteUID;
|
||||
// 被禁言到期时间
|
||||
public long forbiddenExpirationTime;
|
||||
public String memberAvatarCacheKey;
|
||||
}
|
||||
```
|
36
src/sdk/android/cmd.md
Normal file
36
src/sdk/android/cmd.md
Normal file
@ -0,0 +1,36 @@
|
||||
# 命令管理
|
||||
|
||||
CMD(命令)消息只能是服务器下发客户端进行解析 cmd消息格式
|
||||
|
||||
### 监听cmd消息
|
||||
|
||||
```java
|
||||
WKIM.getInstance().getCMDManager().addCmdListener("key", cmd -> {
|
||||
//处理cmd消息
|
||||
});
|
||||
// 移出监听
|
||||
WKIM.getInstance().getCMDManager().removeCmdListener("key");
|
||||
```
|
||||
```kotlin
|
||||
WKIM.getInstance().cmdManager.addCmdListener("key", { cmd ->
|
||||
//处理cmd消息
|
||||
})
|
||||
// 移出监听
|
||||
WKIM.getInstance().cmdManager.removeCmdListener("key")
|
||||
```
|
||||
|
||||
### 数据结构说明
|
||||
|
||||
```java
|
||||
|
||||
public class WKCMD {
|
||||
// 命令ID
|
||||
public String cmdKey;
|
||||
// 命令参数
|
||||
public JSONObject paramJsonObject;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
143
src/sdk/android/conversation.md
Normal file
143
src/sdk/android/conversation.md
Normal file
@ -0,0 +1,143 @@
|
||||
# 最近会话管理
|
||||
|
||||
`需要实现最近会话数据源` [最近会话数据源](/sdk/android/datasource.html#最近会话数据源)
|
||||
|
||||
### 获取最近会话列表
|
||||
#### 所有最近会话
|
||||
`Java`
|
||||
```java
|
||||
// 查询所有最近会话
|
||||
WKIM.getInstance().getConversationManager().getAll();
|
||||
```
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
// 查询所有最近会话
|
||||
WKIM.getInstance().conversationManager.getAll()
|
||||
```
|
||||
#### 新消息
|
||||
只有第一次打开应用时,需要同步最近会话列表, 后续最近会话列表的变化,通过监听来获取
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
WKIM.getInstance().getConversationManager().addOnRefreshMsgListener("key", new IRefreshConversationMsg() {
|
||||
@Override
|
||||
public void onRefreshConversationMsg(WKUIConversationMsg wkUIConversationMsg, boolean isEnd) {
|
||||
// wkUIConversationMsg 最近会话消息内容 UI上已有该会话需进行更新,反之添加到UI上
|
||||
// isEnd 为了防止频繁刷新UI,当isEnd为true可刷新UI
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
WKIM.getInstance().conversationManager.addOnRefreshMsgListener(
|
||||
"key"
|
||||
) { wkUIConversationMsg, isEnd ->
|
||||
// wkUIConversationMsg 最近会话消息内容 UI上已有该会话需进行更新,反之添加到UI上
|
||||
// isEnd 为了防止频繁刷新UI,当isEnd为true可刷新UI
|
||||
}
|
||||
```
|
||||
|
||||
### 移除最近会话
|
||||
#### 删除
|
||||
`Java`
|
||||
|
||||
```java
|
||||
// 删除某个最近会话
|
||||
WKIM.getInstance().getConversationManager().deleteWitchChannel(String channelId, byte channelType);
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
// 删除某个最近会话
|
||||
WKIM.getInstance().conversationManager.deleteWitchChannel(channelId, channelType)
|
||||
```
|
||||
|
||||
#### 监听删除
|
||||
在删除某个最近会话时会回调此方法
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
WKIM.getInstance().getConversationManager().addOnDeleteMsgListener("key", new IDeleteConversationMsg() {
|
||||
@Override
|
||||
public void onDelete(String channelID, byte channelType) {
|
||||
// channelID 聊天频道ID
|
||||
// channelType 聊天频道类型
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
WKIM.getInstance().conversationManager.addOnDeleteMsgListener(
|
||||
"key"
|
||||
) { channelID, channelType ->
|
||||
// channelID 聊天频道ID
|
||||
// channelType 聊天频道类型
|
||||
}
|
||||
```
|
||||
### 常用方法
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
// 查询所有最近会话
|
||||
WKIM.getInstance().getConversationManager().getAll();
|
||||
|
||||
// 修改消息红点
|
||||
WKIM.getInstance().getConversationManager().updateRedDot(String channelID, byte channelType, int redDot);
|
||||
|
||||
// 删除某个会话
|
||||
WKIM.getInstance().getConversationManager().deleteMsg(String channelId, byte channelType);
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
// 查询所有最近会话
|
||||
WKIM.getInstance().conversationManager.getAll()
|
||||
|
||||
// 修改消息红点
|
||||
WKIM.getInstance().conversationManager.updateRedDot( channelID, channelType, redDot)
|
||||
|
||||
// 删除某个会话
|
||||
WKIM.getInstance().conversationManager.deleteMsg( channelId, channelType)
|
||||
```
|
||||
|
||||
### 数据结构说明
|
||||
WKUIConversationMsg 类核心数据
|
||||
|
||||
```java
|
||||
public class WKUIConversationMsg {
|
||||
// 最后一条消息时间
|
||||
public long lastMsgTimestamp;
|
||||
// 消息频道 频道资料,可能为空,如果为空可以调用 WKChannelManager 的 fetchChannelInfo(channelID, channelType); 触发频道信息变更
|
||||
private WKChannel wkChannel;
|
||||
// 消息正文
|
||||
private WKMsg wkMsg;
|
||||
// 未读消息数量
|
||||
public int unreadCount;
|
||||
// 远程扩展
|
||||
private WKConversationMsgExtra remoteMsgExtra()
|
||||
// 本地扩展字段
|
||||
public HashMap<String, Object> localExtraMap;
|
||||
// 最近会话提醒项 如[有人@你][群内审核]等
|
||||
public List<WKReminder> getReminderList(){
|
||||
// ...
|
||||
}
|
||||
// 获取远程扩展
|
||||
public WKConversationMsgExtra getRemoteMsgExtra(){
|
||||
// ...
|
||||
}
|
||||
// 会话channel信息
|
||||
public WKChannel getWkChannel(){
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
188
src/sdk/android/datasource.md
Normal file
188
src/sdk/android/datasource.md
Normal file
@ -0,0 +1,188 @@
|
||||
# 数据源管理
|
||||
|
||||
### 文件
|
||||
在自定义附件消息的时候发送给对方的消息是将网络地址发送给对方,并不是实际的文件。这个时候我们就需监听附件的上传
|
||||
|
||||
#### 监听上传附件
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
WKIM.getInstance().getMsgManager().addOnUploadAttachListener(new IUploadAttachmentListener() {
|
||||
@Override
|
||||
public void onUploadAttachmentListener(WKMsg wkMsg, IUploadAttacResultListener listener) {
|
||||
// 在这里将未上传的文件上传到服务器并返回给sdk
|
||||
if(wkMsg.type == WKMsgContentType.WK_IMAGE){
|
||||
WKMediaMessageContent mediaMessageContent = (WKMediaMessageContent) wkMsg.baseContentMsgModel;
|
||||
if (TextUtils.isEmpty(mediaMessageContent.url)) {
|
||||
// todo 上传文件
|
||||
// ...
|
||||
mediaMessageContent.url = "xxxxxx"; // 设置网络地址并返回给sdk
|
||||
listener.onUploadResult(true, mediaMessageContent);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
WKIM.getInstance().msgManager.addOnUploadAttachListener { wkMsg, listener ->
|
||||
// 在这里将未上传的文件上传到服务器并返回给sdk
|
||||
if (wkMsg.type == WKMsgContentType.WK_IMAGE) {
|
||||
val mediaMessageContent = wkMsg.baseContentMsgModel as WKMediaMessageContent
|
||||
if (TextUtils.isEmpty(mediaMessageContent.url)) {
|
||||
// todo 上传文件
|
||||
// ...
|
||||
mediaMessageContent.url = "xxxxxx" // 设置网络地址并返回给sdk
|
||||
listener.onUploadResult(true, mediaMessageContent)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
#### 监听下载附件
|
||||
|
||||
sdk 中不会主动下载消息的附件。在收到带有附件的消息时需要 app 自己按需下载。在 app 下载完成后可改文件本地地址,避免重复下载
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
/**
|
||||
* 修改消息内容体
|
||||
*
|
||||
* @param clientMsgNo 客户端消息ID
|
||||
* @param messageContent 消息module 将本地地址保存在 messageContent 中
|
||||
* @param isRefreshUI 是否通知UI刷新对应消息
|
||||
*/
|
||||
WKIM.getInstance().getMsgManager().updateContent(String clientMsgNo, WKMessageContent messageContent, boolean isRefreshUI);
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
WKIMWKIM.getInstance().msgManager.updateContent(clientMsgNo, messageContent)
|
||||
```
|
||||
### 最近会话
|
||||
|
||||
#### 最近会话数据源
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
WKIM.getInstance().getConversationManager().addOnSyncConversationListener(new ISyncConversationChat() {
|
||||
@Override
|
||||
public void syncConversationChat(String last_msg_seqs, int msg_count, long version, ISyncConversationChatBack iSyncConversationChatBack) {
|
||||
/**
|
||||
* 同步会话
|
||||
*
|
||||
* @param last_msg_seqs 最近会话列表msg_seq集合
|
||||
* @param msg_count 会话里面消息同步数量
|
||||
* @param version 最大版本号
|
||||
* @param iSyncConvChatBack 回调
|
||||
*/
|
||||
// 需要请求业务接口将数据返回给sdk
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
WKIM.getInstance().conversationManager.addOnSyncConversationListener { last_msg_seqs, msg_count, version, iSyncConversationChatBack ->
|
||||
// todo 同步最近会话数据
|
||||
}
|
||||
```
|
||||
|
||||
### 频道
|
||||
#### 频道资料数据源
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
// 监听获取channel信息
|
||||
WKIM.getInstance().getChannelManager().addOnGetChannelInfoListener(new IGetChannelInfo() {
|
||||
@Override
|
||||
public WKChannel onGetChannelInfo(String channelID, byte channelType, IChannelInfoListener iChannelInfoListener) {
|
||||
// 获取个人资料还是群资料可通过 channelType 区分
|
||||
// 如果app本地有该channel信息可直接返回数据,反之可获取网络数据后通过 iChannelInfoListener 返回
|
||||
return null;
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
// 监听获取channel信息
|
||||
WKIM.getInstance().channelManager.addOnGetChannelInfoListener { channelID, channelType, iChannelInfoListener ->
|
||||
// 获取个人资料还是群资料可通过 channelType 区分
|
||||
// 如果app本地有该channel信息可直接返回数据,反之可获取网络数据后通过 iChannelInfoListener 返回
|
||||
null
|
||||
}
|
||||
```
|
||||
|
||||
- <font color='#999' size=2>SDK 内置频道类型 可通过 `WKChannelType` 查看</font>
|
||||
|
||||
也可以批量保存频道资料信息
|
||||
```java
|
||||
// 批量保存频道资料信息
|
||||
WKIM.getInstance().getChannelManager().saveOrUpdateChannels(channels);
|
||||
```
|
||||
```kotlin
|
||||
// 批量保存频道资料信息
|
||||
WKIM.getInstance().channelManager.saveOrUpdateChannels(channels)
|
||||
```
|
||||
### 频道成员
|
||||
#### 频道成员数据源
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
// 监听获取频道成员信息
|
||||
WKIM.getInstance().getChannelMembersManager().addOnGetChannelMembersListener((channelID, b, keyword, page, limit, iChannelMemberListResult) ->{
|
||||
// 获取频道成员后通过 iChannelMembersListener 返回给sdk
|
||||
});
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
// 监听获取频道成员信息
|
||||
WKIM.getInstance().channelMembersManager.addOnGetChannelMembersListener { channelID, channelType, keyword, page, limit, back ->
|
||||
// 获取频道成员后通过 iChannelMembersListener 返回给sdk
|
||||
}
|
||||
```
|
||||
|
||||
### 消息
|
||||
#### 频道消息数据源
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
WKIM.getInstance().getMsgManager().addOnSyncChannelMsgListener(new ISyncChannelMsgListener() {
|
||||
@Override
|
||||
public void syncChannelMsgs(String channelID, byte channelType,long startMessageSeq, long endMessageSeq, int limit, int pullMode, ISyncChannelMsgBack iSyncChannelMsgBack) {
|
||||
/**
|
||||
* 同步某个频道的消息
|
||||
*
|
||||
* @param channelID 频道ID
|
||||
* @param channelType 频道类型
|
||||
* @param startMessageSeq 开始消息列号(结果包含start_message_seq的消息)
|
||||
* @param endMessageSeq 结束消息列号(结果不包含end_message_seq的消息)
|
||||
* @param limit 消息数量限制
|
||||
* @param pullMode 拉取模式 0:向下拉取 1:向上拉取
|
||||
* @param iSyncChannelMsgBack 请求返回
|
||||
*/
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
WKIM.getInstance().msgManager.addOnSyncChannelMsgListener { channelID, channelType, startMessageSeq, endMessageSeq, limit, pullMode, iSyncChannelMsgBack ->
|
||||
// 调用接口获取channel历史消息
|
||||
// do ...
|
||||
}
|
||||
```
|
47
src/sdk/android/integration.md
Normal file
47
src/sdk/android/integration.md
Normal file
@ -0,0 +1,47 @@
|
||||
# 集成
|
||||
|
||||
## 快速入门
|
||||
|
||||
**Gradle**
|
||||
|
||||
[](https://jitpack.io/#WuKongIM/WuKongIMAndroidSDK)
|
||||
|
||||
```
|
||||
implementation implementation 'com.github.WuKongIM:WuKongIMAndroidSDK:version' // 版本号请看上面
|
||||
```
|
||||
|
||||
jitpack 还需在主程序的`build.gradle`文件中添加:
|
||||
|
||||
```
|
||||
allprojects {
|
||||
repositories {
|
||||
...
|
||||
maven { url 'https://jitpack.io' }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
由于 sdk 内使用了 sqlcipher 加密数据库和 curve25519 加密算法,需将库添加到项目中
|
||||
|
||||
```
|
||||
implementation "net.zetetic:android-database-sqlcipher:4.5.3"
|
||||
implementation "androidx.sqlite:sqlite-ktx:2.3.1"
|
||||
implementation 'org.whispersystems:curve25519-android:0.5.0'
|
||||
implementation 'org.whispersystems:signal-protocol-android:2.8.1'
|
||||
```
|
||||
|
||||
**混淆**
|
||||
|
||||
```
|
||||
-dontwarn com.xinbida.wukongim.**
|
||||
-keep class com.xinbida.wukongim.**{*;}
|
||||
|
||||
#数据库加密
|
||||
-keep,includedescriptorclasses class net.sqlcipher.** { *; }
|
||||
-keep,includedescriptorclasses interface net.sqlcipher.** { *; }
|
||||
|
||||
#--------- 混淆dh curve25519-------
|
||||
-keep class org.whispersystems.curve25519.**{*;}
|
||||
-keep class org.whispersystems.** { *; }
|
||||
-keep class org.thoughtcrime.securesms.** { *; }
|
||||
```
|
47
src/sdk/android/intro.md
Normal file
47
src/sdk/android/intro.md
Normal file
@ -0,0 +1,47 @@
|
||||
# 说明
|
||||
|
||||
## 设计理念
|
||||
|
||||
为了让开发者更快更方便的使用 SDK,悟空 SDK 提供了一个唯一的入口来访问 SDK 中的所有功能。就像书籍的目录一样可以通过目录查找对应的内容。如连接 IM `WKIM.getInstance().getConnectionManager().connection()`
|
||||
|
||||
## 结构说明
|
||||
|
||||
 SDK 常用功能介绍
|
||||
|
||||
```java
|
||||
|
||||
// 消息管理器
|
||||
// 负责消息的增删改查、新消息监听、刷新消息监听、消息入库、发送消息回执监听、监听同步某个聊天数据等
|
||||
WKIM.getInstance().getMsgManager()
|
||||
|
||||
// 连接管理
|
||||
// 负责IM的连接、断开、退出登录、监听连接状态、监听获取连接IP等
|
||||
WKIM.getInstance().getConnectionManager()
|
||||
|
||||
// 频道管理
|
||||
// 可获取Channel的信息,刷新Channel缓存,监听Channel更改[置顶、免打扰、禁言]、搜索Channel等
|
||||
WKIM.getInstance().getChannelManager()
|
||||
|
||||
// 最近会话管理
|
||||
// 获取最近聊天记录、刷新最近会话[新增聊天、红点改变]、监听移除某个会话、监听同步最近会话等
|
||||
WKIM.getInstance().getConversationManager()
|
||||
|
||||
// 频道成员管理
|
||||
// 获取Channel成员列表、设置成员备注、保存修改成员数据、监听刷新成员和移除成员等
|
||||
WKIM.getInstance().getChannelMembersManager()
|
||||
|
||||
// 提醒管理
|
||||
// 获取某个会话的提醒如:[有人@我] [入群申请] 等。还可自定义提醒项,如像 语音未读 等
|
||||
WKIM.getInstance().getReminderManager()
|
||||
|
||||
// 命令管理
|
||||
// 负责监听服务器下发的命令消息
|
||||
WKIM.getInstance().getCMDManager()
|
||||
|
||||
// 机器人管理
|
||||
// 可以获取机器人菜单、同步机器人菜单,查询菜单等
|
||||
WKIM.getInstance().getRobotManager()
|
||||
```
|
||||
### SDK 与 APP 交互原则
|
||||
|
||||
 sdk 与 app 交互流程就是 app 调用 sdk 提供的方法,sdk 处理完数据后通过事件将数据回调给 app。如发送消息流程:app 调用发送消息方法,sdk 将入库后的消息 push 给 app
|
276
src/sdk/android/message.md
Normal file
276
src/sdk/android/message.md
Normal file
@ -0,0 +1,276 @@
|
||||
# 消息管理
|
||||
|
||||
|
||||
### 发送消息
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
/**
|
||||
*
|
||||
* @param textContent 消息正文
|
||||
* @param channelID 投递的频道ID
|
||||
* @param channelType 投递的频道类型(个人频道,群频道,客服频道等等)
|
||||
*/
|
||||
WKIM.getInstance().getMsgManager().sendMessage(textContent,channelID, channelType);
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
WKIM.getInstance().msgManager.sendMessage(textContent,channelID, channelType)
|
||||
```
|
||||
|
||||
- <font size=2 color="#999">sdk 内置频道类型可通过`WKChannelType`查看</font>
|
||||
|
||||
如给用户`A`发送一条文本消息。构建文本消息正文
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
WKTextContent textContent = new WKTextContent("你好,悟空");
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
val textContent = WKTextContent("你好,悟空")
|
||||
```
|
||||
|
||||
将消息发送给用户`A`
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
WKIM.getInstance().getMsgManager().sendMessage(textContent,"A",WKChannelType.PERSONAL);
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
WKIM.getInstance().msgManager.sendMessage(textContent,"A",WKChannelType.PERSONAL)
|
||||
```
|
||||
|
||||
#### 文本消息
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
public class WKTextContent extends WKMessageContent {
|
||||
|
||||
public WKTextContent(String content) {
|
||||
this.content = content;
|
||||
this.type = WKMsgContentType.WK_TEXT;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 图片消息
|
||||
|
||||
```java
|
||||
public class WKImageContent extends WKMediaMessageContent {
|
||||
public int width; // 宽度
|
||||
public int height; // 高度
|
||||
public WKImageContent(String localPath) {
|
||||
this.localPath = localPath;
|
||||
this.type = WKMsgContentType.WK_IMAGE;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- <font color="#999" size=2>在构建图片消息正文时,无需传递图片的高宽。sdk 会自动获取图片高宽</font>
|
||||
|
||||
#### 语音消息
|
||||
|
||||
```java
|
||||
public class WKVoiceContent extends WKMediaMessageContent {
|
||||
public int timeTrad; // 语音时长
|
||||
public String waveform; // 音频波浪数据 (可选参数)
|
||||
|
||||
public WKVoiceContent(String localPath, int timeTrad) {
|
||||
this.type = WKMsgContentType.WK_VOICE;
|
||||
this.timeTrad = timeTrad;
|
||||
this.localPath = localPath;
|
||||
}
|
||||
}
|
||||
```
|
||||
### 消息入库返回(并不是消息发送状态)
|
||||
|
||||
在发送消息时,sdk 将消息保存在本地数据库后就会触发入库回调。此时消息并未进行发送,可在此监听中将消息展示在 UI 上
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
WKIM.getInstance().getMsgManager().addOnSendMsgCallback("key", new ISendMsgCallBackListener() {
|
||||
@Override
|
||||
public void onInsertMsg(WKMsg wkMsg) {
|
||||
// 可以在这里将保存在数据库的消息`wkMsg`展示在UI上
|
||||
// ...
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
WKIM.getInstance().msgManager.addOnSendMsgCallback("key") { wkMsg ->
|
||||
// 将消息wkMsg展示在UI上
|
||||
}
|
||||
```
|
||||
|
||||
- <font color='#999' size=2>关于事件是否传入唯一 key 说明请查看[事件监听](/sdk/android#说明)</font>
|
||||
|
||||
### 收到新消息监听
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
WKIM.getInstance().getMsgManager().addOnNewMsgListener("key", new INewMsgListener() {
|
||||
@Override
|
||||
public void newMsg(List<WKMsg> list) {
|
||||
// list:接收到的消息
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
WKIM.getInstance().msgManager.addOnNewMsgListener("key") { list ->
|
||||
// list:接收到的消息
|
||||
}
|
||||
```
|
||||
|
||||
- <font color='#999' size=2>如果在聊天页面内收到新消息时需判断该消息是否属于当前会话,可通过消息对象`WKMsg`的`channelID`和`channelType`判断</font>
|
||||
|
||||
### 刷新消息监听
|
||||
|
||||
在 sdk 更新过消息时,如:消息发送状态,有人点赞消息,消息已读回执,消息撤回,消息被编辑等等,sdk 都将回调以下事件。UI 可通过消息对象`WKMsg`的`clientMsgNO`来判断具体是哪条消息发生了更改。
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
WKIM.getInstance().getMsgManager().addOnRefreshMsgListener("key", new IRefreshMsg() {
|
||||
@Override
|
||||
public void onRefresh(WKMsg wkMsg, boolean isEnd) {
|
||||
// wkMsg:刷新的消息对象
|
||||
// isEnd:为了避免频繁刷新UI导致卡顿,当isEnd为true时在刷新UI
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
WKIM.getInstance().msgManager.addOnRefreshMsgListener("") { wkMsg, isEnd ->
|
||||
// wkMsg:刷新的消息对象
|
||||
// isEnd:为了避免频繁刷新UI导致卡顿,当isEnd为true时在刷新UI
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### 查看某个频道的聊天信息
|
||||
|
||||
`Java`
|
||||
|
||||
```java
|
||||
/**
|
||||
* 查询或同步某个频道消息
|
||||
*
|
||||
* @param channelId 频道ID
|
||||
* @param channelType 频道类型
|
||||
* @param oldestOrderSeq 最后一次消息大orderSeq 第一次进入聊天传入0
|
||||
* @param contain 是否包含 oldestOrderSeq 这条消息
|
||||
* @param dropDown 是否下拉
|
||||
* @param aroundMsgOrderSeq 查询此消息附近消息 如 aroundMsgOrderSeq=20 返回数据则是 [16,17,19,20,21,22,23,24,25]
|
||||
* @param limit 每次获取数量
|
||||
* @param iGetOrSyncHistoryMsgBack 请求返还
|
||||
*/
|
||||
WKIM.getInstance().getMsgManager().getOrSyncHistoryMessages(String channelId, byte channelType, long oldestOrderSeq, boolean contain, boolean dropDown, int limit, long aroundMsgOrderSeq, final IGetOrSyncHistoryMsgBack iGetOrSyncHistoryMsgBack) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
`Kotlin`
|
||||
|
||||
```kotlin
|
||||
WKIM.getInstance().msgManager.getOrSyncHistoryMessages(channelId,channelType,oldestOrderSeq,contain,dropDown,limit,aroundMsgOrderSeq,object :IGetOrSyncHistoryMsgBack{
|
||||
override fun onResult(list: MutableList<WKMsg>?) {
|
||||
// list 获取到的消息 展示到UI
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
- <font color='#999' size=2>获取历史消息并不是同步方法,因为有可能存在非连续性时会往服务器同步数据</font>
|
||||
|
||||
代码
|
||||
```java
|
||||
WKIM.getInstance().getMsgManager().getOrSyncHistoryMessages(channelId, channelType, oldestOrderSeq, contain, pullMode, limit, aroundMsgOrderSeq, new IGetOrSyncHistoryMsgBack() {
|
||||
@Override
|
||||
public void onSyncing() {
|
||||
// 正在同步中 按需显示loading
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResult(List<WKMsg> list) {
|
||||
// 展示消息
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### 离线消息接收
|
||||
`需要实现同步频道消息数据源` [频道消息数据源](/sdk/android/datasource.html#频道消息数据源)
|
||||
|
||||
因为WuKongIM 是支持消息永久存储,所以会产生海量的离线消息。对此我们采用了按需拉取的机制,如 10 个会话一个会话 10 万条消息,WuKongIM 不会把这个 10\*10 万=100 万条消息都拉取到本地。 而是采用拉取这 10 个会话的信息和对应的最新 20 条消息,也就是实际只拉取了 200 条消息 相对 100 万条消息来说大大提高了离线拉取速度。用户点进对应的会话才会去按需拉取这个会话的消息。 这些机制 SDK 内部都已做好了封装,使用者其实不需要关心。使用者只需要关心最近会话的变化和监听获取数据的回调即可。
|
||||
|
||||
### 数据结构说明
|
||||
|
||||
#### 消息类核心属性
|
||||
|
||||
```java
|
||||
public class WKMsg {
|
||||
// 服务器消息ID(全局唯一,无序)
|
||||
public String messageID;
|
||||
// 本地唯一ID
|
||||
public String clientMsgNO;
|
||||
// 服务器时间 (10位时间戳)
|
||||
public long timestamp;
|
||||
// 消息来源发送者
|
||||
public String fromUID;
|
||||
// 聊天频道ID
|
||||
public String channelID;
|
||||
// 聊天频道类型
|
||||
public byte channelType;
|
||||
// 消息正文
|
||||
public WKMessageContent baseContentMsgModel;
|
||||
// 消息头
|
||||
public WKMsgHeader header;
|
||||
// 本地扩展字段
|
||||
public HashMap localExtraMap;
|
||||
// 远程扩展
|
||||
public WKMsgExtra remoteExtra;
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
#### 消息正文核心属性
|
||||
|
||||
```java
|
||||
public class WKMessageContent {
|
||||
// 消息内容类型
|
||||
public int type;
|
||||
// 消息中的@提醒信息
|
||||
public WKMentionInfo mentionInfo;
|
||||
// 消息回复对象
|
||||
public WKReply reply;
|
||||
// 编码消息 上层需实现该方法并编码
|
||||
public JSONObject encodeMsg() {
|
||||
return new JSONObject();
|
||||
}
|
||||
// 解码消息 上层需实现该方法并解码
|
||||
public WKMessageContent decodeMsg(JSONObject jsonObject) {
|
||||
return this;
|
||||
}
|
||||
...
|
||||
}
|
||||
```
|
BIN
src/sdk/android/msg_reply.jpg
Normal file
BIN
src/sdk/android/msg_reply.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 591 KiB |
82
src/sdk/android/reminder.md
Normal file
82
src/sdk/android/reminder.md
Normal file
@ -0,0 +1,82 @@
|
||||
# 提醒项管理
|
||||
|
||||
会话提醒目前只支持服务器下发指令。客户端只需监听同步会话提醒和监听刷新会话消息即可
|
||||
### 获取提醒项
|
||||
`java`
|
||||
```java
|
||||
// 获取指定会话的提醒项
|
||||
List<WKReminder> allReminder = WKIM.getInstance().getReminderManager().getReminders(channelId, channelType);
|
||||
|
||||
// 获取指定类型的提醒项
|
||||
WKIM.getInstance().getReminderManager().getRemindersWithType(String channelID, byte channelType, int type);
|
||||
```
|
||||
`kotlin`
|
||||
```kotlin
|
||||
// 获取指定会话的提醒项
|
||||
val allReminder = WKIM.getInstance().reminderManager.s(channelId, channelType)
|
||||
|
||||
// 获取指定类型的提醒项
|
||||
WKIM.getInstance().reminderManager.getRemindersWithType( channelID, channelType, type);
|
||||
```
|
||||
### 保存提醒项
|
||||
`java`
|
||||
```java
|
||||
// 保存提醒项
|
||||
WKIM.getInstance().getReminderManager().saveOrUpdateReminders(List<WKReminder> reminderList);
|
||||
```
|
||||
`kotlin`
|
||||
```kotlin
|
||||
// 保存提醒项
|
||||
WKIM.getInstance().reminderManager.saveOrUpdateReminders(list)
|
||||
```
|
||||
|
||||
### 事件
|
||||
#### 新增提醒项
|
||||
`java`
|
||||
```java
|
||||
// 监听新增提醒项
|
||||
WKIM.getInstance().getReminderManager().addOnNewReminderListener("key", new INewReminderListener() {
|
||||
@Override
|
||||
public void newReminder(List<WKReminder> list) {
|
||||
|
||||
}
|
||||
});
|
||||
// 移出监听
|
||||
WKIM.getInstance().getReminderManager().removeNewReminderListener("key");
|
||||
```
|
||||
|
||||
`kotlin`
|
||||
```kotlin
|
||||
// 监听新增提醒项
|
||||
WKIM.getInstance().reminderManager.addOnNewReminderListener("key", object : INewReminderListener {
|
||||
override fun newReminder(list: List<WKReminder>) {
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
// 移出监听
|
||||
WKIM.getInstance().reminderManager.removeNewReminderListener("key");
|
||||
```
|
||||
|
||||
- <font color='#999' size=2>注:key为监听的唯一标识,可以为任意字符串,添加监听和移出监听时需要传入相同的key</font>
|
||||
|
||||
### 数据结构说明
|
||||
```java
|
||||
|
||||
public class WKReminder {
|
||||
public long reminderID; // 提醒项ID
|
||||
public String messageID; // 消息ID
|
||||
public String channelID; // 频道ID
|
||||
public byte channelType; // 频道类型
|
||||
public long messageSeq; // 消息序列号
|
||||
public int type; // 提醒类型[1、有人@你][2、群内审核] 等
|
||||
public String uid;
|
||||
public String text; // 提醒内容
|
||||
public Map data; // 提醒包含的自定义数据
|
||||
public long version; // 版本号 增量同步需要用到
|
||||
public int done; // 0.未完成 1.已完成
|
||||
public int needUpload; // 0.不需要上传 1.需要上传
|
||||
public String publisher; // 发布者
|
||||
}
|
||||
```
|
||||
|
BIN
src/sdk/android/sdk.png
Normal file
BIN
src/sdk/android/sdk.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 335 KiB |
208
src/sdk/flutter/advance.md
Normal file
208
src/sdk/flutter/advance.md
Normal file
@ -0,0 +1,208 @@
|
||||
# 高级功能
|
||||
|
||||
### 自定义消息类型
|
||||
|
||||
在WuKongIM 中所有的消息类型都是自定义消息。下面我们以`gif`消息举例
|
||||
|
||||
#### 第一步 定义消息
|
||||
|
||||
定义消息对象并继承 `WKMessageContent` 并在构造方法中指定消息类型
|
||||
|
||||
- <font color='#999' size=2>SDK 内置消息类型可通过 `WkMessageContentType` 查看</font>
|
||||
|
||||
**继承 `WKMessageContent` 和定义 gif 消息的正文结构**
|
||||
```dart
|
||||
class GifContent extends WKMessageContent{
|
||||
int width=0; // 宽度
|
||||
int height=0; // 高度
|
||||
String url; // 远程地址
|
||||
GifContent(this.url){
|
||||
// 指定消息类型
|
||||
contentType = WkMessageContentType.gif;
|
||||
}
|
||||
}
|
||||
```
|
||||
#### 第二步 编码解码
|
||||
```dart
|
||||
class GifContent extends WKMessageContent{
|
||||
int c=0; // 宽度
|
||||
int height=0; // 高度
|
||||
String url; // 远程地址
|
||||
GifContent(this.url){
|
||||
// 指定消息类型
|
||||
contentType = WkMessageContentType.gif;
|
||||
}
|
||||
|
||||
@override
|
||||
WKMessageContent decodeJson(Map<String, dynamic> json) {
|
||||
url = readString(json, 'url');
|
||||
width = readInt(json, 'width');
|
||||
height = readInt(json, 'height');
|
||||
return this;
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> encodeJson() {
|
||||
return {'url': url, 'width': width, 'height': height};
|
||||
}
|
||||
// 如果需要获取可显示内容可重写
|
||||
|
||||
@override
|
||||
String displayText() {
|
||||
return "[动态图片]";
|
||||
}
|
||||
}
|
||||
```
|
||||
- <font color='#999' size=2>解码和编码消息时无需将 `type` 字段考虑其中,sdk 内部会自动处理</font>
|
||||
|
||||
#### 第三步 注册消息
|
||||
```dart
|
||||
WKIM.shared.messageManager.registerMsgContent(WkMessageContentType.gif,
|
||||
(dynamic data) {
|
||||
return GifContent('').decodeJson(data);
|
||||
});
|
||||
```
|
||||
|
||||
对此通过这三步自定义普通消息就已完成。在收到消息时`WKMsg`中的type为3就表示该消息是名片消息,其中`messageContent`则为自定义的`GifContent`,这时可将`messageContent`强转为`GifContent`并渲染到UI上
|
||||
|
||||
### 自定义附件消息
|
||||
|
||||
我们在发送消息的时候有时需发送带附件的消息。WuKongIM 也提供自定义附件消息,自定义附件消息和普通消息区别不大。下面我们图片消息举例
|
||||
|
||||
#### 第一步 定义消息
|
||||
|
||||
值得注意的是自定义附件消息需继承`WKMediaMessageContent`而不是`WKMessageContent`
|
||||
|
||||
|
||||
```dart
|
||||
|
||||
class WKImageContent extends WKMediaMessageContent {
|
||||
int width; // 图片宽度
|
||||
int height; // 图片高度
|
||||
WKImageContent(this.width, this.height) {
|
||||
contentType = WkMessageContentType.image;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 第二步 编码解码
|
||||
```dart
|
||||
class WKImageContent extends WKMediaMessageContent {
|
||||
int width; // 图片宽度
|
||||
int height; // 图片高度
|
||||
WKImageContent(this.width, this.height) {
|
||||
contentType = WkMessageContentType.image;
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> encodeJson() {
|
||||
return {'width': width, 'height': height, 'url': url};
|
||||
}
|
||||
|
||||
@override
|
||||
WKMessageContent decodeJson(Map<String, dynamic> json) {
|
||||
width = readInt(json, 'width');
|
||||
height = readInt(json, 'height');
|
||||
url = readString(json, 'url');
|
||||
localPath = readString(json, 'localPath');
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
#### 第三步 注册消息
|
||||
```dart
|
||||
WKIM.shared.messageManager.registerMsgContent(WkMessageContentType.image,
|
||||
(dynamic data) {
|
||||
return WKImageContent(
|
||||
0,
|
||||
0,
|
||||
).decodeJson(data);
|
||||
});
|
||||
```
|
||||
|
||||
### 消息扩展
|
||||
|
||||
随着业务的发展应用在聊天中的功能也日益增多,为了满足绝大部分的需求 WuKongIM 中增加了消息扩展功能。消息扩展分`本地扩展`和`远程扩展`,本地扩展只针对 app 本地使用卸载 app 后将丢失,远程扩展是服务器保存卸载重装后数据将恢复
|
||||
|
||||
#### 本地扩展
|
||||
|
||||
本地扩展就是消息对象`WKMsg`中的`localExtraMap`字段
|
||||
```dart
|
||||
// 修改消息本地扩展
|
||||
WKIM.shared.messageManager.updateLocalExtraWithClientMsgNo(String clientMsgNo,dynamic data);
|
||||
```
|
||||
- <font color='#999' size=2>更新成功后 sdk 会触发刷新消息回调</font>
|
||||
|
||||
#### 远程扩展
|
||||
|
||||
远程扩展就是消息对象`WKMsg`中的`wkMsgExtra`字段
|
||||
```dart
|
||||
// 修改消息远程扩展
|
||||
WKIM.shared.messageManager.saveRemoteExtraMsg(List<WKSyncExtraMsg> list);
|
||||
```
|
||||
|
||||
### 消息已读未读
|
||||
消息的已读未读又称消息回执。消息回执功能可通过 setting 进行设置
|
||||
#### 发送回执消息
|
||||
```dart
|
||||
Setting setting = Setting();
|
||||
setting.receipt = 1; //开启回执
|
||||
var option = WKSendOptions();
|
||||
option.setting = setting;
|
||||
// 发送消息
|
||||
WKIM.shared.messageManager.sendWithOption(
|
||||
text, WKChannel(channelID, channelType), option);
|
||||
```
|
||||
当用户浏览过对方发送的消息时,如果对方开启了消息回执这时需将查看过的消息上传到服务器标记该消息已读。当对方或者自己上传过已读消息这时服务器会下发同步消息扩展的 cmd(命令)消息,此时需同步最新消息扩展通过`WKIM.shared.messageManager.saveRemoteExtraMsg(List<WKSyncExtraMsg> list)`方法保存到 sdk 中
|
||||
|
||||
### 消息回复
|
||||
在聊天中如果消息过多,发送消息回复就会显得消息很乱无章可循。这时就需要对某条消息进行特定的回复,即消息回复。 如以下效果
|
||||
|
||||
<img src='./../msg_reply.jpg' width=30%/>
|
||||
|
||||
在发送消息时,只需将消息正文`WKMessageContent`中的`WKReply`对象赋值就能对达到消息回复效果
|
||||
#### 发送回复消息
|
||||
```dart
|
||||
// 回复
|
||||
WKTextContent text = WKTextContent(content);
|
||||
WKReply reply = WKReply();
|
||||
reply.messageId = "11";
|
||||
reply.rootMid = "111";
|
||||
reply.fromUID = "11";
|
||||
reply.fromName = "12";
|
||||
WKTextContent payloadText = WKTextContent("dds");
|
||||
reply.payload = payloadText;
|
||||
text.reply = reply;
|
||||
// 发送消息
|
||||
WKIM.shared.messageManager.sendMessage( text, WKChannel(channelID, channelType));
|
||||
```
|
||||
|
||||
### 消息回应(点赞)
|
||||
|
||||
当自己或者别人对消息回应(点赞)时,都会触发 cmd(命令)消息通知到应用。应用在收到同步消息回应的cmd时获取可调用服务器同步接口将获取的回应数据更新到sdk
|
||||
```dart
|
||||
// 保存消息回应
|
||||
WKIM.shared.messageManager.saveMessageReactions(List<WKSyncMsgReaction> list);
|
||||
```
|
||||
|
||||
- <font color='#999' size=2>同一个用户对同一条消息只能做出一条回应。重复进行消息不同 emoji 的回应会做为修改回应,重复进行相同 emoji 的回应则做为删除回应</font> sdk 更新消息回应后会触发消息刷新的事件。app 需监听此事件并对 UI 进行刷新
|
||||
|
||||
### 消息编辑
|
||||
|
||||
当我们给对方发送消息发现发送内容有错误时,这时无需撤回重发只需要将消息编辑即可
|
||||
|
||||
#### 设置编辑内容
|
||||
```dart
|
||||
WKIM.shared.messageManager.updateMsgEdit(String messageID, String channelID, int channelType,
|
||||
String content);
|
||||
```
|
||||
更改 sdk 消息编辑内容后需将编辑后的内容上传到服务器,则需要监听上传消息扩展
|
||||
|
||||
#### 监听上传消息扩展
|
||||
```dart
|
||||
WKIM.shared.messageManager.addOnUploadMsgExtra((wkMsgExtra) => {
|
||||
// 上传到自己的服务器
|
||||
});
|
||||
```
|
||||
如果自己或者别人编辑了消息,都会触发 cmd(命令)消息,app根据cmd类型判断后去同步消息扩展即可 app 需监听消息更新的事件完成对 UI 的刷新
|
55
src/sdk/flutter/base.md
Normal file
55
src/sdk/flutter/base.md
Normal file
@ -0,0 +1,55 @@
|
||||
# 基础
|
||||
### 初始化
|
||||
|
||||
#### 连接IP
|
||||
```dart
|
||||
WKIM.shared.options.getAddr = (Function(String address) complete) async {
|
||||
// 可通过接口获取后返回
|
||||
complete('xxxxx:5100');
|
||||
};
|
||||
```
|
||||
- <font color="#999" font-size=2>返回 IM 通信端的 IP 和 IM 通信端的 TCP 端口。<font color="#FF0000">分布式可调用接口获取 IP 和 Port 后返回</font></font>
|
||||
|
||||
#### 初始化sdk
|
||||
```dart
|
||||
// uid 登录用户ID(业务服务端在IM通讯端登记了的uid))
|
||||
// token 登录用户token(业务服务端在IM通讯端登记了的token)
|
||||
WKIM.shared.setup(Options.newDefault('uid', 'token'));
|
||||
```
|
||||
|
||||
### 连接/断开
|
||||
#### 连接
|
||||
```dart
|
||||
WKIM.shared.connectionManager.connect();
|
||||
```
|
||||
|
||||
#### 断开
|
||||
```dart
|
||||
// isLogout true:退出并不再重连 false:退出保持重连
|
||||
WKIM.shared.connectionManager.disconnect(isLogout)
|
||||
```
|
||||
|
||||
|
||||
### 连接状态监听
|
||||
```dart
|
||||
WKIM.shared.connectionManager.addOnConnectionStatus('home',
|
||||
(status, reason, connInfo) {
|
||||
if (status == WKConnectStatus.connecting) {
|
||||
// 连接中
|
||||
} else if (status == WKConnectStatus.success) {
|
||||
// 连接成功
|
||||
// connInfo.nodeId 节点ID
|
||||
} else if (status == WKConnectStatus.noNetwork) {
|
||||
// 没有网络连接
|
||||
} else if (status == WKConnectStatus.syncMsg) {
|
||||
// 同步消息
|
||||
} else if (status == WKConnectStatus.kicked) {
|
||||
// 被踢下线 需退出应用回到登录界面
|
||||
} else if (status == WKConnectStatus.fail) {
|
||||
// 连接失败
|
||||
} else if (status == WKConnectStatus.syncCompleted) {
|
||||
// 同步完成
|
||||
}
|
||||
});
|
||||
```
|
||||
|
96
src/sdk/flutter/channel.md
Normal file
96
src/sdk/flutter/channel.md
Normal file
@ -0,0 +1,96 @@
|
||||
# 频道管理
|
||||
|
||||
频道(Channel)WuKongIM 中是一个比较抽象的概念。发送消息都是先发送给频道,频道根据自己的配置规则进行投递消息,频道分频道和频道详情。 更多介绍请移步[什么是频道](/guide/initialize#频道)
|
||||
|
||||
### 数据源
|
||||
|
||||
`需要实现获取频道资料的数据源` [获取频道资料数据源](/sdk/flutter/datasource.html#频道资料数据源)
|
||||
### 频道资料
|
||||
#### 获取频道资料
|
||||
```dart
|
||||
// 获取某个channel资料
|
||||
WKIM.shared.channelManager.getChannel(String channelID,int channelType);
|
||||
```
|
||||
|
||||
#### 强制刷新频道资料
|
||||
```dart
|
||||
// 强制刷新某个channel资料
|
||||
WKIM.shared.channelManager.fetchChannelInfo(String channelID, int channelType)
|
||||
```
|
||||
### 事件
|
||||
#### 监听频道更新事件
|
||||
```dart
|
||||
// 监听channel刷新事件
|
||||
WKIM.shared.channelManager.addOnRefreshListener('key',(wkChannel){
|
||||
// 刷新对应channel 信息
|
||||
});
|
||||
|
||||
// 移除监听
|
||||
WKIM.shared.channelManager.removeOnRefreshListener('key');
|
||||
```
|
||||
|
||||
- <font color='#999' size=2>注:key为监听的唯一标识,可以为任意字符串,添加监听和移出监听时需要传入相同的key</font>
|
||||
|
||||
### 常用方法
|
||||
```dart
|
||||
// 批量保存频道资料
|
||||
WKIM.shared.channelManager.addOrUpdateChannels(List<WKChannel> channelList);
|
||||
|
||||
// 搜索
|
||||
WKIM.shared.channelManager.search(String keyword);
|
||||
```
|
||||
### 数据结构说明
|
||||
```dart
|
||||
|
||||
class WKChannel {
|
||||
String channelID = "";
|
||||
int channelType = WKChannelType.personal;
|
||||
String channelName = "";
|
||||
//频道备注(频道的备注名称,个人的话就是个人备注,群的话就是群别名)
|
||||
String channelRemark = "";
|
||||
int showNick = 0;
|
||||
//是否置顶
|
||||
int top = 0;
|
||||
//是否保存在通讯录
|
||||
int save = 0;
|
||||
//免打扰
|
||||
int mute = 0;
|
||||
//禁言
|
||||
int forbidden = 0;
|
||||
//邀请确认
|
||||
int invite = 0;
|
||||
//频道状态[1:正常2:黑名单]
|
||||
int status = 1;
|
||||
//是否已关注 0.未关注(陌生人) 1.已关注(好友)
|
||||
int follow = 0;
|
||||
//是否删除
|
||||
int isDeleted = 0;
|
||||
//创建时间
|
||||
String createdAt = "";
|
||||
//修改时间
|
||||
String updatedAt = "";
|
||||
//频道头像
|
||||
String avatar = "";
|
||||
//版本
|
||||
int version = 0;
|
||||
//扩展字段
|
||||
dynamic localExtra;
|
||||
//是否在线
|
||||
int online = 0;
|
||||
//最后一次离线时间
|
||||
int lastOffline = 0;
|
||||
// 最后一次离线设备标识
|
||||
int deviceFlag = 0;
|
||||
//是否回执消息
|
||||
int receipt = 0;
|
||||
// 机器人
|
||||
int robot = 0;
|
||||
//分类[service:客服]
|
||||
String category = "";
|
||||
String username = "";
|
||||
String avatarCacheKey = "";
|
||||
dynamic remoteExtraMap;
|
||||
String parentChannelID = "";
|
||||
int parentChannelType = 0;
|
||||
}
|
||||
```
|
67
src/sdk/flutter/channel_member.md
Normal file
67
src/sdk/flutter/channel_member.md
Normal file
@ -0,0 +1,67 @@
|
||||
# 频道成员管理
|
||||
### 获取频道成员
|
||||
#### 频道内所有成员
|
||||
```dart
|
||||
// 获取频道内所有成员
|
||||
WKIM.shared.channelMemberManager.getMembers(channelId: channelId);
|
||||
```
|
||||
#### 频道内指定用户的成员信息
|
||||
```dart
|
||||
// 获取频道内指定用户的成员信息
|
||||
WKIM.shared.channelMemberManager.getMember(channelId: channelId,uid;
|
||||
```
|
||||
|
||||
### 事件
|
||||
#### 刷新频道成员
|
||||
```dart
|
||||
// 刷新频道成员
|
||||
WKIM.shared.channelMemberManager.addOnRefreshMemberListener('key', (WKChannelMember member,bool isEnd){
|
||||
// todo 刷新会话列表
|
||||
});
|
||||
|
||||
// 移除刷新频道成员监听
|
||||
WKIM.shared.channelMemberManager.removeRefreshMemberListener('key');
|
||||
```
|
||||
|
||||
- <font color='#999' size=2>注:key为监听的唯一标识,可以为任意字符串,添加监听和移出监听时需要传入相同的key</font>
|
||||
|
||||
### 数据结构说明
|
||||
```dart
|
||||
class WKChannelMember {
|
||||
String channelID = "";
|
||||
//频道类型
|
||||
int channelType = 0;
|
||||
//成员id
|
||||
String memberUID = "";
|
||||
//成员名称
|
||||
String memberName = "";
|
||||
//成员备注
|
||||
String memberRemark = "";
|
||||
//成员头像
|
||||
String memberAvatar = "";
|
||||
//成员角色
|
||||
int role = 0;
|
||||
//成员状态黑名单等1:正常2:黑名单
|
||||
int status = 0;
|
||||
//是否删除
|
||||
int isDeleted = 0;
|
||||
//创建时间
|
||||
String createdAt = "";
|
||||
//修改时间
|
||||
String updatedAt = "";
|
||||
//版本
|
||||
int version = 0;
|
||||
// 机器人0否1是
|
||||
int robot = 0;
|
||||
//扩展字段
|
||||
dynamic extraMap;
|
||||
// 用户备注
|
||||
String remark = "";
|
||||
// 邀请者uid
|
||||
String memberInviteUID = "";
|
||||
// 被禁言到期时间
|
||||
int forbiddenExpirationTime = 0;
|
||||
String memberAvatarCacheKey = "";
|
||||
}
|
||||
|
||||
```
|
21
src/sdk/flutter/cmd.md
Normal file
21
src/sdk/flutter/cmd.md
Normal file
@ -0,0 +1,21 @@
|
||||
# 命令管理
|
||||
CMD(命令)消息只能是服务器下发客户端进行解析 cmd消息格式
|
||||
### 监听命令消息
|
||||
|
||||
```dart
|
||||
// 监听命令消息
|
||||
WKIM.shared.cmdManager.addOnCmdListener('chat', (cmdMsg) {
|
||||
// todo 按需处理cmd消息
|
||||
});
|
||||
|
||||
// 移除监听
|
||||
WKIM.shared.cmdManager.removeCmdListener('chat');
|
||||
```
|
||||
|
||||
### 数据结构说明
|
||||
```dart
|
||||
class WKCMD {
|
||||
String cmd = ''; // 命令ID
|
||||
dynamic param; // 对应命令参数
|
||||
}
|
||||
```
|
68
src/sdk/flutter/conversation.md
Normal file
68
src/sdk/flutter/conversation.md
Normal file
@ -0,0 +1,68 @@
|
||||
# 最近会话管理
|
||||
|
||||
### 获取最近会话
|
||||
#### 所有最近会话
|
||||
|
||||
```dart
|
||||
// 查询所有最近会话
|
||||
WKIM.shared.conversationManager.getAll();
|
||||
```
|
||||
|
||||
#### 新消息
|
||||
|
||||
只有第一次打开应用时,需要同步最近会话列表, 后续最近会话列表的变化,通过监听来获取
|
||||
```dart
|
||||
WKIM.getInstance().getConversationManager().addOnRefreshMsgListener("key", new IRefreshConversationMsg() {
|
||||
@Override
|
||||
public void onRefreshConversationMsg(WKUIConversationMsg wkUIConversationMsg, boolean isEnd) {
|
||||
// wkUIConversationMsg 最近会话消息内容 UI上已有该会话需进行更新,反之添加到UI上
|
||||
// isEnd 为了防止频繁刷新UI,当isEnd为true可刷新UI
|
||||
}
|
||||
});
|
||||
```
|
||||
### 删除最近会话
|
||||
|
||||
```dart
|
||||
// 删除最近会话
|
||||
WKIM.shared.conversationManager.deleteMsg(channelId,channelType);
|
||||
```
|
||||
|
||||
### 常用方法
|
||||
|
||||
```dart
|
||||
// 设置红点
|
||||
WKIM.shared.conversationManager.updateRedDot(channelId,channelType,count);
|
||||
|
||||
// 删除所有最近会话
|
||||
WKIM.shared.conversationManager.clearAll();
|
||||
```
|
||||
|
||||
### 数据结构说明
|
||||
|
||||
```dart
|
||||
|
||||
class WKConversationMsg {
|
||||
//频道id
|
||||
String channelID = '';
|
||||
//频道类型
|
||||
int channelType = WKChannelType.personal;
|
||||
//最后一条消息本地ID
|
||||
String lastClientMsgNO = '';
|
||||
//是否删除
|
||||
int isDeleted = 0;
|
||||
//服务器同步版本号
|
||||
int version = 0;
|
||||
//最后一条消息时间
|
||||
int lastMsgTimestamp = 0;
|
||||
//未读消息数量
|
||||
int unreadCount = 0;
|
||||
//最后一条消息序号
|
||||
int lastMsgSeq = 0;
|
||||
//扩展字段
|
||||
dynamic localExtraMap;
|
||||
WKConversationMsgExtra? msgExtra;
|
||||
String parentChannelID = '';
|
||||
int parentChannelType = 0;
|
||||
}
|
||||
|
||||
```
|
101
src/sdk/flutter/datasource.md
Normal file
101
src/sdk/flutter/datasource.md
Normal file
@ -0,0 +1,101 @@
|
||||
# 数据源管理
|
||||
|
||||
### 文件
|
||||
在自定义附件消息的时候发送给对方的消息是将网络地址发送给对方,并不是实际的文件。这个时候我们就需监听附件的上传
|
||||
|
||||
#### 监听上传附件
|
||||
```dart
|
||||
// 监听上传消息附件
|
||||
WKIM.shared.messageManager.addOnUploadAttachmentListener((wkMsg, back) {
|
||||
if (wkMsg.contentType == WkMessageContentType.image) {
|
||||
// todo 上传附件
|
||||
WKImageContent imageContent = wkMsg.messageContent! as WKImageContent;
|
||||
imageContent.url = 'xxxxxx';
|
||||
wkMsg.messageContent = imageContent;
|
||||
back(wkMsg);
|
||||
}
|
||||
if (wkMsg.contentType == WkMessageContentType.voice) {
|
||||
// todo 上传语音
|
||||
WKVoiceContent voiceContent = wkMsg.messageContent! as WKVoiceContent;
|
||||
voiceContent.url = 'xxxxxx';
|
||||
wkMsg.messageContent = voiceContent;
|
||||
back(wkMsg);
|
||||
} else if (wkMsg.contentType == WkMessageContentType.video) {
|
||||
WKVideoContent videoContent = wkMsg.messageContent! as WKVideoContent;
|
||||
// todo 上传封面及视频
|
||||
videoContent.cover = 'xxxxxx';
|
||||
videoContent.url = 'ssssss';
|
||||
wkMsg.messageContent = videoContent;
|
||||
back(wkMsg);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
#### 附件下载
|
||||
|
||||
sdk 中不会主动下载消息的附件。在收到带有附件的消息时需要 应用 自己按需下载。在 应用 下载完成后可改文件本地地址,避免重复下载
|
||||
|
||||
```dart
|
||||
/**
|
||||
* 修改消息内容体
|
||||
*
|
||||
* @param clientMsgNo 客户端消息ID
|
||||
* @param messageContent 消息module 将本地地址保存在 messageContent 中
|
||||
* @param isRefreshUI 是否通知UI刷新对应消息
|
||||
*/
|
||||
WKIM.shared.messageManager.updateContent(String clientMsgNo, WKMessageContent messageContent, boolean isRefreshUI);
|
||||
```
|
||||
|
||||
### 最近会话
|
||||
#### 监听同步会话
|
||||
```dart
|
||||
WKIM.shared.conversationManager
|
||||
.addOnSyncConversationListener((lastSsgSeqs, msgCount, version, back) {
|
||||
/**
|
||||
* 同步会话
|
||||
*
|
||||
* @param lastSsgSeqs 最近会话列表msg_seq集合
|
||||
* @param msgCount 会话里面消息同步数量
|
||||
* @param version 最大版本号
|
||||
* @param back 回调
|
||||
*/
|
||||
// 需要请求业务接口将数据返回给sdk
|
||||
back(conversation);
|
||||
});
|
||||
```
|
||||
|
||||
### 频道
|
||||
#### 频道资料数据源
|
||||
```dart
|
||||
// 监听获取channel信息
|
||||
WKIM.shared.channelManager.addOnGetChannelListener((channelId, channelType, back) {
|
||||
// 获取到资料后 通过back返回
|
||||
// 或调用 WKIM.shared.channelManager.addOrUpdateChannel()方法更新sdk中channel资料
|
||||
});
|
||||
```
|
||||
|
||||
也可以批量保存频道资料信息
|
||||
```dart
|
||||
// 批量保存频道资料信息
|
||||
WKIM.shared.channelManager.addOrUpdateChannels(channels);
|
||||
```
|
||||
|
||||
### 消息
|
||||
#### 频道消息数据源
|
||||
```dart
|
||||
WKIM.shared.messageManager.addOnSyncChannelMsgListener((channelID,
|
||||
channelType, startMessageSeq, endMessageSeq, limit, pullMode, back) {
|
||||
/*
|
||||
* 同步某个频道的消息
|
||||
*
|
||||
* @param channelID 频道ID
|
||||
* @param channelType 频道类型
|
||||
* @param startMessageSeq 开始消息列号(结果包含start_message_seq的消息)
|
||||
* @param endMessageSeq 结束消息列号(结果不包含end_message_seq的消息)
|
||||
* @param limit 消息数量限制
|
||||
* @param pullMode 拉取模式 0:向下拉取 1:向上拉取
|
||||
* @param iSyncChannelMsgBack 请求返回
|
||||
*/
|
||||
// todo 请求接口后需返回给sdk
|
||||
});
|
||||
```
|
BIN
src/sdk/flutter/fluttersdk.png
Normal file
BIN
src/sdk/flutter/fluttersdk.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 308 KiB |
14
src/sdk/flutter/integration.md
Normal file
14
src/sdk/flutter/integration.md
Normal file
@ -0,0 +1,14 @@
|
||||
# 集成
|
||||
|
||||
## 快速入门
|
||||
#### 安装
|
||||
[](https://pub.dartlang.org/packages/wukongimfluttersdk)
|
||||
|
||||
```
|
||||
dependencies:
|
||||
wukongimfluttersdk: ^version // 版本号看上面
|
||||
```
|
||||
#### 引入
|
||||
```dart
|
||||
import 'package:wukongimfluttersdk/wkim.dart';
|
||||
```
|
45
src/sdk/flutter/intro.md
Normal file
45
src/sdk/flutter/intro.md
Normal file
@ -0,0 +1,45 @@
|
||||
# 说明
|
||||
|
||||
## 设计理念
|
||||
|
||||
为了让开发者更快更方便的使用 SDK,悟空 SDK 提供了一个唯一的入口来访问 SDK 中的所有功能。就像书籍的目录一样可以通过目录查找对应的内容。如连接 IM `WKIM.shared.connectionManager.connect();`
|
||||
|
||||
## 结构说明
|
||||
|
||||

|
||||
|
||||
SDK 常用功能介绍
|
||||
|
||||
```dart
|
||||
// 消息管理器
|
||||
// 负责消息的增删改查、新消息监听、刷新消息监听、消息入库、监听同步某个聊天数据等
|
||||
WKIM.shared.messageManager
|
||||
|
||||
// 最近会话管理
|
||||
// 获取最近聊天记录、刷新最近会话[新增聊天、红点改变]、监听移除某个会话、监听同步最近会话等
|
||||
WKIM.shared.conversationManager
|
||||
|
||||
// 连接管理
|
||||
// 负责IM的连接、断开、退出登录、监听连接状态、监听获取连接IP等
|
||||
WKIM.shared.connectionManager
|
||||
|
||||
// 频道管理
|
||||
// 可获取Channel的信息,刷新Channel缓存,监听Channel更改[置顶、免打扰、禁言]等
|
||||
WKIM.shared.channelManager
|
||||
|
||||
// 频道成员管理
|
||||
// 获取Channel成员列表、设置成员备注、保存修改成员数据、监听刷新成员和移除成员等
|
||||
WKIM.shared.channelMemberManager
|
||||
|
||||
// 提醒项管理
|
||||
// 获取某个会话的提醒如:[有人@我] [入群申请] 等。还可自定义提醒项,如像 语音未读 等
|
||||
WKIM.shared.reminderManager
|
||||
|
||||
// 命令管理
|
||||
// 负责监听服务器下发的命令消息
|
||||
WKIM.shared.cmdManager
|
||||
```
|
||||
|
||||
### SDK 与 APP 交互原则
|
||||
|
||||
 sdk 与 app 交互流程就是 app 调用 sdk 提供的方法,sdk 处理完数据后通过事件将数据回调给 app。如发送消息流程:app 调用发送消息方法,sdk 将入库后的消息 push 给 app
|
180
src/sdk/flutter/message.md
Normal file
180
src/sdk/flutter/message.md
Normal file
@ -0,0 +1,180 @@
|
||||
# 消息管理
|
||||
|
||||
|
||||
### 发送消息
|
||||
|
||||
```dart
|
||||
WKIM.shared.messageManager.sendMessage(WKTextContent('我是文本消息'), WKChannel('uid_1', WKChannelType.personal));
|
||||
```
|
||||
|
||||
如给用户`A`发送一条文本消息。构建文本消息正文
|
||||
|
||||
```dart
|
||||
WKTextContent textContent = new WKTextContent("你好,悟空");
|
||||
```
|
||||
|
||||
将消息发送给用户`A`
|
||||
|
||||
```dart
|
||||
WKIM.shared.messageManager.sendMessage(textContent,WKChannel('A', WKChannelType.personal));
|
||||
```
|
||||
|
||||
#### 文本消息
|
||||
```dart
|
||||
class WKTextContent extends WKMessageContent {
|
||||
WKTextContent(content) {
|
||||
contentType = WkMessageContentType.text;
|
||||
this.content = content;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 图片消息
|
||||
```dart
|
||||
class WKImageContent extends WKMediaMessageContent {
|
||||
int width;
|
||||
int height;
|
||||
WKImageContent(this.width, this.height) {
|
||||
contentType = WkMessageContentType.image;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 语音消息
|
||||
```dart
|
||||
class WKVoiceContent extends WKMediaMessageContent {
|
||||
int timeTrad; // 语音秒长
|
||||
String? waveform; // 语音波纹 base64编码
|
||||
WKVoiceContent(this.timeTrad) {
|
||||
contentType = WkMessageContentType.voice;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 消息入库返回(并不是消息发送状态)
|
||||
在发送消息时,sdk 将消息保存在本地数据库后就会触发入库回调。此时消息并未进行发送,可在此监听中将消息展示在 UI 上
|
||||
|
||||
监听消息入库事件
|
||||
```dart
|
||||
WKIM.shared.messageManager.addOnMsgInsertedListener((wkMsg) {
|
||||
// 展示在UI
|
||||
});
|
||||
```
|
||||
|
||||
### 新消息
|
||||
监听新消息事件
|
||||
|
||||
```dart
|
||||
WKIM.shared.messageManager.addOnNewMsgListener('chat', (msgs) {
|
||||
// 展示在UI上
|
||||
});
|
||||
```
|
||||
- <font color='#999' size=2>如果在聊天页面内收到新消息时需判断该消息是否属于当前会话,可通过消息对象`WKMsg`的`channelID`和`channelType`判断</font>
|
||||
|
||||
|
||||
### 刷新消息监听
|
||||
|
||||
在 sdk 更新过消息时,如:消息发送状态,有人点赞消息,消息已读回执,消息撤回,消息被编辑等等,sdk 都将回调以下事件。UI 可通过消息对象`WKMsg`的`clientMsgNO`来判断具体是哪条消息发生了更改。
|
||||
|
||||
监听刷新消息事件
|
||||
```dart
|
||||
WKIM.shared.messageManager.addOnRefreshMsgListener('chat', (wkMsg) {
|
||||
// todo 刷新消息
|
||||
});
|
||||
```
|
||||
|
||||
### 查看某个频道的聊天信息
|
||||
```dart
|
||||
/*
|
||||
* 查询或同步某个频道消息
|
||||
*
|
||||
* @param channelId 频道ID
|
||||
* @param channelType 频道类型
|
||||
* @param oldestOrderSeq 最后一次消息大orderSeq 第一次进入聊天传入0
|
||||
* @param contain 是否包含 oldestOrderSeq 这条消息
|
||||
* @param pullMode 拉取模式 0:向下拉取 1:向上拉取
|
||||
* @param aroundMsgOrderSeq 查询此消息附近消息 如 aroundMsgOrderSeq=20 返回数据则是 [16,17,19,20,21,22,23,24,25]
|
||||
* @param limit 每次获取数量
|
||||
* @param iGetOrSyncHistoryMsgBack 请求返还
|
||||
* @param syncBack 同步消息时回掉,可通过此回掉显示加载中
|
||||
*/
|
||||
WKIM.shared.messageManager.getOrSyncHistoryMessages(
|
||||
channelID, channelType, oldestOrderSeq, contain, pullMode, limit, aroundMsgOrderSeq, Function(List<WKMsg>)){
|
||||
|
||||
},Function() syncBack);
|
||||
```
|
||||
|
||||
- <font color='#999' size=2>获取历史消息并不是同步方法,因为有可能存在非连续性时会往服务器同步数据</font>
|
||||
|
||||
### 离线消息
|
||||
`需要实现同步频道消息数据源` [频道消息数据源](/sdk/flutter/datasource.html#频道消息数据源)
|
||||
|
||||
因为WuKongIM 是支持消息永久存储,所以会产生海量的离线消息。对此我们采用了按需拉取的机制,如 10 个会话一个会话 10 万条消息,WuKongIM 不会把这个 10\*10 万=100 万条消息都拉取到本地。 而是采用拉取这 10 个会话的信息和对应的最新 20 条消息,也就是实际只拉取了 200 条消息 相对 100 万条消息来说大大提高了离线拉取速度。用户点进对应的会话才会去按需拉取这个会话的消息。 这些机制 SDK 内部都已做好了封装,使用者其实不需要关心。使用者只需要关心最近会话的变化和监听获取数据的回调即可。
|
||||
|
||||
### 数据结构说明
|
||||
|
||||
#### 消息类核心属性
|
||||
```dart
|
||||
class WKMsg {
|
||||
// 消息头 redDot:是否显示红点 noPersist:是否不存储 syncOnce:是否只同步一次
|
||||
MessageHeader header = MessageHeader();
|
||||
// 消息设置 receipt:是否回执,topic:是否话题聊天,stream:是否流消息;
|
||||
Setting setting = Setting();
|
||||
// 服务器消息ID(全局唯一,无序)
|
||||
String messageID = "";
|
||||
// 服务器消息ID(有序)
|
||||
int messageSeq = 0;
|
||||
// 本地消息有序ID
|
||||
int clientSeq = 0;
|
||||
// 10位时间戳
|
||||
int timestamp = 0;
|
||||
// 本地唯一ID
|
||||
String clientMsgNO = "";
|
||||
// 发送者
|
||||
String fromUID = "";
|
||||
// 所属频道ID
|
||||
String channelID = "";
|
||||
// 所属频道类型
|
||||
int channelType = WKChannelType.personal;
|
||||
// 消息正文类型 如 1:【文本】2:【图片】...
|
||||
int contentType = 0;
|
||||
// 消息负载
|
||||
String content = "";
|
||||
// 消息状态 0.发送中 1.成功
|
||||
int status = 0;
|
||||
// 是否被删除 1.是
|
||||
int isDeleted = 0;
|
||||
// 发送者的资料
|
||||
WKChannel? _from;
|
||||
// 所属频道资料
|
||||
WKChannel? _channelInfo;
|
||||
// 发送者在频道内类型资料(群消息才有值)
|
||||
WKChannelMember? _memberOfFrom;
|
||||
// 排序号
|
||||
int orderSeq = 0;
|
||||
// 本地扩展字段
|
||||
dynamic localExtraMap;
|
||||
// 远程扩展字段,服务器维护
|
||||
WKMsgExtra? wkMsgExtra;
|
||||
// 本条消息回应数据
|
||||
List<WKMsgReaction>? reactionList;
|
||||
// 消息正文体 contentType==1.WKTextContent contentType==2.WKImageConent
|
||||
WKMessageContent? messageContent;
|
||||
}
|
||||
```
|
||||
|
||||
#### 消息正文体
|
||||
```dart
|
||||
class WKMessageContent {
|
||||
// 消息类型 1.文本 2.图片
|
||||
var contentType = 0;
|
||||
// 消息内容
|
||||
String content = "";
|
||||
// 回复消息
|
||||
WKReply? reply;
|
||||
// 消息内容渲染数据
|
||||
List<WKMsgEntity>? entities;
|
||||
// 提醒信息
|
||||
WKMentionInfo? mentionInfo;
|
||||
}
|
||||
```
|
45
src/sdk/flutter/reminder.md
Normal file
45
src/sdk/flutter/reminder.md
Normal file
@ -0,0 +1,45 @@
|
||||
# 提醒项管理
|
||||
会话提醒目前只支持服务器下发指令。客户端只需监听同步会话提醒和监听刷新会话消息即可
|
||||
|
||||
### 获取提醒项
|
||||
|
||||
```dart
|
||||
// 获取指定频道的提醒项列表
|
||||
WKIM.shared.reminderManager.getWithChannel(channelId,channelType)
|
||||
```
|
||||
|
||||
### 保存提醒项
|
||||
|
||||
```dart
|
||||
// 保存提醒项
|
||||
WKIM.shared.reminderManager.saveOrUpdateReminders(list)
|
||||
```
|
||||
### 事件
|
||||
#### 新增提醒项
|
||||
```dart
|
||||
// 监听新增提醒项
|
||||
WKIM.shared.reminderManager.addOnNewReminderListener(key, (reminder) {
|
||||
// 处理新增提醒项
|
||||
});
|
||||
|
||||
// 移除监听
|
||||
WKIM.shared.reminderManager.removeOnNewReminderListener(key);
|
||||
```
|
||||
- <font color='#999' size=2>注:key为监听的唯一标识,可以为任意字符串,添加监听和移出监听时需要传入相同的key</font>
|
||||
### 数据结构说明
|
||||
```dart
|
||||
class WKReminder {
|
||||
int reminderID = 0; // 提醒项ID
|
||||
String messageID = ''; // 消息ID
|
||||
String channelID = ''; // 频道ID
|
||||
int channelType = 0; // 频道类型
|
||||
int messageSeq = 0; // 消息序列号
|
||||
int type = 0; // 提醒类型
|
||||
String text = ''; // 提醒内容
|
||||
dynamic data; // 附加数据
|
||||
int version = 0; // 版本号
|
||||
int done = 0; // 完成状态
|
||||
int needUpload = 0; // 是否需要上传(这里是指上传到业务服务器)
|
||||
String publisher = ''; // 发布者
|
||||
}
|
||||
```
|
352
src/sdk/harmonyos/advance.md
Normal file
352
src/sdk/harmonyos/advance.md
Normal file
@ -0,0 +1,352 @@
|
||||
# 高级功能
|
||||
|
||||
### 自定义消息
|
||||
在WuKongIM 中所有的消息类型都是自定义消息
|
||||
|
||||
#### 自定义普通消息
|
||||
下面我们以名片消息举例
|
||||
|
||||
##### 第一步 定义消息
|
||||
定义消息对象并继承 WKMessageContent 并在构造方法中指定消息类型
|
||||
|
||||
```typescripts
|
||||
// 定义名片消息
|
||||
export class CardMessageContent extends WKMessageContent {
|
||||
uid: string = ''
|
||||
name: string = ''
|
||||
avatar: string = ''
|
||||
constructor() {
|
||||
super();
|
||||
this.contentType = 16 // 指定类型
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
##### 第二步 编码和解码
|
||||
我们需要将uid,name,avatar三个字段信息发送给对方,最终传递的消息内容为
|
||||
```typescripts
|
||||
{
|
||||
"type": 16,
|
||||
"uid": "xxxx",
|
||||
"name": "xxx",
|
||||
"avatar": "xxx"
|
||||
}
|
||||
```
|
||||
重写`WKMessageContent`的`encodeJson`方法开始编码
|
||||
|
||||
```typescripts
|
||||
|
||||
// 编码发送内容
|
||||
encodeJson(): Record<string, Object> {
|
||||
let json: Record<string, Object> = {}
|
||||
json['uid'] = this.uid
|
||||
json['name'] = this.name
|
||||
json['avatar'] = this.avatar
|
||||
return json
|
||||
}
|
||||
|
||||
```
|
||||
重写`WKMessageContent`的`decodeJson`方法开始解码
|
||||
```typescripts
|
||||
|
||||
// 解码内容
|
||||
decodeJson(jsonStr: string): WKMessageContent {
|
||||
let json = CommonUtil.jsonToRecord(jsonStr)
|
||||
if (json !== undefined) {
|
||||
this.uid = CommonUtil.readString(json, 'uid')
|
||||
this.name = CommonUtil.readString(json, 'name')
|
||||
this.avatar = CommonUtil.readString(json, 'avatar')
|
||||
}
|
||||
return this
|
||||
}
|
||||
```
|
||||
- <font color='#999' size=2>解码和编码消息时无需将 `type` 字段考虑其中,sdk 内部会自动处理</font>
|
||||
##### 第三步 注册消息
|
||||
```typescripts
|
||||
// 注册自定义消息
|
||||
WKIM.shared.messageManager().registerMsgContent(16, (jsonStr: string) => {
|
||||
return new CardMessageContent().decodeJson(jsonStr)
|
||||
})
|
||||
```
|
||||
对此通过这三步自定义普通消息就已完成。在收到消息时`WKMsg`中的`type`为16就表示该消息是名片消息,其中`messageContent`则为自定义的`CardMessageContent`,这时可将`messageContent`强转为`CardMessageContent`并渲染到UI上
|
||||
完整代码
|
||||
```typescripts
|
||||
|
||||
// 自定义普通消息
|
||||
export class CardMessageContent extends WKMessageContent {
|
||||
uid: string = ''
|
||||
name: string = ''
|
||||
avatar: string = ''
|
||||
constructor() {
|
||||
super();
|
||||
this.contentType = 16 // 指定类型
|
||||
}
|
||||
|
||||
// 编码发送内容
|
||||
encodeJson(): Record<string, Object> {
|
||||
let json: Record<string, Object> = {}
|
||||
json['uid'] = this.uid
|
||||
json['name'] = this.name
|
||||
json['avatar'] = this.avatar
|
||||
return json
|
||||
}
|
||||
|
||||
// 解码内容
|
||||
decodeJson(jsonStr: string): WKMessageContent {
|
||||
let json = CommonUtil.jsonToRecord(jsonStr)
|
||||
if (json !== undefined) {
|
||||
this.uid = CommonUtil.readString(json, 'uid')
|
||||
this.name = CommonUtil.readString(json, 'name')
|
||||
this.avatar = CommonUtil.readString(json, 'avatar')
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
// 最近会话显示内容
|
||||
displayText(): string {
|
||||
return '[名片]'
|
||||
}
|
||||
}
|
||||
```
|
||||
### 自定义附件消息
|
||||
我们在发送消息的时候有时需发送带附件的消息。WuKongIM 也提供自定义附件消息,自定义附件消息和普通消息区别不大。下面我们已地理位置消息举例
|
||||
|
||||
##### 第一步 定义消息
|
||||
值得注意的是自定义附件消息需继承`WKMediaMessageContent`而不是`WKMessageContent`
|
||||
```typescripts
|
||||
export class LocationMessageContent extends WKMediaMessageContent {
|
||||
address: string = ''
|
||||
longitude: number = 0.0
|
||||
latitude: number = 0.0
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.contentType = 17 // 指定类型
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- <font color='#999' size=2>`WKMediaMessageContent`提供了`url`,`localPath`字段,自定义消息无需在定义网络地址和本地地址字段</font>
|
||||
|
||||
##### 第二步 编码和解码
|
||||
我们需要将`longitude`,`latitude`,`address`,`url`信息发送给对方,最终传递的消息内容为
|
||||
```typescripts
|
||||
{
|
||||
"type": 17,
|
||||
"longitude": 115.25,
|
||||
"latitude": 39.26,
|
||||
"url": "xxx",
|
||||
"address": "xxx"
|
||||
}
|
||||
```
|
||||
重写`WKMessageContent`的encodeJson方法开始编码
|
||||
```typescripts
|
||||
// 编码
|
||||
encodeJson(): Record<string, Object> {
|
||||
let json: Record<string, Object> = {}
|
||||
json['url'] = this.url
|
||||
json['longitude'] = this.longitude
|
||||
json['latitude'] = this.latitude
|
||||
return json
|
||||
}
|
||||
```
|
||||
重写`WKMessageContent`的`decodeJson`方法开始解码
|
||||
```typescripts
|
||||
// 解码
|
||||
decodeJson(jsonStr: string): WKMessageContent {
|
||||
let json = CommonUtil.jsonToRecord(jsonStr)
|
||||
if (json !== undefined) {
|
||||
this.address = CommonUtil.readString(json, 'address')
|
||||
this.url = CommonUtil.readString(json, 'url')
|
||||
this.longitude = CommonUtil.readNumber(json, 'longitude')
|
||||
this.latitude = CommonUtil.readNumber(json, 'latitude')
|
||||
}
|
||||
return this
|
||||
}
|
||||
```
|
||||
##### 第三步 注册消息
|
||||
```typescripts
|
||||
// 注册自定义消息
|
||||
WKIM.shared.messageManager().registerMsgContent(17, (jsonStr: string) => {
|
||||
return new LocationMessageContent().decodeJson(jsonStr)
|
||||
})
|
||||
```
|
||||
### 消息扩展
|
||||
随着业务的发展应用在聊天中的功能也日益增多,为了满足绝大部分的需求 WuKongIM 中增加了消息扩展功能。消息扩展分`本地扩展`和`远程扩展`,本地扩展只针对 app 本地使用卸载 app 后将丢失,远程扩展是服务器保存卸载重装后数据将恢复
|
||||
#### 本地扩展
|
||||
本地扩展就是消息对象`WKMsg`中的l`localExtraMap`字段
|
||||
```typescripts
|
||||
/**
|
||||
* 修改消息本地扩展
|
||||
*
|
||||
* @param clientMsgNo 客户端ID
|
||||
* @param extra 扩展字段
|
||||
*/
|
||||
WKIM.shared.messageManager().updateLocalExtra(clientMsgNo: string, extra: Record<string, Object>)
|
||||
```
|
||||
|
||||
- <font color='#999' size=2>更新成功后 sdk 会触发刷新消息回调</font>
|
||||
#### 远程扩展
|
||||
远程扩展就是消息对象`WKMsg`中的`remoteExtra`字段
|
||||
|
||||
```typescripts
|
||||
WKIM.shared.messageManager().saveRemoteExtras(list: WKMsgExtra[])
|
||||
```
|
||||
|
||||
- <font color='#999' size=2>更新成功后 sdk 会触发刷新消息回调</font>
|
||||
##### 数据结构说明
|
||||
```typescripts
|
||||
|
||||
export class WKMsgExtra {
|
||||
// 消息ID
|
||||
messageId = ''
|
||||
// 频道ID
|
||||
channelId = ''
|
||||
// 频道类型
|
||||
channelType: number = WKChannelType.personal
|
||||
// 是否已读 1.是
|
||||
readed = 0
|
||||
// 已读数量
|
||||
readedCount = 0
|
||||
// 未读数量
|
||||
unreadCount = 0
|
||||
// 是否撤回 1.是
|
||||
revoke = 0
|
||||
// 是否删除
|
||||
isMutualDeleted = 0
|
||||
// 撤回者uid
|
||||
revoker = ''
|
||||
// 版本号
|
||||
extraVersion = 0
|
||||
// 编辑时间
|
||||
editedAt = 0
|
||||
// 编辑内容
|
||||
contentEdit = ''
|
||||
// 是否需要上传 1.是
|
||||
needUpload = 0
|
||||
// 是否置顶
|
||||
isPinned = 0
|
||||
// 编辑后正文
|
||||
contentEditMsgModel?: WKMessageContent
|
||||
}
|
||||
|
||||
```
|
||||
### 消息已读未读
|
||||
消息的已读未读又称消息回执。消息回执功能可通过 setting 进行设置
|
||||
|
||||
```typescripts
|
||||
let option = new WKSendOptions()
|
||||
option.setting.receipt = 1 // 开启回执
|
||||
// 发送消息
|
||||
WKIM.shared.messageManager().sendWithOption(textModel, channel, option)
|
||||
```
|
||||
当登录用户浏览过对方发送的消息时,如果对方开启了消息回执这时需将查看过的消息上传到服务器标记该消息已读。当对方或者自己上传过已读消息这时业务服务器会下发同步消息扩展的 cmd(命令)消息`syncMessageExtra`,此时需同步最新消息扩展保存到 sdk 中
|
||||
|
||||
### 消息编辑
|
||||
当我们给对方发送消息发现发送内容有错误时,这时无需撤回重发只需要将消息编辑即可
|
||||
|
||||
<video controls height='30%' width='30%' src="/video/msgedit.mp4"></video>
|
||||
#### 设置编辑内容
|
||||
```typescripts
|
||||
/**
|
||||
* 修改编辑内容
|
||||
* @param messageId 消息服务器ID
|
||||
* @param channelId 频道ID
|
||||
* @param channelType 频道类型
|
||||
* @param content 编辑后的内容
|
||||
*/
|
||||
WKIM.shared.messageManager().updateEdit(messageId: string, channelId: string, channelType: number, content: string)
|
||||
```
|
||||
更改 sdk 消息编辑内容后需将编辑后的内容上传到服务器,则需要监听上传消息扩展
|
||||
|
||||
```typescripts
|
||||
WKIM.shared.config.provider.uploadMessageExtraCallback = (extra: WKMsgExtra) => {
|
||||
//上传到业务服务器
|
||||
}
|
||||
```
|
||||
### 消息回复
|
||||
|
||||
|
||||
在聊天中如果消息过多,发送消息回复就会显得消息很乱无章可循。这时就需要对某条消息进行特定的回复,即消息回复,如以下效果 <img src='./../msg_reply.jpg' width=30%/>
|
||||
|
||||
在发送消息时,只需将消息正文`WKMessageContent`中的`WKReply`对象赋值就能对达到消息回复效果
|
||||
|
||||
```typescripts
|
||||
let textModel: WKTextContent = new WKTextContent(this.sendContent)
|
||||
textModel.reply = new WKReply()
|
||||
textModel.reply.messageId = ''
|
||||
// 设置其他字段信息
|
||||
|
||||
// 发送消息
|
||||
WKIM.shared.messageManager().send(textModel, channel)
|
||||
```
|
||||
|
||||
#### 回复消息结构说明
|
||||
```typescripts
|
||||
|
||||
export class WKReply {
|
||||
// 被回复的消息根ID,多级回复时的第一次回复的消息ID
|
||||
rootMid = ''
|
||||
// 被回复的消息ID
|
||||
messageId = ''
|
||||
// 被回复的MessageSeq
|
||||
messageSeq = 0
|
||||
// 被回复者uid
|
||||
fromUID = ''
|
||||
// 被回复者名称
|
||||
fromName = ''
|
||||
// 被回复的消息字符串
|
||||
contentEdit = ''
|
||||
// 编辑时间
|
||||
editAt = 0
|
||||
// 回复消息被撤回标记 1.是
|
||||
revoke = 0
|
||||
// 被回复消息编辑后的内容
|
||||
contentEditMsgModel?: WKMessageContent
|
||||
// 被回复的消息体
|
||||
payload?: WKMessageContent
|
||||
}
|
||||
```
|
||||
|
||||
### 消息回应(点赞)
|
||||
#### 保存
|
||||
```typescripts
|
||||
WKIM.shared.messageManager().saveReactions(list: WKMsgReaction[])
|
||||
```
|
||||
|
||||
- <font color='#999' size=2>同一个用户对同一条消息只能做出一条回应。重复进行消息不同 emoji 的回应会做为修改回应,重复进行相同 emoji 的回应则做为删除回应</font> sdk 更新消息回应后会触发消息刷新的事件。app 需监听此事件并对 UI 进行刷新
|
||||
监听消息回应刷新
|
||||
```typescripts
|
||||
// 监听消息回应刷新
|
||||
WKIM.shared.messageManager().addRefreshReactionListener((list)=>{
|
||||
// 刷新 UI
|
||||
})
|
||||
```
|
||||
#### 获取
|
||||
|
||||
```typescripts
|
||||
WKIM.shared.messageManager().getMsgReactions(messageId:string)
|
||||
```
|
||||
|
||||
#### 数据结构说明
|
||||
```typescripts
|
||||
export class WKMsgReaction {
|
||||
// 消息ID
|
||||
messageId = ""
|
||||
// 频道ID
|
||||
channelId = ""
|
||||
// 频道类型
|
||||
channelType = WKChannelType.personal
|
||||
// 回应者uid
|
||||
uid = ""
|
||||
// 消息序号
|
||||
seq = 0
|
||||
// 回应表情
|
||||
emoji = ""
|
||||
// 是否删除 1.是
|
||||
isDeleted = 0
|
||||
// 创建时间
|
||||
createdAt = ""
|
||||
}
|
||||
|
||||
```
|
64
src/sdk/harmonyos/base.md
Normal file
64
src/sdk/harmonyos/base.md
Normal file
@ -0,0 +1,64 @@
|
||||
|
||||
# 基础
|
||||
|
||||
|
||||
### 初始化
|
||||
```typescript
|
||||
// uid 登录用户ID(业务服务端在IM通讯端登记了的uid))
|
||||
// token 登录用户token(业务服务端在IM通讯端登记了的token)
|
||||
await WKIM.shared.init(uid, token)
|
||||
```
|
||||
|
||||
### 连接地址
|
||||
```typescript
|
||||
WKIM.shared.config.provider.connectAddrCallback = (): Promise<string> => {
|
||||
// 通过网络获取连接地址后返回
|
||||
let add = HttpUtil.getIP()
|
||||
return add
|
||||
}
|
||||
```
|
||||
- <font color="#999" font-size=2>返回 IM 通信端的 IP 和 IM 通信端的 TCP 端口。<font color="#FF0000">分布式可调用接口获取 IP 和 Port 后返回</font></font>
|
||||
|
||||
### 连接
|
||||
```typescript
|
||||
// 连接
|
||||
WKIM.shared.connectionManager().connection()
|
||||
```
|
||||
|
||||
### 断开
|
||||
```typescript
|
||||
// 断开 isLogout true:退出并清空用户信息 false:退出保持用户信息
|
||||
WKIM.shared.connectionManager().disConnection(isLogout)
|
||||
```
|
||||
|
||||
### 监听连接状态
|
||||
```typescript
|
||||
// 监听连接状态
|
||||
WKIM.shared.connectionManager()
|
||||
.addConnectStatusListener((status: number, reasonCode?: number, connInfo?: ConnectionInfo) => {
|
||||
switch (status) {
|
||||
case WKConnectStatus.success: {
|
||||
// `悟空IM(连接成功-节点:${connInfo?.nodeId})`
|
||||
break
|
||||
}
|
||||
case WKConnectStatus.fail:
|
||||
// '连接失败'
|
||||
break
|
||||
case WKConnectStatus.connecting:
|
||||
// '连接中...'
|
||||
break
|
||||
case WKConnectStatus.syncing:
|
||||
// '同步中...'
|
||||
break
|
||||
case WKConnectStatus.syncCompleted:
|
||||
// `悟空IM(连接成功-节点:${this.nodeId})`
|
||||
break
|
||||
case WKConnectStatus.noNetwork:
|
||||
// '网络异常'
|
||||
break
|
||||
case WKConnectStatus.kicked:
|
||||
// '其他账号登录'
|
||||
break
|
||||
}
|
||||
})
|
||||
```
|
79
src/sdk/harmonyos/channel.md
Normal file
79
src/sdk/harmonyos/channel.md
Normal file
@ -0,0 +1,79 @@
|
||||
# 频道管理
|
||||
|
||||
频道(Channel)WuKongIM 中是一个比较抽象的概念。发送消息都是先发送给频道,频道根据自己的配置规则进行投递消息,频道分频道和频道详情。 更多介绍请移步[什么是频道](/guide/initialize#频道)
|
||||
|
||||
### 数据源
|
||||
|
||||
`需要实现获取频道资料的数据源` [获取频道资料数据源](/sdk/harmonyos/datasource.html#频道资料数据源)
|
||||
### 频道资料
|
||||
|
||||
#### 获取频道资料
|
||||
```javascrip
|
||||
// 获取频道资料
|
||||
let channel = WKIM.shared.channelManager().getChannel(channelId, channelType)
|
||||
```
|
||||
#### 强制刷新频道资料
|
||||
```javascrip
|
||||
// 强制刷新频道资料
|
||||
WKIM.shared.channelManager().fetchChannelInfo(channelId, channelType)
|
||||
```
|
||||
|
||||
### 事件
|
||||
#### 监听频道资料更新
|
||||
```javascrip
|
||||
refreshChannelListener = (channel: WKChannel) => {
|
||||
// 刷新
|
||||
}
|
||||
// 添加刷新频道监听
|
||||
WKIM.shared.channelManager().addRefreshListener(this.refreshChannelListener)
|
||||
|
||||
// 在退出页面时移除监听
|
||||
WKIM.shared.channelManager().removeRefreshListener(this.refreshChannelListener)
|
||||
```
|
||||
|
||||
### 常用方法
|
||||
```typescript
|
||||
// 保存频道资料
|
||||
WKIM.shared.channelManager().addOrUpdate(channel: WKChannel)
|
||||
|
||||
// 批量保存
|
||||
WKIM.shared.channelManager().addOrUpdates(list: WKChannel[])
|
||||
|
||||
// 修改频道头像缓存地址
|
||||
WKIM.shared.channelManager().updateAvatarCacheKey(channelId: string, channelType: number, key: string)
|
||||
```
|
||||
|
||||
### 数据结构说明
|
||||
```typescript
|
||||
export class WKChannel {
|
||||
channelId: string // 频道ID
|
||||
channelType: number // 频道类型
|
||||
channelName: string = "" // 频道名称
|
||||
channelRemark: string = "" // 频道备注
|
||||
showNick: number = 0 // 显示昵称 0.不显示 1.显示
|
||||
top: number = 0 // 置顶 0.不置顶 1.置顶
|
||||
save: number = 0 // 是否保存到通讯录 0.不保存 1.保存
|
||||
mute: number = 0 // 是否免打扰 0.不免打扰 1.免打扰
|
||||
forbidden: number = 0 // 是否禁言 0.不禁言 1.禁言
|
||||
invite: number = 0 // 是否允许邀请 0.不允许 1.允许
|
||||
status: number = 0 // 频道状态 0.禁用 1.正常
|
||||
follow: number = 0 // 关注状态 0.未关注 1.已关注
|
||||
isDeleted: number = 0 // 是否删除 0.未删除 1.已删除
|
||||
createdAt: string = '' // 创建时间
|
||||
updatedAt: string = '' // 更新时间
|
||||
avatar: string = '' // 头像
|
||||
version: number = 0 // 频道版本
|
||||
online: number = 0 // 在线状态 0.离线 1.在线
|
||||
lastOffline: number = 0 // 最后离线时间
|
||||
deviceFlag: number = 0 // 设备标识 0.APP 1.WEB 2.PC
|
||||
receipt: number = 0 // 是否开启回执 0.未开启 1.开启
|
||||
robot: number = 0 // 是否为机器人 0.不是 1.是
|
||||
category: string = '' // 频道分类
|
||||
username: string = '' // 用户名
|
||||
avatarCacheKey: string = '' // 头像缓存key
|
||||
localExtra?: Record<string, Object> // 本地扩展
|
||||
remoteExtra?: Record<string, Object> // 远程扩展
|
||||
parentChannelId: string = '' // 父频道ID
|
||||
parentChannelType: number = 0 // 父频道类型
|
||||
}
|
||||
```
|
58
src/sdk/harmonyos/channel_member.md
Normal file
58
src/sdk/harmonyos/channel_member.md
Normal file
@ -0,0 +1,58 @@
|
||||
# 频道成员管理
|
||||
### 获取频道成员
|
||||
#### 获取某个频道下的所有成员
|
||||
```typescript
|
||||
// 获取某个channel下的所有成员
|
||||
let members = WKIM.shared.channelMemberManager().getMembers(channelId, channelType)
|
||||
```
|
||||
#### 分页查询频道成员
|
||||
`需要实现分页获取频道成员资料的数据源` [获取分页频道成员资料数据源](/sdk/harmonyos/datasource.html#频道成员分页数据源)
|
||||
```typescript
|
||||
// 分页获取频道成员
|
||||
WKIM.shared.channelMemberManager().getWithPageOrSearch(channelId, channelType,option)
|
||||
```
|
||||
`option`说明
|
||||
```typescript
|
||||
export class SyncChannelMemberOptions {
|
||||
searchKey: string = '' // 搜索关键字
|
||||
page: number = 0 // 页码
|
||||
limit: number = 20 // 每页数量
|
||||
}
|
||||
```
|
||||
### 事件
|
||||
#### 监听刷新频道成员
|
||||
```typescript
|
||||
refreshChannelMemberListener = (members: WKChannelMember[]) => {
|
||||
// 刷新
|
||||
}
|
||||
// 添加刷新频道成员监听
|
||||
WKIM.shared.channelMemberManager().addRefreshListener(this.refreshChannelMemberListener)
|
||||
|
||||
// 在退出页面时移除监听
|
||||
WKIM.shared.channelMemberManager().removeRefreshListener(this.refreshChannelMemberListener)
|
||||
```
|
||||
|
||||
### 数据结构说明
|
||||
```typescript
|
||||
|
||||
export class WKChannelMember {
|
||||
channelId: string = '' // 频道ID
|
||||
channelType: number = WKChannelType.personal // 频道类型
|
||||
memberUID: string = '' // 成员UID
|
||||
memberName: string = '' // 成员名称
|
||||
memberRemark: string = '' // 成员备注
|
||||
memberAvatar: string = '' // 成员头像
|
||||
role = 0 // 成员角色
|
||||
status = 0 // 成员状态
|
||||
isDeleted = 0 // 是否被删除
|
||||
createdAt: string = '' // 创建时间
|
||||
updatedAt: string = '' // 更新时间
|
||||
version = 0 // 版本号
|
||||
robot = 0 // 是否为机器人
|
||||
extra?: Record<string, object> // 扩展字段
|
||||
memberInviteUID: string = '' // 邀请人UID
|
||||
forbiddenExpirationTime = 0 // 禁言截止时间
|
||||
memberAvatarCacheKey: string = '' // 头像缓存key
|
||||
}
|
||||
|
||||
```
|
23
src/sdk/harmonyos/cmd.md
Normal file
23
src/sdk/harmonyos/cmd.md
Normal file
@ -0,0 +1,23 @@
|
||||
# 命令管理
|
||||
CMD(命令)消息只能是服务器下发客户端进行解析 cmd消息格式
|
||||
### 监听命令消息
|
||||
|
||||
```typescript
|
||||
cmdListener = (cmd: WKCMD) => {
|
||||
// 处理CMD消息
|
||||
}
|
||||
// 添加CMD消息监听
|
||||
WKIM.shared.cmdManager().addCmdListener(this.cmdListener)
|
||||
|
||||
|
||||
// 在退出页面时移除监听
|
||||
WKIM.shared.cmdManager().removeCmdListener(this.cmdListener)
|
||||
```
|
||||
|
||||
### 数据结构说明
|
||||
```typescript
|
||||
export class WKCMD {
|
||||
cmd: string = '' // 命令Id
|
||||
paramJsonObject?: Record<string, Object> // 命令参数
|
||||
}
|
||||
```
|
52
src/sdk/harmonyos/conversation.md
Normal file
52
src/sdk/harmonyos/conversation.md
Normal file
@ -0,0 +1,52 @@
|
||||
# 最近会话管理
|
||||
|
||||
### 获取最近会话
|
||||
#### 所有最近会话
|
||||
|
||||
```javascrip
|
||||
// 查询所有最近会话
|
||||
let msgs = WKIM.shared.conversationManager().all()
|
||||
```
|
||||
|
||||
#### 新消息
|
||||
|
||||
只有第一次打开应用时,需要同步最近会话列表, 后续最近会话列表的变化,通过监听来获取
|
||||
```typescript
|
||||
WKIM.shared.conversationManager().addRefreshListener((list:WKConversation[]) => {
|
||||
// 当UI列表没有list中的数据时需执行添加操作
|
||||
})
|
||||
```
|
||||
|
||||
### 删除最近会话
|
||||
```typescript
|
||||
// 删除最近会话
|
||||
WKIM.shared.conversationManager().delete(channelId, channelType)
|
||||
```
|
||||
调用删除最近会话后,会触发删除最近会话事件,UI可以监听删除最近会话事件,并将UI上的会话进行删除
|
||||
```typescript
|
||||
WKIM.shared.conversationManager().addDeletedListener((channelId: string, channelType: number) => {
|
||||
// 删除UI上的会话
|
||||
})
|
||||
```
|
||||
|
||||
### 数据结构说明
|
||||
```typescript
|
||||
export class WKConversation {
|
||||
channelId: string = '' // 频道ID
|
||||
channelType: number = WKChannelType.personal // 频道类型
|
||||
lastClientMsgNo: string = '' // 最后一条消息的序列号
|
||||
isDeleted: number = 0 // 是否被删除
|
||||
version: number = 0 // 会话版本号
|
||||
unreadCount = 0 // 未读消息数
|
||||
lastMsgTimestamp = 0 // 最后一条消息的时间戳
|
||||
lastMsgSeq = 0 // 最后一条消息的序列号
|
||||
parentChannelId = '' // 父会话ID
|
||||
parentChannelType = WKChannelType.personal // 父会话类型
|
||||
localExtra?: Record<string, Object> // 本地扩展字段
|
||||
remoteExtra?: WKConversationExtra // 远程扩展字段
|
||||
private reminders?: WKReminder[] // 提醒项
|
||||
private msg?: WKMsg // 最后一条消息
|
||||
private channel?: WKChannel // 频道信息
|
||||
}
|
||||
|
||||
```
|
118
src/sdk/harmonyos/datasource.md
Normal file
118
src/sdk/harmonyos/datasource.md
Normal file
@ -0,0 +1,118 @@
|
||||
# 数据源管理
|
||||
|
||||
### 文件
|
||||
在自定义附件消息的时候发送给对方的消息是将网络地址发送给对方,并不是实际的文件。这个时候我们就需监听附件的上传
|
||||
#### 上传
|
||||
```typescript
|
||||
// 定义上传文件数据源
|
||||
let uploadAttachmentCallback = async (msg: WKMsg): Promise<[boolean, WKMsg]> => {
|
||||
if (msg.contentType === WKMsgContentType.Image) {
|
||||
// 上传图片
|
||||
let imageContent = msg.messageContent as WKImageContent
|
||||
imageContent.url = 'xxxx'
|
||||
msg.messageContent = imageContent
|
||||
return [true, msg]
|
||||
} else if (msg.contentType === WKMsgContentType.Voice) {
|
||||
// 上传语音
|
||||
let voiceContent = msg.messageContent as WKVoiceContent
|
||||
voiceContent.url = 'xxxx'
|
||||
msg.messageContent = voiceContent
|
||||
return [true, msg]
|
||||
} else if (msg.contentType === WKMsgContentType.Video) {
|
||||
// 上传视频
|
||||
let videoContent = msg.messageContent as WKVideoContent
|
||||
videoContent.url = 'xxxx'
|
||||
msg.messageContent = videoContent
|
||||
return [true, msg]
|
||||
} else if (msg.contentType === 17) {
|
||||
// 上传自定义附件消息
|
||||
let customerMsg = msg.messageContent as LocationMessageContent
|
||||
customerMsg.url = 'https://img1.baidu.com/it/u=3362698628,1928330748&fm=253&fmt=auto&app=138&f=JPEG?w=390&h=308'
|
||||
msg.messageContent = customerMsg
|
||||
return [true, msg]
|
||||
}
|
||||
return [true, msg]
|
||||
}
|
||||
|
||||
// 提供文件上传数据源
|
||||
WKIM.shared.config.provider.uploadAttachmentCallback = uploadAttachmentCallback
|
||||
|
||||
```
|
||||
|
||||
#### 下载
|
||||
sdk 中不会主动下载消息的附件。在收到带有附件的消息时需要 app 自己按需下载。在 app 下载完成后可改文件本地地址,避免重复下载
|
||||
```typescript
|
||||
WKIM.shared.messageManager().updateContent(clientMsgNo: string, messageContent: WKMessageContent)
|
||||
```
|
||||
|
||||
### 最近会话
|
||||
|
||||
#### 同步最近会话数据源
|
||||
```typescript
|
||||
// 定义提供者
|
||||
let syncConversationCallback = async (lastMsgSeqs: string, msgCount: number,
|
||||
version: number): Promise<WKSyncConversation> => {
|
||||
// do 请求接口后返回给sdk
|
||||
}
|
||||
|
||||
// 设置同步最近会话提供者
|
||||
WKIM.shared.config.provider.syncConversationCallback = syncConversationCallback
|
||||
|
||||
```
|
||||
|
||||
### 频道
|
||||
#### 频道资料数据源
|
||||
```typescript
|
||||
// 设置频道资料提供者
|
||||
WKIM.shared.config.provider.channelInfoCallback =
|
||||
async (channelId: string, channelType: number): Promise<WKChannel> => {
|
||||
// 测试数据,实际可通过接口返回
|
||||
WKLogger.error('获取channel资料', channelId, channelType + "")
|
||||
let channel = new WKChannel(channelId, channelType)
|
||||
if (channel.channelType === WKChannelType.personal) {
|
||||
channel.channelName = `单聊${channelId}`
|
||||
channel.channelRemark = `备注${channel.channelName}`
|
||||
} else if (channel.channelType === WKChannelType.group) {
|
||||
channel.channelName = `群${channelId}`
|
||||
}
|
||||
|
||||
channel.avatar = `https://api.multiavatar.com/${channel.channelId}.png`
|
||||
return channel
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### 频道成员
|
||||
#### 频道成员分页数据源
|
||||
```typescript
|
||||
// 定义提供者
|
||||
WKIM.shared.config.provider.channelMemberWithPageCallback = async (channel: WKChannel,
|
||||
option: SyncChannelMemberOptions): Promise<WKChannelMember[]> => {
|
||||
// todo 请求接口后返回给sdk
|
||||
let list: WKChannelMember[] = []
|
||||
return list
|
||||
}
|
||||
```
|
||||
|
||||
### 消息
|
||||
#### 频道消息数据源
|
||||
|
||||
```typescript
|
||||
// 定义提供者
|
||||
let syncMessageCallback = async (channel: WKChannel, options: SyncOptions): Promise<WKSyncChannelMsg> => {
|
||||
/*
|
||||
* 同步某个频道的消息
|
||||
*
|
||||
* @param channel.channelId 频道ID
|
||||
* @param channel.channelType 频道类型
|
||||
* @param options.startMessageSeq 开始消息列号(结果包含start_message_seq的消息)
|
||||
* @param options.endMessageSeq 结束消息列号(结果不包含end_message_seq的消息)
|
||||
* @param options.limit 消息数量限制
|
||||
* @param options.pullMode 拉取模式 0:向下拉取 1:向上拉取
|
||||
*/
|
||||
// todo 请求接口后需返回给sdk
|
||||
}
|
||||
|
||||
// 同步channel消息
|
||||
WKIM.shared.config.provider.syncMessageCallback = syncMessageCallback
|
||||
```
|
10
src/sdk/harmonyos/integration.md
Normal file
10
src/sdk/harmonyos/integration.md
Normal file
@ -0,0 +1,10 @@
|
||||
# 集成
|
||||
|
||||
### 下载安装
|
||||
```
|
||||
ohpm install @wukong/wkim
|
||||
```
|
||||
### 引入
|
||||
```
|
||||
import { WKIM } from '@wukong/wkim';
|
||||
```
|
44
src/sdk/harmonyos/intro.md
Normal file
44
src/sdk/harmonyos/intro.md
Normal file
@ -0,0 +1,44 @@
|
||||
# 说明
|
||||
|
||||
## 设计理念
|
||||
|
||||
为了让开发者更快更方便的使用 SDK,悟空 SDK 提供了一个唯一的入口来访问 SDK 中的所有功能。就像书籍的目录一样可以通过目录查找对应的内容。如连接 IM `WKIM.shared.connectionManager().connection();`
|
||||
|
||||
## 结构说明
|
||||
|
||||

|
||||
|
||||
SDK 常用功能介绍
|
||||
```typescript
|
||||
// 连接管理
|
||||
// 负责IM的连接、断开、退出登录、监听连接状态等
|
||||
WKIM.shared.connectionManager()
|
||||
|
||||
// 消息管理
|
||||
// 负责消息的增删改查、新消息监听、刷新消息监听、消息入库等
|
||||
WKIM.shared.messageManager()
|
||||
|
||||
// 会话管理
|
||||
// 负责会话的增删改查、会话列表监听、会话消息监听等
|
||||
WKIM.shared.conversationManager()
|
||||
|
||||
// 频道管理
|
||||
// 可获取Channel的信息,刷新Channel缓存,监听Channel更改[置顶、免打扰、禁言]等
|
||||
WKIM.shared.channelManager()
|
||||
|
||||
// 频道成员管理
|
||||
// 获取Channel成员列表、设置成员备注、保存修改成员数据、监听刷新成员和移除成员等
|
||||
WKIM.shared.channelMemberManager()
|
||||
|
||||
// 提醒项管理
|
||||
// 获取某个会话的提醒如:[有人@我] [入群申请] 等。还可自定义提醒项,如像 语音未读 等
|
||||
WKIM.shared.reminderManager()
|
||||
|
||||
// 命令管理
|
||||
// 负责监听服务器下发的命令消息
|
||||
WKIM.shared.cmdManager()
|
||||
```
|
||||
|
||||
### SDK 与 APP 交互原则
|
||||
|
||||
 sdk 与 app 交互流程就是 app 调用 sdk 提供的方法,sdk 处理完数据后通过事件将数据回调给 app。如发送消息流程:app 调用发送消息方法,sdk 将入库后的消息 push 给 app
|
185
src/sdk/harmonyos/message.md
Normal file
185
src/sdk/harmonyos/message.md
Normal file
@ -0,0 +1,185 @@
|
||||
# 消息管理
|
||||
|
||||
### 发送消息
|
||||
#### 说明
|
||||
发送消息的方法
|
||||
```typescript
|
||||
|
||||
/**
|
||||
* 发送消息
|
||||
* @param model 消息内容
|
||||
* @param channel 频道对象 个人频道,群频道
|
||||
*/
|
||||
WKIM.shared.messageManager().send(model: WKMessageContent, channel: WKChannel);
|
||||
```
|
||||
|
||||
#### 文本消息
|
||||
```typescript
|
||||
// 文本消息
|
||||
let textModel: WKTextContent = new WKTextContent('你好,悟空')
|
||||
|
||||
// 发送给用户A
|
||||
WKIM.shared.messageManager().send(textModel, new WKChannel('A', WKChannelType.personal));
|
||||
```
|
||||
|
||||
#### 图片消息
|
||||
```typescript
|
||||
// 图片消息
|
||||
let imageModel: WKImageContent = new WKImageContent(localPath)
|
||||
imageModel.width = 100
|
||||
imageModel.height = 100
|
||||
|
||||
// 发送给用户A
|
||||
WKIM.shared.messageManager().send(imageModel, new WKChannel('A', WKChannelType.personal));
|
||||
```
|
||||
|
||||
#### 自定义消息
|
||||
```typescript
|
||||
// 自定义消息
|
||||
let model: xxx = new xxx()
|
||||
|
||||
// 发送给群组g_100
|
||||
WKIM.shared.messageManager().send(model, new WKChannel('g_100', WKChannelType.group));
|
||||
```
|
||||
### 消息入库返回(并不是消息发送状态)
|
||||
在发送消息时,sdk 将消息保存在本地数据库后就会触发入库回调。此时消息并未进行发送,可在此监听中将消息展示在 UI 上
|
||||
|
||||
```typescript
|
||||
// 监听发送消息入库
|
||||
WKIM.shared.messageManager().addInsertedListener((msg) => {
|
||||
// 将消息展示在 UI 上
|
||||
})
|
||||
```
|
||||
|
||||
### 新消息
|
||||
监听新消息事件
|
||||
|
||||
```typescript
|
||||
// 新消息监听器
|
||||
newMsgsListener = (msgs: WKMsg[]) => {
|
||||
// 处理新消息
|
||||
}
|
||||
|
||||
// 监听新消息
|
||||
WKIM.shared.messageManager().addNewMsgListener(this.newMsgsListener)
|
||||
|
||||
// 移除新消息监听
|
||||
WKIM.shared.messageManager().removeNewMsgListener(this.newMsgsListener)
|
||||
```
|
||||
|
||||
### 刷新消息
|
||||
在 sdk 更新过消息时,如:消息发送状态,有人点赞消息,消息已读回执,消息撤回,消息被编辑等等,sdk 都将回调以下事件。UI 可通过消息对象WKMsg的clientMsgNO来判断具体是哪条消息发生了更改。
|
||||
|
||||
```typescript
|
||||
// 刷新消息监听器
|
||||
refreshMsgListener = (msg: WKMsg) => {
|
||||
// 处理刷新消息
|
||||
}
|
||||
|
||||
// 监听刷新消息
|
||||
WKIM.shared.messageManager().addRefreshListener(this.refreshMsgListener)
|
||||
|
||||
// 移除刷新消息监听
|
||||
WKIM.shared.messageManager().removeRefreshListener(this.refreshMsgListener)
|
||||
```
|
||||
|
||||
### 查看某个频道的聊天信息
|
||||
```typescript
|
||||
let option = new ChannelMsgOptions(() => {
|
||||
// 同步中 按需显示loading
|
||||
}, (list) => {
|
||||
// 消息数据
|
||||
})
|
||||
option.oldestOrderSeq = 0 // 最后一次消息大orderSeq 第一次进入聊天传入0
|
||||
option.contain = false // 是否包含 oldestOrderSeq 这条消息
|
||||
option.pullMode = 1 // 拉取模式 拉取模式 0:向下拉取 1:向上拉取
|
||||
option.limit = 20 // 一次拉取消息数量
|
||||
option.aroundMsgOrderSeq = 0 // 查询此消息附近消息 如 aroundMsgOrderSeq=20 返回数据则是 [16,17,19,20,21,22,23,24,25]
|
||||
// 查看某个频道的聊天信息
|
||||
WKIM.shared.messageManager().getOrSyncHistoryMessages(channel, option)
|
||||
```
|
||||
|
||||
|
||||
- <font color='#999' size=2>获取历史消息并不是同步方法,因为有可能存在非连续性时会往服务器同步数据</font>
|
||||
|
||||
### 离线消息
|
||||
`需要实现同步频道消息数据源` [频道消息数据源](/sdk/harmonyos/datasource.html#频道消息数据源)
|
||||
|
||||
因为WuKongIM 是支持消息永久存储,所以会产生海量的离线消息。对此我们采用了按需拉取的机制,如 10 个会话一个会话 10 万条消息,WuKongIM 不会把这个 10\*10 万=100 万条消息都拉取到本地。 而是采用拉取这 10 个会话的信息和对应的最新 20 条消息,也就是实际只拉取了 200 条消息 相对 100 万条消息来说大大提高了离线拉取速度。用户点进对应的会话才会去按需拉取这个会话的消息。 这些机制 SDK 内部都已做好了封装,使用者其实不需要关心。使用者只需要关心最近会话的变化和监听获取数据的回调即可。
|
||||
|
||||
|
||||
### 数据结构说明
|
||||
#### 消息结构
|
||||
```typescript
|
||||
export class WKMsg {
|
||||
// 服务端唯一消息ID
|
||||
messageId = "";
|
||||
// 服务端消息序号
|
||||
messageSeq = 0;
|
||||
// 客户端消息序号
|
||||
clientSeq = 0;
|
||||
// 消息时间戳
|
||||
timestamp = 0;
|
||||
// 过期时间
|
||||
expireTime = 0;
|
||||
// 过期时间戳
|
||||
expireTimestamp = 0;
|
||||
// 客户端唯一编号
|
||||
clientMsgNo = "";
|
||||
// 发送者uid
|
||||
fromUID = "";
|
||||
// 所属频道ID
|
||||
channelId = "";
|
||||
// 所属频道类型
|
||||
channelType = WKChannelType.personal;
|
||||
// 消息类型
|
||||
contentType = 0;
|
||||
// 消息内容字符串
|
||||
content = "";
|
||||
// 消息状态 1.发送成功 0.发送中
|
||||
status = 0;
|
||||
voiceStatus = 0;
|
||||
// 是否删除 1.是
|
||||
isDeleted = 0;
|
||||
// 搜索关键字
|
||||
searchableWord = "";
|
||||
// 消息发送者资料
|
||||
private from?: WKChannel
|
||||
// 消息所属频道资料
|
||||
private channelInfo?: WKChannel
|
||||
// 消息发送者在频道内资料 群消息才有值
|
||||
private memberOfFrom?: WKChannelMember
|
||||
// 排序号
|
||||
orderSeq = 0;
|
||||
// 是否已读
|
||||
viewed = 0;
|
||||
// 已读时间
|
||||
viewedAt = 0;
|
||||
// 话题ID
|
||||
topicId = "";
|
||||
// 本地扩展
|
||||
localExtraMap?: Record<string, object>
|
||||
// 远程扩展
|
||||
wkMsgExtra?: WKMsgExtra
|
||||
// 消息回应点赞数据
|
||||
reactionList?: WKMsgReaction[]
|
||||
// 消息正文
|
||||
messageContent?: WKMessageContent
|
||||
}
|
||||
```
|
||||
|
||||
#### 消息正文结构
|
||||
```typescript
|
||||
export class WKMessageContent {
|
||||
// 消息类型
|
||||
contentType: number = 0
|
||||
// 消息内容
|
||||
content: string = ""
|
||||
// 渲染消息内容 如@某人时需要渲染@xxx这段文字
|
||||
entities?: ArrayList<WKMsgEntity>
|
||||
// 消息回复
|
||||
reply?: WKReply
|
||||
// 提醒信息
|
||||
mentionInfo?: WKMentionInfo
|
||||
}
|
||||
```
|
62
src/sdk/harmonyos/reminder.md
Normal file
62
src/sdk/harmonyos/reminder.md
Normal file
@ -0,0 +1,62 @@
|
||||
# 提醒项管理
|
||||
会话提醒目前只支持服务器下发指令。客户端只需监听同步会话提醒和监听刷新会话消息即可
|
||||
|
||||
### 获取提醒项
|
||||
```typescript
|
||||
// 获取指定频道的提醒项
|
||||
// channelId: 频道ID
|
||||
// channelType: 频道类型
|
||||
// done: 1.已经完成的提醒项 0.未完成的提醒项
|
||||
WKIM.shared.reminderManager().get(channelId,channelType,done)
|
||||
```
|
||||
### 保存提醒项
|
||||
```typescript
|
||||
// 保存提醒项
|
||||
WKIM.shared.reminderManager().save(list: WKReminder[])
|
||||
```
|
||||
|
||||
### 事件
|
||||
#### 新增/更新事件
|
||||
```typescript
|
||||
refreshReminders = (reminders: WKReminder[]): void => {
|
||||
// 新增提醒项 或 更新提醒项
|
||||
}
|
||||
|
||||
// 监听提醒项
|
||||
WKIM.shared.reminderManager().addRefreshListener(this.refreshReminders)
|
||||
|
||||
// 移除监听
|
||||
WKIM.shared.reminderManager().removeRefreshListener(this.refreshReminders)
|
||||
|
||||
```
|
||||
|
||||
### 数据结构说明
|
||||
```typescript
|
||||
|
||||
export class WKReminder {
|
||||
// 提醒项ID
|
||||
reminderId = 0
|
||||
// 消息ID
|
||||
messageId = ''
|
||||
// 所属频道ID
|
||||
channelId: string = ''
|
||||
// 所属频道类型
|
||||
channelType: number = WKChannelType.personal
|
||||
// 消息序号
|
||||
messageSeq = 0
|
||||
// 提醒项类型 1.[@某人] 2.[入群申请] ...
|
||||
type = 0
|
||||
// 显示内容
|
||||
text = ''
|
||||
// 提醒项内容
|
||||
data?: Record<string, Object>
|
||||
// 版本号 增量同步需要
|
||||
version = 0
|
||||
// 是否完成 1.是
|
||||
done = 0
|
||||
// 是否需要上传到服务器
|
||||
needUpload = 0
|
||||
// 发布者
|
||||
publisher = ''
|
||||
}
|
||||
```
|
Loading…
x
Reference in New Issue
Block a user