自定义消息
自定义消息体编写规范
支持自定义普通消息,不支持自定义媒体消息
自定义消息规范
- 继承自 MessageContent 并实现 MessageTag 注解
- 按需增加自定义消息的属性
- 必须声明无参的构造方法,因为注册自定义消息时候,只能用无参构造方法
- 实现基类 encode 方法,将自定义消息转为 JSON 字符串
- 将基类的数据保存到 map 中
- 将本类的独有属性放到 map 中
- 需要将数据类型声明为 Object
- 将 map 转为 字符串
- 实现基类 decode 方法,将 JSON 字符串转为自定义消息
- 将字符串转为 map
- 将基类的数据解析出来
- 将本类的独有属性解析
- 实现基类 getClassName 方法,将自定义消息类名返回
- 直接写字符串可能会出现拼写错误的情况,所以此处建议直接使用 类名.name
- 按需实现基类 getSearchableWord 方法。从 1.1.0 版本开始支持。
MessageTag 规范
MessageTag 有两个参数
- 第一个参数,string 类型,用来唯一标识该自定义消息,RC: 为 SDK 内置的,app 禁用 RC: 开头
- 第二个参数,MessageFlag 类型,用来表示自定义消息的持久化类型
MessageFlag 类型 | 说明 | 建议 |
---|---|---|
None | 空值,不表示任何意义。此类消息不会保存到数据库,也不会记录未读数 | 一般用作命令消息,通知端上做一个动作 |
Save | 消息需要被存储到消息历史记录。此类消息会保存到数据库,但是不记录未读数 | 常用于小灰条类型的消息,需要 UI 展示,但不需要增加未读数 |
Count | 消息需要被记入未读消息数。此类消息会保存到数据库,并且增加未读数 | 如文本,图片等消息均为此类 |
Status | 状态消息, 不存储不计数。此类消息不会保存到数据库,也不会记录未读数。对方在线能收到该消息;对方不在线,服务器会直接丢弃该消息,对方如果之后再上线也不会再收到此消息 | 一般用于发送输入状态之类的消息 |
自定义消息完整示例
import { JsonUtil, MessageContent, MessageFlag, MessageTag } from '@rongcloud/imlib';
import List from '@ohos.util.List';
const CustomOrderMessageObjectName = "App:OrderMsg";
const CustomOrderMessageFlag = MessageFlag.Count;
/**
* 1. 继承自 MessageContent 并实现 MessageTag 注解
*/
@MessageTag(CustomOrderMessageObjectName,CustomOrderMessageFlag)
class CustomOrderMessage extends MessageContent {
/**
* 2. 按需增加属性
*/
id: string = ""; // 订单 ID
name: string = ""; // 订单名称
price: number = 0; // 订单价格
/**
* 3. 必须声明无参的构造方法,因为注册自定义消息时候,只能用无参构造方法
*
* > 详细见 IMEngine registerMessageType()
*/
constructor() {
super();
}
/**
* 4. 将消息对象转为 JSON 字符串
*/
encode(): string {
// 4.1 将基类的数据保存到 map 中
let map = super.encodeBaseData();
// 4.2 将本类的独有属性放到 map 中
// 说明:ts 的 map 必须指定 kv 的类型,所以存多种类型数据,需要转为 Object
if (this.id) {
map.set("id", this.id as Object);
}
if (this.name) {
map.set("name", this.name as Object);
}
map.set("price", this.price as Object);
// 4.3 将 map 转为 字符串
return JsonUtil.stringifyFromMap(map);
}
/**
* 5. 将字符串转为消息对象
*/
decode(contentString: string): void {
// 5.1 将字符串转为 map
let map = JsonUtil.parseToMap(contentString);
// 5.2 将基类的数据解析出来
super.decodeBaseData(map);
// 5.3 将本类的独有属性解析
// 说明:需要将 Object 转为对应的数据类型
if (map.get("id")) {
this.id = map.get("id") as string;
}
if (map.get("name")) {
this.name = map.get("name") as string;
}
if (map.get("price")) {
this.price = map.get("price") as number;
}
}
/**
* 6. 将当前类名返回:该方法的作用是防止代码混淆或者压缩后无法获取正常的类名
* 直接写字符串可能会出现拼写错误的情况,所以此处建议直接使用 类名.name
*/
getClassName(): string {
return CustomOrderMessage.name;
}
/**
* 7. 返回搜索字段
* ```
* 1) 不实现该方法,该类消息无法被搜索
* 2) 实现该方法,返回 null 或者 List 长度为 0,无法被搜索
* 3) 实现该方法, List 里面的 空字符串 和 null 会被忽略
* 4) List 中必须包含有效的字符串才能被搜索到
* ```
* @returns 返回搜索字段
*/
getSearchableWord(): List<string> | null {
if (!this.name) {
return null;
}
let list = new List<string>();
list.add(this.name);
return list;
}
}
export { CustomOrderMessage, CustomOrderMessageObjectName }
自定义消息体注册
- 自定义消息注册需要在 init 之后,connect 之前
- 如果在 init 之前或者 connect 之后注册,那么此类消息可能无法被正常收发
- 支持批量注册自定义消息
- 自定义消息需要满足如下三点
- 继承 MessageContent
- 实现 MessageTag 注解
- 实现无参构造方法
let clazzList: List<MessageContentConstructor> = new List();
clazzList.add(CustomTextMessage);
clazzList.add(CustomOrderMessage);
IMEngine.getInstance().registerMessageType(clazzList);
自定义消息体使用
- 创建自定义消息体
- 创建 Message 对象
- 把消息发送出去
private testSendCustomMessage1(): void {
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = Define.targetId;
let cusMsg = new CustomOrderMessage();
cusMsg.id = "apple";
cusMsg.name = "苹果"
cusMsg.price = 2.3;
let option: ISendMsgOption = {};
let msg = new Message(conId, cusMsg);
hilog.info(0x0000, 'IM-App', 'SendCustomMessage start');
IMEngine.getInstance().sendMessage(msg, option, (message: Message) => {
hilog.info(0x0000, 'IM-App', 'SendCustomMessage onSave msg:%{public}s', JSON.stringify(message));
}).then(result => {
hilog.info(0x0000, 'IM-App', 'SendCustomMessage onResult :%{public}s', JSON.stringify(result));
})
}