本文档提供消息相关的类型和接口使用说明。
API 接口详细文档参看 Android API 参考、iOS API 参考、Web API 参考、微信小程序 API 参考。
BIMMessage 为 IMSDK 的消息内容承载类,在使用 IMSDK 的过程中会频繁的使用该类。
IMSDK 支持如下消息:
| 消息分类 | 消息类型 | 说明 |
|---|---|---|
| 文本消息 | BIM_MESSAGE_TYPE_TEXT | 普通文本消息 |
| 图片消息 | BIM_MESSAGE_TYPE_IMAGE | 图片消息,含原始图,缩略图 |
| 视频消息 | BIM_MESSAGE_TYPE_VIDEO | 视频文件以及视频封面图,最大不超过 50M |
| 语音消息 | BIM_MESSAGE_TYPE_AUDIO | 语音文件,最大不超过 50M |
| 文件消息 | BIM_MESSAGE_TYPE_FILE | 文件消息,最大不超过 50M |
| 自定义消息 | BIM_MESSAGE_TYPE_CUSTOM | 开发者自定义字符串发送,IMSDK 透传 |
使用 BIMClient 中的 createTextMessage 方法创建文本消息。
BIMMessage textMessage = BIMClient.getInstance().createTextMessage("消息内容");java
BIMMessage *textMessage = [[BIMClient sharedInstance] createTextMessage:@"消息内容"];objectivec使用 BIMClient 中的 createImageMessage 方法创建图片消息,其中 path 为当前发送图片文件的本地路径。
BIMMessage imageMessage = BIMClient.getInstance().createImageMessage(path);java
BIMMessage *imageMessage = [[BIMClient sharedInstance] createImageMessage:path];objectivec使用 BIMClient 中的 createAudioMessage 方法创建语音消息,其中 path 为当前语音文件的本地路径。
BIMMessage audioMessage = BIMClient.getInstance().createAudioMessage(path);java
BIMMessage *audioMessage = [[BIMClient sharedInstance] createAudioMessage:path duration:duration];objectivec使用 BIMClient 中的 createVideoMessage 方法创建视频消息,其中 path 为当前视频文件的本地路径。
BIMMessage videoMessage = BIMClient.getInstance().createVideoMessage(path);java
BIMMessage *videoMessage = [[BIMClient sharedInstance] createVideoMessage:path];objectivec使用 BIMClient 中的 createFileMessage 方法创建文件消息,其中 path 为当前文件的本地路径,uri 为当前文件本地 uri,path 和 uri 可以二选一使用(iOS 只有 path),推荐优先使用 path。
/**
* 创建文件消息
* @param uri 文件uri
* @param path 文件路径
* @param fileName 文件名称
* @param length 文件大小
* @return
*/
BIMMessage fileMessage = BIMClient.getInstance().createFileMessage(uri, path, fileName, length);java
BIMMessage *fileMessage = [[BIMClient sharedInstance] createFileMessage:path fileName:fileName];objectivec使用 BIMClient 中的 createCustomMessage 方法创建文件消息,其中 data 参数为自定义消息内容,通常为 json 格式数据。
/**
* 创建自定义消息
* @param data 自定义消息内容
* @return
*/
BIMMessage customMessage = BIMClient.getInstance().createCustomMessage(data);java
BIMMessage *customMessage = [[BIMClient sharedInstance] createCustomMessage:data];objectivec发送消息的方法在 BIMClient 中,使用 sendMessage 接口可实现,示例代码如下。
/**
* @param message
* @param conversationId 会话id
* @param callback 回调
*/
BIMClient.getInstance().sendMessage(msg, conversationId, new BIMSendCallback() {
@Override
public void onAdd(BIMMessage message) {
//媒体消息回调,方便媒体消息上屏
}
@Override
public void onProgress(BIMMessage message, int progress) {
//媒体消息回调,上传进度
}
@Override
public void onSaved(BIMMessage bimMessage) {
//媒体消息回调,消息已经入库
}
@Override
public void onSuccess(BIMMessage bimMessage) {
//发送成功
}
@Override
public void onAsync(BIMMessage bimMessage, boolean isUpdate) {
//发送风控回调
}
@Override
public void onError(BIMMessage bimMessage, int code, String desc) {
//发送失败
}
})java
//发送消息
[[BIMClient sharedInstance] sendMessage:sendMessage conversationId:self.conversation.conversationID saved:nil completion:^(BIMMessage * _Nonnull message, BIMError * _Nullable error) {
}];objectivec使用 BIMClient 中的 addMessageListener 设置消息监听,可通过 bimMessage.getMsgType() 获取消息类型属性。
BIMClient.getInstance().addMessageListener(new BIMMessageListener() {
@Override
public void onReceiveMessage(BIMMessage bimMessage) {
//收到消息回调
}
@Override
public void onSendMessage(BIMMessage bimMessage) {
//本地发出消息回调
}
@Override
public void onDeleteMessage(BIMMessage bimMessage) {
//删除消息回调
}
@Override
public void onRecallMessage(BIMMessage bimMessage) {
//撤回消息回调
}
@Override
public void onUpdateMessage(BIMMessage bimMessage) {
//消息更新回调
}
@Override
public void onReceiveMessagesReadReceipt(List<BIMMessageReadReceipt> receiptList) {
//收到消息已读回执回调
}
});java
[[BIMClient sharedInstance] addMessageListener:<#(nonnull id<BIMMessageListener>)#>];
/// 收到新消息
- (void)onReceiveMessage:(BIMMessage *)message {
}
/// 收到消息被删除
- (void)onDeleteMessage:(NSString *)msgID {
}
/// 收到消息撤回
- (void)onRecallMessage:(BIMMessage *)message {
}
/// 消息被修改(内容+扩展)
- (void)onUpdateMessage:(BIMMessage *)message {
}
/// 发送消息入库完成
- (void)onSendMessage:(BIMMessage *)message {
}
/// 收到消息已读回执
- (void)onReceiveMessagesReadReceipt:(NSArray<BIMMessageReadReceipt *> *)receiptList;
{
}objectivec版本 v1.11.0 以上单聊支持消息和会话已读回执。消息已读回执是指消息发送后,接收方查看消息后可以发送自己已读给发送端。会话已读回执是指接收方可以标记整个会话消息已读。
是否(消息接收方)已发送或(消息发送方)已收到消息已读回执,可通过 BIMMessage 的 isReadAck 方法获取。
public boolean isReadAck();java
@property (nonatomic, assign, readonly) BOOL isReadAck;objectivec从其他界面进入会话页面时,完成消息拉取后可主动拉取消息已读回执信息。
// 进入会话拉取消息
BIMClient.getInstance().getNewerMessageList(conversationId, option, new BIMResultCallback<BIMMessageListResult>() {
@Override
public void onSuccess(BIMMessageListResult bimMessageListResult) {
// ...
// 历史消息
List<BIMMessage> messageList = bimMessageListResult.getMessageList();
// 过滤已读消息
List<BIMMessage> needQueryMsgList = new ArrayList<>();
for (BIMMessage bimMessage: messageList) {
// 已读消息不再查询
if (!bimMessage.isReadAck()) {
needQueryMsgList.add(bimMessage);
}
}
// 获取消息已读回执
BIMClient.getInstance().getMessagesReadReceipt(needQueryMsgList, new BIMResultCallback<List<BIMMessageReadReceipt>>() {
@Override
public void onSuccess(List<BIMMessageReadReceipt> messageReadReceipts) {
// 请求成功,刷新UI
}
@Override
public void onFailed(BIMErrorCode code) {
// 请求失败
}
});
}
@Override
public void onFailed(BIMErrorCode code) {
// 获取历史消息失败
}
});java
@weakify(self);
[[BIMClient sharedInstance] getHistoryMessageList:self.conversation.conversationID option:option completion:^(NSArray<BIMMessage *> * _Nullable messages, BOOL hasMore, BIMMessage * _Nullable earliestMessage, BIMError * _Nullable error) {
@strongify(self);
// 不是单聊会话不用拉已读回执
if (self.conversation.conversationType != BIM_CONVERSATION_TYPE_ONE_CHAT) {
return;
}
NSMutableArray<BIMMessage *> *needGetReceiptMessages = [NSMutableArray array];
[messages enumerateObjectsUsingBlock:^(BIMMessage * _Nonnull message, NSUInteger idx, BOOL * _Nonnull stop) {
// 已读的或者不是自己发的消息,也不用拉已读回执
if (message.isReadAck || message.senderUID != [[BIMClient sharedInstance] getCurrentUserID].longLongValue) {
return;
}
[needGetReceiptMessages addObject:message];
}];
if (BTD_isEmptyArray(needGetReceiptMessages)) {
return;
}
[[BIMClient sharedInstance] getMessagesReadReceipt:[needGetReceiptMessages copy] completion:^(NSArray<BIMMessageReadReceipt *> * _Nullable receiptList, BIMError * _Nullable error) {}];
}];objectivec在会话页面,接收到消息时,根据消息类型发送消息已读回执。
// 假设bimMessage已被用户查看
public void sendMessageAck(BIMMessage bimMessage) {
if (!bimMessage.isSelf() && !bimMessage.isReadAck()) {
// 语音和视频消息需要点开才发送已读回执,可以根据需求调整。
if (bimMessage.getMsgType() == BIMMessageType.BIM_MESSAGE_TYPE_AUDIO
|| bimMessage.getMsgType() == BIMMessageType.BIM_MESSAGE_TYPE_VIDEO) {
return;
}
List<BIMMessage> messageList = new ArrayList<>();
messageList.add(bimMessage);
BIMClient.getInstance().sendMessageReadReceipts(bimMessage, new BIMSimpleCallback() {
@Override
public void onSuccess() {
// 发送成功
}
@Override
public void onFailed(BIMErrorCode code) {
// 发送失败
}
});
}
}java
if (message.senderUID == [BIMClient sharedInstance].getCurrentUserID.longLongValue) {
return;
}
if (!message.serverMessageID || message.isReadAck || self.conversation.conversationType != BIM_CONVERSATION_TYPE_ONE_CHAT) {
return;
}
// 语音和视频消息需要点开才发送已读回执,可以根据需求调整。
if (message.msgType == BIM_MESSAGE_TYPE_VIDEO || message.msgType == BIM_MESSAGE_TYPE_AUDIO) {
return;
}
[[BIMClient sharedInstance] sendMessageReadReceipts:@[message] completion:^(BIMError * _Nullable error) {}];objectivec使用 BIMClient 中的 addMessageListener 设置消息已读回执监听。
BIMClient.getInstance().addMessageListener(new BIMMessageListener() {
// ... 其他回调
@Override
public void onReceiveMessagesReadReceipt(List<BIMMessageReadReceipt> receiptList) {
// 收到消息已读回执回调
}
});java
[[BIMClient sharedInstance] addMessageListener:listener];
/// 收到消息已读回执
- (void)onReceiveMessagesReadReceipt:(NSArray<BIMMessageReadReceipt *> *)receiptList;
{
[receiptList enumerateObjectsUsingBlock:^(BIMMessageReadReceipt * _Nonnull receipt, NSUInteger idx, BOOL * _Nonnull stop) {
// 收到消息已读回执回调
}];
}objectivec进入会话页面,可通过发送会话已读回执标记会话所有消息已读。
// 会话已读回执仅支持单聊
if (bimConversation.getConversationType() == BIMConversationType.BIM_CONVERSATION_TYPE_ONE_CHAT) {
BIMClient.getInstance().markConversationMessagesRead(bimConversation.getConversationID(), new BIMSimpleCallback() {
@Override
public void onSuccess() {
// 发送成功
}
@Override
public void onFailed(BIMErrorCode code) {
// 发送失败
}
});
}java
// 会话已读回执仅支持单聊
if (self.conversation.conversationType == BIM_CONVERSATION_TYPE_ONE_CHAT) {
[[BIMClient sharedInstance] markConversationMessagesRead:self.conversation.conversationID completion:^(BIMError * _Nullable error) {}];
}objectivec使用 BIMClient 中的 addConversationListener 设置消息已读回执监听。
BIMClient.getInstance().addConversationListener(new BIMConversationListListener() {
// ... 其他回调
@Override
public void onConversationRead(String conversationId, long fromUid) {
//收到会话已读回执回调,刷新UI
}
});java
[[BIMClient sharedInstance] addConversationListener:listener];
//收到会话已读回执
- (void)onConversationRead:(NSString *)conversationId fromUid:(long long)uid
{
dispatch_async(dispatch_get_main_queue(), ^{
//收到会话已读回执回调,刷新UI
});
}objectivec当你需要通过调用服务端接口 SendMessage 或 UserBroadcast 接口向客户端发送消息时,你需要传入 MsgType 和 Content 来构建一条信息。
你需要将消息内容按照以下 Json 格式进行构建,并将 Json 内容转换成 String 格式后传入 SendMessage.Content 中。
MsgType = 10001
{
"text":"文字消息" // 文本
}
JsonMsgType = 10003
{
"__files":{//媒体列表
"media":{//媒体信息
"displayType":"media",//固定值为 media
"mime":"image/jpeg",//mimetype 格式
"length":5313,//文件大小,单位为 b
"fileName":"Your_file.jpeg",//文件名称
"type":"jpeg",//文件类型
"ext":{
"s:file_ext_key_source_app_id":"000000", //AppId
"s:file_ext_key_file_name":"Your_file.jpeg",//文件名称
"s:file_ext_key_original_height":"200", //原图高
"s:file_ext_key_original_width":"100", //原图宽
"s:file_ext_key_thumb_height":"100", //缩略图高
"s:file_ext_key_thumb_width":"50", //缩略图宽
"s:file_ext_key_preview_width":"100",//中图宽
"s:file_ext_key_preview_height":"200",//中图宽
"s:file_ext_key_preview_url":"https://xxx.xxx",//中图url
"s:file_ext_key_thumb_url":"https://xxx.xxx.xxx"//缩略图url
},
"remoteURL":"https://xxx.xxx.xxxxx"//原图url
}
}
}
JsonMsgType = 10004
{
"__files":{//媒体列表
"media":{//媒体信息
"displayType":"media",//固定值为 media
"mime":"video/mp4",//mimetype 格式
"length":13494185,//文件大小,单位为 b
"fileName":"Your_file.mp4",//文件名称
"type":"mp4",//文件类型
"ext":{
"s:file_ext_key_source_app_id":"000000",//AppId
"s:file_ext_key_file_name":"Your_file.mp4",//文件名称
"s:file_ext_key_video_duration":"10",//视频时长,单位为 s。
"s:file_ext_key_video_height":"200",//视频高,单位为 px。
"s:file_ext_key_video_width":"100",//视频宽,单位为 px。
"s:file_ext_key_video_cover_url":"https://xxx.xxx"//封面url
},
//视频url
"remoteURL":"https://xxx.xxx"
}
}
}
JsonMsgType = 10005
{
"__files":{//媒体列表
"media":{//媒体信息
"displayType":"media",//固定值为 media
"mime":"string",//mimetype 格式
"length":9410,//文件大小,单位为 b
"fileName":"Your_file.v",//文件名称
"type":"v",//文件类型
"ext":{
"s:file_ext_key_source_app_id":"000000",//AppId
"s:file_ext_key_file_name":"Your_file.v"//文件名称
},
//文件 url
"remoteURL":"https://xxx.xxx"
}
}
}
JsonMsgType = 10006
{
"__files":{//媒体列表
"media":{//媒体信息
"displayType":"media",//固定值为 media
"mime":"audio/*",//mimetype 格式
"length":328364,//文件大小,单位为 b
"fileName":"Your_file.wav",//文件名称
"type":"wav",//文件类型
"ext":{
"s:file_ext_key_source_app_id":"000000",//AppId
"s:file_ext_key_file_name":"Your_file.wav",//文件名称
"s:file_ext_key_audio_duration":"3.608"//语音时长,单位为 s
},
//语音url
"remoteURL":"xxx.xxx"
}
}
}
JsonMsgType = 10012
IM 未对自定义消息 Content 字段进行约定,你可以自行构建渲染。