====== 消息管理–发送和接收消息 ======
更新时间:2022-02-28
本文介绍环信即时通讯 IM Web SDK 如何发送和接收多种类型的消息。
===== 技术原理 =====
环信即时通讯 IM Web SDK 支持发送和接收消息和已读回执,其中包含如下主要方法:
* ''%%send%%'' 发送消息给特定用户、群组或者聊天室;
* ''%%recallMessage%%'' 撤回自己发出的消息;
* ''%%addEventHandler%%'' 添加接收的回调通知(所有 SDK 事件回调、具体事件回调请参考下文);
* 发送会话已读通知;
* 发送指定消息已读的通知。
消息收发流程如下:
- 用户 A 发送一条消息到环信的消息服务器。
- 单聊时消息服务器发消息给用户 B,群聊时发消息给群内其他每个成员。
- 用户收到消息。
{{:ccim:web:sendandreceivemsg.png?800|}}
===== 前提条件 =====
开始前,请确保满足以下条件:
* 完成 SDK 初始化,详见 [[ccim:web:quickstart|快速开始]]。
* 了解环信即时通讯 IM 的使用限制,详见 [[ccim:limitation|使用限制]]。
===== 实现方法 =====
==== 构造消息 ====
首先,构造一个消息。示例代码如下:
let msg = WebIM.message.create(option); // 消息内容选项,下文详细介绍。
==== 发送文本消息 ====
示例如下:
// 单聊时发送文本消息。
function sendPrivateText() {
let option = {
chatType: 'singleChat', // 会话类型,设置为单聊。
type: 'txt', // 消息类型。
to: 'userID', // 消息接收方(用户 ID)。
msg: 'message content' // 消息内容。
}
let msg = WebIM.message.create(option);
connection.send(msg).then(() => {
console.log('send private text Success');
}).catch((e) => {
console.log("Send private text error");
})
};
**注意**
群组消息和聊天室消息只需修改 option 对象下的其中 2 个参数:''%%to%%'' 和 ''%%chatType%%'' 群聊:''%%to: (群组 ID)%%''、''%%chatType:"groupChat"%%'' 聊天室:''%%to: (聊天室 ID)%%''、''%%chatType:"chatRoom"%%''
==== 接收消息 ====
你可以通过 ''%%addEventHandler%%'' 注册监听器接收各类消息的回调,函数代码如下:
// handlerID 为用户自定义的 EventHandler ID, 可利用不同的 ID 注册多个监听器。
connection.addEventHandler('handlerID', {
onConnected: function ( message ) {}, // 连接成功回调。
onDisconnected: function ( message ) {}, // 连接关闭回调。
onTextMessage: function ( message ) {}, // 收到文本消息。
onEmojiMessage: function ( message ) {}, // 收到表情消息。
onImageMessage: function ( message ) {}, // 收到图片消息。
onCmdMessage: function ( message ) {}, // 收到命令消息。
onAudioMessage: function ( message ) {}, // 收到音频消息。
onLocationMessage: function ( message ) {},// 收到位置消息。
onFileMessage: function ( message ) {}, // 收到文件消息。
onCustomMessage: function ( message ) {}, // 收到自定义消息。
onVideoMessage: function (message) {}, // 收到视频消息。
onRecallMessage: function( message ){}, // 收到消息撤回回执。
onReceivedMessage: function(message){}, // 收到消息送达服务器回执。
onDeliveredMessage: function(message){}, // 收到消息送达客户端回执。
onReadMessage: function(message){}, // 收到消息已读回执。
onMutedMessage: function(message){}, // 如果用户在 A 群组被禁言,在 A 群发消息会触发该回调且消息不传递给该群的其它成员。
onChannelMessage: function(message){} // 收到会话已读回执,对方发送 `channel ack` 时会触发该回调。
onPresence: function ( message ) {}, // 处理“广播”或“发布-订阅”消息,如联系人订阅请求、处理群组、聊天室被踢或解散等消息.
onRoster: function ( message ) {}, // 处理好友申请。
onInviteMessage: function ( message ) {}, // 处理群组邀请。
onOnline: function () {}, // 本机网络连接成功。
onOffline: function () {}, // 本机网络掉线。
onError: function ( message ) {}, // 失败回调。
onBlacklistUpdate: function (list) { // 黑名单变动。
// 查询黑名单、将好友拉黑以及将好友移出黑名单均会触发该回调,`list` 列明黑名单上的现有好友。
},
});
==== 撤回消息 ====
消息撤回功能指用户可撤回特定时间内发出的消息,消息撤回时限默认 2 分钟。如需调整,可联系环信即时通讯 IM 的客户经理。
/**
* 发送要撤回的消息。
* @param {Object} option -
* @param {Object} option.mid - 要撤回消息的 ID。
* @param {Object} option.to - 消息接收对象。
* @param {Object} option.type - 消息类型:chat (单聊)、groupchat (群聊)和 chatroom (聊天室)。
*/
let option = {
mid: 'msgId',
to: 'userID',
chatType: 'singleChat'
};
connection.recallMessage(option).then((res) => {
console.log('success', res)
}).catch((error) => {
// 消息撤回失败 (超过 2 分钟)。
console.log('fail', error)
})
监听要撤回的消息,示例如下:
WebIM.conn.addEventHandler('MESSAGES',{
onRecallMessage: => (msg) {
// 这里需要在本地删除对应的消息,也可以插入一条消息:“XXX撤回一条消息”。
console.log('撤回成功',msg)
},
})
==== 发送附件类型的消息 ====
除文本消息外,还有几种其他类型的消息,其中语音、图片、短视频和文件等消息发送前先将附件上传到消息服务器。语音收到会自动下载,而图片和视频会自动下载缩略图。文件消息不会自动下载附件,接收方需调用下载附件的 API,具体实现参考下文。
发送附件消息,SDK 自动分两步完成:
- 上传附件到服务器,获得服务返回的附件信息等;
- 发送附件消息,消息体包含附件的基本信息和服务器路径等。
=== 发送图片消息 ===
示例如下:
function sendPrivateImg() {
let input = document.getElementById('image'); // 选择要发送的图片。
let file = WebIM.utils.getFileUrl(input); // 将图片转换为 fileObj 格式。
// 也可将文件自行处理成该格式。
// let file = {
// data: file file 对象。
// filename: 'fileName', 文件名称。
// filetype: 'filetype', 文件类型。
// }
let allowType = {
'jpg': true,
'gif': true,
'png': true,
'bmp': true
};
if (file.filetype.toLowerCase() in allowType) {
let option = {
chatType: 'singleChat', // 会话类型,设置为单聊。
type: 'img', // 消息类型,设置为图片。
to: 'userID', // 消息接收方(用户 ID)。
file: file,
onFileUploadError: function () {
// 消息上传失败。
console.log('onFileUploadError');
},
onFileUploadProgress: function (progress) {
// 上传进度的回调。
console.log(progress)
},
onFileUploadComplete: function () {
// 消息上传成功。
console.log('onFileUploadComplete');
}
};
let msg = WebIM.message.create(option);
connection.send(msg).then(() => {
console.log('Success'); // 消息发送成功。
}).catch((e) => {
console.log("Fail"); // 如禁言或拉黑后消息发送失败。
});
}
};
=== 发送 URL 图片消息 ===
示例如下:
需要在 WebIMConfig.js 中 设置 ''%%useOwnUploadFun: true%%''。
function sendPrivateUrlImg() {
let option = {
chatType: 'singleChat', // 会话类型,设置为单聊。
type: 'img', // 消息类型,设置为图片。
to: 'userID', // 消息接收方(用户 ID)。
url: 'imgUrl' // 图片 URL。
}
let msg = WebIM.message.create(option);
connection.send(msg).then((res) => {
console.log('success', res); // 消息发送成功。
}).catch((e) => {
console.log("fail"); // 如禁言或拉黑后消息发送失败。
});
}
=== 发送文件消息 ===
示例如下:
function sendPrivateFile() {
let input = document.getElementById('file'); // 选择要发送的文件。
let file = WebIM.utils.getFileUrl(input); // 将文件转换成 fileObj 格式。
// 也可以将文件自行处理成该格式。
// let file = {
// data: file file 对象。
// filename: 'fileName', 文件名称。
// filetype: 'filetype', 文件类型。
// }
let allowType = {
'jpg': true,
'gif': true,
'png': true,
'bmp': true,
'zip': true,
'txt': true,
'doc': true,
'pdf': true
};
if (file.filetype.toLowerCase() in allowType) {
let option = {
chatType: 'singleChat', // 会话类型,设置为单聊。
type: 'file', // 消息类型,设置为文件。
to: 'userID', // 消息接收方(用户 ID)。
file: file,
filename: file.filename,
onFileUploadError: function () {
// 消息上传失败。
console.log('onFileUploadError');
},
onFileUploadProgress: function (progress) {
// 上传进度的回调。
console.log(progress)
},
onFileUploadComplete: function () {
// 消息上传成功。
console.log('onFileUploadComplete');
}
}
let msg = WebIM.message.create(option);
connection.send(msg).then(() => {
console.log('success'); // 消息发送成功。
}).catch((e) => {
console.log("fail"); // 如禁言或拉黑后消息发送失败。
});
}
};
=== 发送音频消息 ===
示例如下:
function sendPrivateAudio() {
let input = document.getElementById('audio'); // 选择要发送的音频。
let file = WebIM.utils.getFileUrl(input); // 将音频转换为 fileObj 格式。
let allowType = {
'mp3': true,
'amr': true,
'wmv': true
};
if (file.filetype.toLowerCase() in allowType) {
let option = {
chatType: 'singleChat', // 会话类型,设置为单聊。
type: 'audio', // 消息类型,设置为音频。
to: 'userID', // 消息接收方。
file: file,
filename: file.filename,
onFileUploadError: function () {
// 消息上传失败。
console.log('onFileUploadError');
},
onFileUploadProgress: function (e) {
// 上传进度的回调。
console.log(e)
},
onFileUploadComplete: function () {
// 消息上传成功。
console.log('onFileUploadComplete');
}
};
let msg = WebIM.message.create(option);
connection.send(msg).then(() => {
console.log('success'); // 消息发送成功。
}).catch((e) => {
console.log("fail"); // 如禁言或拉黑后消息发送失败。
});;
}
};
=== 发送视频消息 ===
示例如下:
function sendPrivateVideo() {
let input = document.getElementById('video'); // 选择要发送的视频。
let file = WebIM.utils.getFileUrl(input); // 将文件转换为 fileObj 格式。
let allowType = {
'mp4': true,
'wmv': true,
'avi': true,
'rmvb': true,
'mkv': true
};
if (file.filetype.toLowerCase() in allowType) {
let option = {
chatType: 'singleChat', // 会话类型,设置为单聊。
type: 'video', // 消息类型,设置为视频。
to: 'username', // 消息接收方。
file: file,
filename: file.filename,
onFileUploadError: function () {
// 消息上传失败。
console.log('onFileUploadError');
},
onFileUploadProgress: function (e) {
// 上传进度的回调。
console.log(e)
},
onFileUploadComplete: function () {
// 消息上传成功。
console.log('onFileUploadComplete');
}
};
let msg = WebIM.message.create(option);
connection.send(msg).then(() => {
console.log('Success'); // 消息发送成功。
}).catch((e) => {
console.log("Fail"); // 如禁言或拉黑后消息发送失败。
});;
}
};
=== 发送贴图消息 ===
利用以下代码可实现用户粘贴图片至输入框后发送:
document.addEventListener('paste', function (e) {
if (e.clipboardData && e.clipboardData.types) {
if (e.clipboardData.items.length > 0) {
if (/^image\/\w+$/.test(e.clipboardData.items[0].type)) {
let blob = e.clipboardData.items[0].getAsFile();
let url = window.URL.createObjectURL(blob);
let msg = new WebIM.message('img'); // 创建图片消息。
let option = {
chatType: 'singleChat', // 会话类型,设置为单聊。
type: 'img', // 消息类型,设置为图片。
to: 'userID', // 消息接收方(用户 ID)。
file: {data: blob, url: url},
onFileUploadError: function (error) {
console.log('error');
},
onFileUploadComplete: function (data) {
console.log('complete');
},
}
let msg = WebIM.message.create(option);
connection.send(msg);
}
}
}
});
==== 发送透传消息 ====
透传消息可视为一条命令,通过发送这条命令给对方,通知对方要执行的操作,收到消息可以自定义处理。
透传消息适用于更新头像或昵称等场景。
let option = {
chatType: 'singleChat', // 会话类型,设置为单聊。
type: 'cmd', // 消息类型,设置为命令消息。
to: 'userID', // 消息接收方。
action : 'action', // 用户自定义操作。对于命令消息,该字段必填。
}
let msg = WebIM.message.create(option)
conn.send(msg).then(() => {
console.log('success'); // 消息发送成功。
}).catch((e) => {
console.log("fail"); // 如禁言获拉黑后消息发送会失败。
});
=== 发送自定义消息 ===
你可以在以上几种消息之外,自己定义消息类型,方便业务处理。自定义消息类型支持你自己设置一个消息的类型名称,这样你可以添加多种自定义消息。自定义消息的内容部分是 key,value 格式的,你需要自己添加并解析该内容。示例如下:
function sendCustomMsg() {
let option = {
chatType: 'singleChat',
type: 'custom',
to: 'userID', // 接收消息对象(用户 ID)
customEvent: 'customEvent', // 自定义事件。
customExts: {}, // 消息内容,key/value 需要 string 类型。
ext:{} // 消息扩展。
}
let msg = WebIM.message.create(option)
connection.send(msg).then(() => {
console.log('success'); // 消息发送成功。
}).catch((e) => {
console.log("fail"); // 如禁言或拉黑后消息发送失败。
});
};
=== 使用消息的扩展字段 ===
当 SDK 提供的消息类型不满足需求时,你可以通过消息扩展字段来传递自定义的内容,从而生成自己需要的消息类型。
当目前消息类型不满足用户需求时,可以在扩展部分保存更多信息,例如消息中需要携带被回复的消息内容或者是图文消息等场景。
function sendPrivateText() {
let option = {
chatType: 'singleChat',
type: 'txt', // 消息类型。
msg: 'message content',
to: 'userID',
ext: { // 扩展字段。
key: '自定义的value',
key2: {
key3: '自定义的value'
}
},
}
let msg = WebIM.message.create(option)
connection.send(msg).then(() => {
console.log('success'); // 消息发送成功。
}).catch((e) => {
console.log("fail"); // 如禁言或拉黑后消息发送失败。
});
};
**注意**
发送 ext 扩展消息,可以不带该字段。不过若有该字段,值不能是 “ext:null” 这种形式,否则会出错。
==== 参考 ====
消息相关限制:
* 每条消息的长度:4 KB;
* 附件的默认大小:10 MB;
* [[ccim:web:message3|从服务器获取会话列表]]:''该功能需联系商务开通,开通后,用户默认可拉取 7 天内的 10 个会话(每个会话包含最新一条历史消息),如需调整会话数量或时间限制请联系环信商务经理(您可以在环信通讯云管理后台首页,扫描二维码联系您的商务经理)。''
* 消息存储时间:根据不同的套餐版本消息存储时间不同,专业版 7 天,旗舰版 90 天, 尊享版 180 天。