发送消息
本文主要描述了如何使用 IMLib SDK 向单聊会话、群聊会话、聊天室会话中发送消息。
- 如发送超级群消息,请参见超级群文档 收发消息。
- 默认情况下,融云允许未加入聊天室的用户在聊天室中发送消息。若您希望未加入聊天室的用户不能通过客户端 SDK 在该聊天室发送消息,可在融云控制台的免费基础功能页面,通过应用配置>IM 服务>免费基础功能>聊天室,开启 SDK 用户不在聊天室中不能发送消息功能。注意:服务端发送聊天室消息的接口不受此配置影响。
消息内容类型简介
IMLib SDK 定义的 Message 对象的 content
属性中可包含两大类消息内容:普通消息内容和媒体消息内容。普通消息内容父类是 MessageContent,媒体消息内容父类是 MediaMessageContent。发送媒体消息和普通消息本质的区别为是否有上传数据过程。
功能 | 消息内容的类型 | 父类 | 描述 |
---|---|---|---|
文本消息 | TextMessage | MessageContent | 文本消息的内容。 |
引用回复 | ReferenceMessage | MessageContent | 引用消息的内容,用于实现引用回复 功能。 |
图片消息 | ImageMessage | MediaMessageContent | 图片消息的内容,支持发送原图。 |
GIF 消息 | GIFMessage | MediaMessageContent | GIF 消息的内容。 |
文件消息 | FileMessage | MediaMessageContent | 文件消息的内容。 |
语音消息 | HQVoiceMessage | MediaMessageContent | 高清语音消息的内容。 |
提及他人(@ 消息) | 不适用 | 不适用 | @消息并非预定义的消息类型。详见如何发送 @ 消息。 |
以上为 IMLib SDK 内置的部分消息内容类型。您还可以创建自定义的消息内容类型,并使用 sendMessage
方法或sendMediaMessage
方法发送。详见自定义消息类型。
重要
- 发送普通消息使用
sendMessage
方法,发送媒体消息使用sendMediaMessage
方法。- 客户端 SDK 发送消息存在频率限制,每秒最多只能发送 5 条消息。
本文使用 IMLib SDK 核心类 RongCoreClient(也可以用 RongIMClient)的发送消息方法。
普通消息
普通消息指文本消息、引用消息等不涉及媒体文件上传的消息。普通消息的消息内容为 MessageContent
的子类的消息,例如文本消息内容(TextMessage),或自定义类型的普通消息内容。
构造普通消息
在发送前,需要先构造 Message 对象。conversationType 字段为会话类型。targetId
表示会话的目标 ID。以下示例中构造了一条包含文本消息内容(TextMessage)的消息对象。
String targetId = "Target ID";
ConversationType conversationType = Conversation.ConversationType.PRIVATE;
TextMessage messageContent = TextMessage.obtain("消息内容");
Message message = Message.obtain(targetId, conversationType, messageContent);
发送普通消息
如果 Message 对象包含普通消息内容,使用 IMLib SDK 核心类 RongCoreClient(也可以用 RongIMClient)的 sendMessage
方法发送消息。
String pushContent = null;
String pushData = null;
RongCoreClient.getInstance().sendMessage(message, pushContent, pushData, new IRongCoreCallback.ISendMessageCallback() {
@Override
public void onAttached(Message message) {
}
@Override
public void onSuccess(Message message) {
}
@Override
public void onError(Message message, IRongCoreEnum.CoreErrorCode coreErrorCode) {
}
});
sendMessage 方法中直接提供了用于控制推送通知内容(pushContent
)和推送附加信息(pushData
)的参数。另一种方式是使用消息推送属性配置 MessagePushConfig,其中包含了 pushContent
和 pushData
,并提供更多推送通知配置能力,例如标题、内容、图标、或其他第三方厂商个性化配置。详见远程推送通知。
关于是否需要配置输入参数或 Message
的 messagePushConfig
属性中 pushContent
,请参考以下内容:
- 如果消息类型为即时通讯服务预定义消息类型中的用户内容类消息格式,例如 TextMessage,
pushContent
可设置为null
。一旦消息触发离线推送通知时,远程推送通知默认使用服务端预置的推送通知内容。关于各类型消息的默认推送通知内容,详见用户内容类消息格式。 - 如果消息类型为即时通讯服务预定义消息类型中通知类、信令类("撤回命令消息" 除外),且需要支持远程推送通知,则必须填写
pushContent
,否则收件人不在线时无法收到远程推送通知。如无需触发远程推送,可不填该字段。 - 如果消息类型为自定义消息类型,请参考自定义消息如何支持远程推送。
- 请注意,聊天室会话不支持离线消息机制,因此也不支持离线消息转推送。
参数 | 类型 | 说明 |
---|---|---|
message | Message | 要发送的消息体。必填属性包括会话类型(conversationType ),会话 ID(targetId ),消息内容(content )。详见消息介绍 中对 Message 的结构说明。 |
pushContent | String | 修改或指定远程消息推送通知栏显示的内容。您也可以在 Message 的推送属性(MessagePushConfig )中配置,会覆盖此处配置,详见下文远程推送通知。 |
pushData | String | 远程推送附加信息。对端收到远程推送消息时,可通过以下方法获取该字段内容:
Message 的推送属性(MessagePushConfig )中配置,会覆盖此处配置,详见下文远程推送通知。 |
callback | ISendMessageCallback | 发送消息 的回调。 |
通过 RongCoreClient
的 sendMessage
方法的回调处理程序 ISendMessageCallback,融云服务器始终会通知您的消息是否已发送成功。当因任何问题导致发送失败时,可通过回调方法返回异常。
- 关于如何个性化配置接收方离线时收到的远程推送通知,详见下文远程推送通知。
- 自定义消息类型默认不支持离线消息转推送机制。如需支持,详见下文自定义消息如何支持远程推送。
媒体消息
媒体消息指图片、GIF、文件等需要处理媒体文件上传的消息。 媒体消息的消息内容类型为 MeidaMessageContent
的子类,例如高清语音消息内容(HQVoiceMessage),或您自定义类型的媒体消息内容。
构造媒体消息
在发送前,需要先构造 Message 对象。媒体消息 Message
对象的 content
字段必须传入 MediaMessageContent 的子类对象,表示媒体消息内容。例如图片消息内容(ImageMessage)、GIF 消息内容(GIFMessage),或继承自 MediaMessageContent 的自定义媒体消息内容。
图片消息内容(ImageMessage)支持设置为发送原图。
String targetId = "Target ID";
ConversationType conversationType = Conversation.ConversationType.ULTRA_GROUP;
Uri localUri = Uri.parse("file://图片的路径");//图片本地路径,接收方可以通过 getThumUri 获取自动生成的缩略图 Uri
boolean mIsFull = true; //是否发送原图
ImageMessage mediaMessageContent = ImageMessage.obtain(localUri, mIsFull);
Message message = Message.obtain(targetId, conversationType, mediaMessageContent);
在发送前,图片会被压缩质量,以及生成缩略图,在聊天界面中展示。GIF 无缩略图,也不会被压缩。
- 图片消息的缩略图:SDK 会以原图 30% 质量生成符合标准大小要求的大图后再上传和发送。压缩后最长边不超过 240 px。缩略图用于在聊天界面中展示。
- 图片:发送消息时如未选择发送原图,SDK 会以原图 85% 质量生成符合标准大 小要求的大图后再上传和发送。压缩后最长边不超过 1080 px。
一般情况下不建议修改 SDK 默认压缩配置。如需调整 SDK 压缩质量,详见知识库文档如何修改 SDK 默认的图片与视频压缩配置。
发送媒体消息
发送媒体消息需要使用 sendMediaMessage
方法。SDK 会为图片、小视频等生成缩略图,根据默认压缩配置进行压缩,再将图片、小视频等媒体文件上传到融云默认的文件服务器(文件存储时长),上传成功之后再发送消息。图片消息如已设置为发送原图,则不会进行压缩。
String pushContent = null;
String pushData = null;
RongCoreClient.getInstance().sendMediaMessage(message, pushContent, pushData, new IRongCoreCallback.ISendMediaMessageCallback() {
@Override
public void onProgress(Message message, int i) {
}
@Override
public void onCanceled(Message message) {
}
@Override
public void onAttached(Message message) {
}
@Override
public void onSuccess(Message message) {
}
@Override
public void onError(final Message message, final IRongCoreEnum.CoreErrorCode coreErrorCode) {
}
});
sendMediaMessage 方法中直接提供了用于控制推送通知内容(pushContent
)和推送附加信息(pushData
)的参数。另一种方式是使用消息推送属性配置 MessagePushConfig,其中包含了 pushContent
和 pushData
,并提供更多推送通知配置能力,例如标题、内容、图标、或其他第三方厂商个性化配置。详见远程推送通知。
关于是否需要配置输入参数或 Message
的 messagePushConfig
属性中 pushContent
,请参考以下内容:
- 如果消息类型为即时通讯服务预定义消息类型中的用户内容类消息格式,例如 HQVoiceMessage,
pushContent
可设置为null
。一旦消息触发离线推送通知时,远程推送通知默认使用服务端预置的推送通知内容。关于各类型消息的默认推送通知内容,详见用户内容类消息格式。 - 如果消息类型为即时通讯服务预定义消息类型中通知类、信令类("撤回命令消息" 除外),且需要支持远程推送通知,则必须填写
pushContent
,否则收件人不在线时无法收到远程推送通知。如无需触发远程推送,可不填该字段。 - 如果消息类型为自定义消息类型,请参考自定义消息如何支持远程推送。
- 请注意,聊天室会话不支持离线消息机制,因此也不支持离线消息转推送。
参数 | 类型 | 说明 |
---|---|---|
message | Message | 要发送的消息体。必填属性包括会话类型(conversationType ),会话 ID(targetId ),消息内容(content )。详见消息介绍 中对 Message 的结构说明。 |
pushContent | String | 修改或指定远程消息推送通知栏显示的内容。您也可以在 Message 的推送属性(MessagePushConfig )中配置,会覆盖此处配置,详见下文远程推送通知。 |
pushData | String | 远程推送附加信息。对端收到远程推送消息时,可通过以下方法获取该字段内容:
Message 的推送属性(MessagePushConfig )中配置,会覆盖此处配置,详见下文远程推送通知。 |
callback | ISendMediaMessageCallback | 发送媒体消息的回调 |
通过 RongCoreClient
的 sendMediaMessage
方法的回调处理程序 ISendMediaMessageCallback,融云服务器始终会通知媒体文件上传进度,以及您的消息是否已发送成功。当因任何问题导致发送失败时,可通过回调方法返回异常。
发送媒体消息的方法默认将媒体文件上传到融云的文件服务器,您可以在客户端应用程序 下载媒体消息文件。融云对上传媒体文件大小进行了限制,GIF 大小限制为 2 MB,文件上传限制为 100 MB。如果您需要提高 GIF 文件上限,可提交工单,文件上传的上限不可调。
- 关于如何个性化配置接收方离线时收到的远程推送通知,详见下文远程推送通知。
- 自定义消息类型默认不支持离线消息转推送机制。如需支持,详见下文自定义消息如何支持远程推送。
发送媒体消息并且上传到自己的服务器
您可以直接发送您服务器上托管的文件。将媒体文件的 URL(表示其位置)作为参数,在构建媒体消息内容时传入。在这种情况下,您的文件不会托管在融云服务器上。当您发送带有远程 URL 的文件消息时,文件大小没有限制,您可以直接使用 sendMessage
方法发送消息。
如果您希望 SDK 在您上传成功后发送消息,您可以使用 sendMediaMessage
方法,在回调接口 ISendMediaMessageCallbackWithUploader 的 onAttached
回调方法中自行实现媒体文件上传,并在上传成功后通知 SDK,提供回媒体文件的远端地址。SDK 会在收到上传成功的通知后发送消息。
String path = "file://图片的路径";
Uri localUri = Uri.parse(path);
ConversationType conversationType = ConversationType.PRIVATE;
String targetId = "目标 ID";
ImageMessage imageMessage = ImageMessage.obtain(localUri, localUri);
Message message = Message.obtain(targetId, conversationType, imageMessage);
IRongCoreCallback.ISendMediaMessageCallbackWithUploader sendMediaMessageCallbackWithUploader =
new IRongCoreCallback.ISendMediaMessageCallbackWithUploader() {
@Override
public void onAttached(
Message message, IRongCoreCallback.MediaMessageUploader uploader) {
/*上传图片到自己的服务器*/
uploadImg(imgMsg.getPicFilePath(), new UploadListener() {
@Override
public void onSuccess(String url) {
// 上传成功,回调 SDK 的 success 方法,传递回图片的远端地址
uploader.success(Uri.parse(url));
}
@Override
public void onProgress(float progress) {
//刷新上传进度
uploader.update((int) progress);
}
@Override
public void onFail() {
// 上传图片失败,回调 error 方法。
uploader.error();
}
});
}
@Override
public void onError(
final Message message, final IRongCoreEnum.CoreErrorCode coreErrorCode) {
//发送失败
}
@Override
public void onProgress(Message message, int progress) {
//发送进度
}
@Override
public void onSuccess(Message message) {
//发送成功
}
@Override
public void onCanceled(Message message) {
//发送取消
}
};
RongCoreClient.getInstance().sendMediaMessage(
message, pushContent, pushData, sendMediaMessageCallbackWithUploader);
如何发送 @ 消息
@消息在融云即时通讯服务中不属于一种预定义的消息类型(详见服务端文档 消息类型概述)。融云通过在消息中携带 mentionedInfo
数据,帮助 App 实现提及他人(@)功能。
消息的 MessageContent
中的 MentionedInfo 字段存储了携带所 @ 人员的信息。无论是 SDK 内置消息类型,或者您自定义的消息类型,都直接或间接继承了 MessageContent 类。
融云支持在向群组和超级群中发消息时,在消息内容中添加 mentionedInfo
。消息发送前,您可以构造 MentionedInfo
,并设置到消息的 MessageContent
中。
List<String> userIdList = new ArrayList<>();
userIdList.add("userId1");
userIdList.add("userId2");
MentionedInfo mentionedInfo = new MentionedInfo(MentionedInfo.MentionedType.PART, userIdList, null);
TextMessage messageContent = TextMessage.obtain("文本消息");
messageContent.setMentionedInfo(mentionedInfo);
MentionedInfo
参数:
参数 | 类型 | 说明 |
---|---|---|
type | MentionedType | (必填)指定 MentionedInfo 的类型。MentionedType.ALL 表示需要提及(@)所有人。MentionedType.PART 表示需要 @ 部分人,被提及的人员需要在 userIdList 中指定。 |
userIdList | List<String> | 被提及(@)用户的 ID 集合。当 type 为 MentionedType.PART 时必填;从 5.3.1 版本开始,支持当 type 为 MentionedType.ALL 时同时在 userIdList 中提及部分人。接收端可通过 mentionedInfo 获取 userIdList 数据。 |
mentionedContent | String | 触发离线消息推送时,通知栏显示的内容。如果是 NULL ,则显示默认提示内容(“有人 @ 你”)。@消息携带的 mentionedContent 优先级最高,会覆盖所有默认或自定义的 pushContent 数据。 |
以下示例展示了发送一条提及部分用户的文本消息,该消息发往一个群聊会话。
List<String> userIdList = new ArrayList<>();
userIdList.add("userId1");
userIdList.add("userId2");
MentionedInfo mentionedInfo = new MentionedInfo(MentionedInfo.MentionedType.PART, userIdList, null);
TextMessage messageContent = TextMessage.obtain("文本消息");
messageContent.setMentionedInfo(mentionedInfo);
Message message = Message.obtain(mTargetId, ConversationType.GROUP, messageContent);
RongCoreClient.getInstance().sendMessage(message, null , null, new IRongCoreCallback.ISendMessageCallback(){
/**
* 消息发送前回调, 回调时消息已存储数据库
* @param message 已存库的消息体
*/
@Override
public void onAttached(Message message) {
}
/**
* 消息发送成功。
* @param message 发送成功后的消息体
*/
@Override
public void onSuccess(Message message) {
}
/**
* 消息发送失败
* @param message 发送失败的消息体
* @param errorCode 具体的错误
*/
@Override
public void onError(Message message, IRongCoreEnum.CoreErrorCode coreErrorCode) {
}
});
IMLib SDK 接收消息后,您需要处理 @ 消息中的数据。您可以在获取 Message
(消息对象)后,通过以下方法获取到消息对象携带的 MentionedInfo
对象。
MentionedInfo mentionedInfo = message.getContent().getMentionedInfo();
远程推送通知
聊天室会话不支持离线消息机制,因此也不支持离线消息转推送。
如果您的应用已经在融云配置第三方推送,在消息接收方离线时,融云服务端会根据消息类型、接收方支持的推送通道、接收方的免打扰设置等,决定是否触发远程推送。
远程推送通知一般会展现在系统的通知栏。融云内置的消息类型默认会在通知栏展现通知标题和通知内容。关于各类型消息的默认推送通知内容,详见用户内容类消息格式。
如果您需要个性化的离线推送通知,可以通过以下方式,修改或指定远程推送的通知标题、通知内容其他属性。
- sendMessage 和 sendMediaMessage 方法的输入参数中直接提供了用于控制推送通知内容(
pushContent
)参数。 - 如果您需要控制离线推送通知的更多属性,例如标题、内容、图标、或根据第三方厂商通道作个性化配置,请使用 Message 的推送属性(
setMessagePushConfig
)方法进行配置。消息推送属性中的pushContent
配置会覆盖发送消息接口中的pushContent
。