首页 > 技术文章 > 一把双刃剑 -- 融云即时通讯sdk中的自定义消息使用心得&指南 (上)

imrtc 2021-04-06 18:45 原文

一把双刃剑 -- 融云即时通讯sdk中的自定义消息使用心得&指南 (上)

背景:

最近公司新上的app要加上即时通讯的功能, 自己快速实现一个当然是不可能的了(项目deadline也顶不住哇).就从各家成熟的SDK厂商选来选去的, 各有各的好也各有各的不足.最后点兵点将,选了融云家的SDK(老板说了算hhhh).

他家的官网和文档地址:
官网:https://www.rongcloud.cn/
文档:https://docs.rongcloud.cn/v4

这个任务当然还是落在我的头上. 我是使用的他们家的带UI的sdk,(他们家有带UI和不带UI的两种sdk, 不带UI的sdk就是只有即时通讯能力, 所有的UI都需要开发者自定实现, 带UI的sdk封装了一些基本的界面,例如会话列表, 和别人聊天的会话界面).

需求:

融云的体系中默认的消息类型只有9种.

功能 描述
文字消息 用来发送文字类消息,其中可以包括表情、超链接(会自动识别),客户端收到消息后计入未读消息数、进行存储。
语音消息 发送高质量的短语音消息,录制的语音文件存储到融云服务端,语音文件格式为 AAC,时长上限为 60 秒,客户端收到消息后计入未读消息数、进行存储。
图片消息 用来发送图片类消息,客户端收到消息后计入未读消息数、进行存储。图片缩略图格式为 JPG,大小建议不超过 100k。
GIF 图片消息 用来发送 GIF 动态图片消息,客户端收到消息后计入未读消息数、进行存储。
图文消息 用来发送图文消息,包含一个标题,一段文字内容和一张图片,客户端收到消息后计入未读消息数、进行存储。
文件消息 用来发送文件类消息,客户端收到消息后计入未读消息数、进行存储。
位置消息 用来发送地理位置消息,客户端收到消息后计入未读消息数、进行存储。
小视频消息 用来发送小视频消息,支持录制发送及选择本地视频文件发送两种方式,录制时长不超过 10 秒,本地选择视频文件方式时长不超过 2 分钟,小视频消息小视频文件格式为 .mp4,客户端收到消息后计入未读消息数、进行存储。
合并转发消息 IMKit SDK 中支持将多条消息合并为一条消息进行发送,合并后的消息以 HTML 文件的方式存储到融云服务端,客户端收到消息后计入未读消息数、进行存储。

这9种消息其实已经满足大部分的即时聊天场景了, 无论是打字聊天最普通的文本消息, 还是长按录制发送的语音消息, 以及图片消息, 分享位置的消息. 基本上微信有的场景, 都覆盖到了.

但是因为各家的产品各不相同, 有人需要一个比微信功能更简洁的聊天工具, 有人则需要一个像QQ那般功能强大的聊天工具. 总是有千奇百怪不同的需求的. 像我们的app就是这样, 总有场景是这里无法满足的. 好比QQ是可以把图片和文本消息放入同一个消息气泡中的(类似于富文本消息), 那么这样的情况下, 默认的几类消息就不够用了.

不过融云还是把这块做的很到位的, 暴露了类和接口让用户去对消息做自定义, 基本上可以做到, 想把消息定义成什么样就定义成什么样子.

心得(上)

这里就举一些我在开发我们公司app时, 用到的自定义消息, 以及使用心得和指南.

只发给当前在线用户的限时奖励通知

只给当前在线用户发送消息, 我们有一种游戏奖励是只发放给特殊时段在线的用户的, 只有当前在线的用户才能接收到这种消息来领取奖励, 其他在该时段未在线的用户, 不能接收到, 且再次登录后也不能接收到保留的离线消息.
这个需求就是做了一个自定义消息来实现的.
把自定义消息类的 MessageTag 中 flag 值设置为 MessageTag.STATUS。此消息类型即为状态消息,状态消息不存储不计数,并且当接收方不在线时,此消息会直接丢弃,用户再上线也不会收到该消息。

有需要的同学可以看他们家关于自定义消息的文档:https://docs.rongcloud.cn/im/imkit/android/conversation/custom_message/

发送自定义消息后撤回消息,撤回消息会失败

这里积累了一个经验, 也算是帮大家踩踩他们家的坑了, 那就是:
使用以下废弃方法发送自定义时会出现此错误:

在发送自定义消息后,撤回消息时没有反应,退出会话界面再次进入后可以正常撤回消息。 在 log 中显示 recallMessage errorCode = 25101。

public Message sendMessage(ConversationType type, String targetId, MessageContent content, String pushContent, String pushData, final SendMessageCallback callback) {

必须要换成这个方法发送才行:

public void sendMessage(Message message, String pushContent, String pushData, final ISendMessageCallback callback) 

这个问题也是蛮坑的, 害. 找他们家技术支持费了点劲才排查出来, 希望大家遇到这种问题能快快找到我这篇经验哈.

推荐阅读