跳到主要内容

自定义消息

自定义消息体编写规范

支持自定义普通消息,不支持自定义媒体消息

自定义消息规范

  1. 继承自 MessageContent 并实现 MessageTag 注解
  2. 按需增加自定义消息的属性
  3. 必须声明无参的构造方法,因为注册自定义消息时候,只能用无参构造方法
  4. 实现基类 encode 方法,将自定义消息转为 JSON 字符串
    • 将基类的数据保存到 map 中
    • 将本类的独有属性放到 map 中
      • 需要将数据类型声明为 Object
    • 将 map 转为 字符串
  5. 实现基类 decode 方法,将 JSON 字符串转为自定义消息
    • 将字符串转为 map
    • 将基类的数据解析出来
    • 将本类的独有属性解析
  6. 实现基类 getClassName 方法,将自定义消息类名返回
    • 直接写字符串可能会出现拼写错误的情况,所以此处建议直接使用 类名.name
  7. 按需实现基类 getSearchableWord 方法。从 1.1.0 版本开始支持。

MessageTag 规范

MessageTag 有两个参数

  1. 第一个参数,string 类型,用来唯一标识该自定义消息,RC: 为 SDK 内置的,app 禁用 RC: 开头
  2. 第二个参数,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 }

自定义消息体注册

  1. 自定义消息注册需要在 init 之后,connect 之前
  2. 如果在 init 之前或者 connect 之后注册,那么此类消息可能无法被正常收发
  3. 支持批量注册自定义消息
  4. 自定义消息需要满足如下三点
    • 继承 MessageContent
    • 实现 MessageTag 注解
    • 实现无参构造方法
let clazzList: List<MessageContentConstructor> = new List();
clazzList.add(CustomTextMessage);
clazzList.add(CustomOrderMessage);
IMEngine.getInstance().registerMessageType(clazzList);

自定义消息体使用

  1. 创建自定义消息体
  2. 创建 Message 对象
  3. 把消息发送出去
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));
})
}