====== 消息管理–发送和接收消息 ====== 更新时间: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 天。