消息收发
更新时间: 2024/03/15 16:12:31
Netease IM Web SDK(以下简称“NIM SDK”)支持收发多种消息类型,助您快速实现多样化的消息业务场景。
NIM SDK 支持的消息类型包括文本消息、文件(包括音视、视频、图片等)消息、地理位置消息、提示消息、通知消息、和自定义消息。SDK 中定义消息对象的结构为NIMMessage
,相同类型的消息,通过在调用相应类型的消息发送接口时配置scene
参数进行区分,该参数值配置为p2p
时表示为单聊消息,为team
时表示为群聊消息,为superTeam
时表示为超大群消息。
本文介绍通过网易云信 NIM SDK 实现消息收发的技术原理、前提条件以及具体的实现流程。
本节的示例代码皆以发送单聊消息(scene
为p2p
)为例。如需发送群消息, 请将scene
的值替换为team
, 将to
的值替换为群 ID(teamId
)。如需发送超大群消息,请将scene
的值替换为superTeam
,将to
替换为超大群的 ID(teamId
)。
API使用限制
发送消息的方法调用均存在频控,一分钟内默认最多可调用 300 次。
前提条件
在实现消息收发之前,请确保:
- 已集成 SDK。
- 已注册云信 IM 账号,获取 accid 和 token。
- 已了解各消息类型的使用限制。
- 已创建群组(如果需要发送群消息)。
实现消息收发
初始化配置
在收发送消息前,用户需要在初始化时按需完成消息相关参数配置。 例如,为了保证能接收到消息,必须注册onmsg
回调来监听消息接收。
以下仅列出于消息强相关的初始化参数,完整的初始化参数参见NIMGetInstanceOptions
。
参数 |
类型 |
说明 |
---|---|---|
shouldIgnoreNotification |
function | 该参数类型为函数(function),表示是否要忽略某条通知类消息。该方法会将接收到的通知类消息对象,按照用户上层定义的逻辑进行过滤, 如果该方法返回 true,那么 SDK 将忽略此条通知类消息 |
onmsg |
function | 消息(NIMMessage )到达事件的回调from 字段就是当前登录的帐号。 |
onroamingmsgs |
function | 同步漫游消息的回调。每个会话对应一个回调, 会传入消息数组 |
onofflinemsgs |
function | 同步离线消息对象的回调, 每个会话对象对应一个回调, 会传入消息数组 |
在支持数据库且启用了多 tab 同时登录时,多个 tab 页同时断线重连之后, 只会有一个 tab 页负责存储漫游消息和离线消息, 即只会有一个 tab 页会收到onroamingmsgs
和onofflinemsgs
回调, 其它 tab 页在同步完成之后, 需要调用获取本地历史记录接口从本地缓存中拉取消息记录。
var nim = NIM.getInstance({
onroamingmsgs: onRoamingMsgs,
onofflinemsgs: onOfflineMsgs,
onmsg: onMsg
});
function onRoamingMsgs(obj) {
console.log('收到漫游消息', obj);
pushMsg(obj.msgs);
}
function onOfflineMsgs(obj) {
console.log('收到离线消息', obj);
pushMsg(obj.msgs);
}
function onMsg(msg) {
console.log('收到消息', msg.scene, msg.type, msg);
pushMsg(msg);
switch (msg.type) {
case 'custom':
/**
* 收到自定义消息,用户d根据消息内容处理
*/
break;
case 'notification':
/**
* 收到群通知消息,用户根据群通知的消息进行进一步处理
*/
break;
// 其它case
default:
break;
}
}
function pushMsg(msgs) {
if (!Array.isArray(msgs)) { msgs = [msgs]; }
var sessionId = msgs[0].scene + '-' + msgs[0].account;
data.msgs = data.msgs || {};
data.msgs[sessionId] = nim.mergeMsgs(data.msgs[sessionId], msgs);
}
收发文本消息
API调用时序
具体说明
-
接收方在进行 SDK 初始化时,注册
onmsg
回调实现对消息接收事件的监听。 -
发送方调用
sendText
方法发送一条文本消息。消息是否存入云端(
isHistoryable
)、写入漫游(isRoamingable
)、计入未读数(isUnreadable
)等配置选项说明,请参见消息配置选项。示例代码如下:
var msg = nim.sendText({ scene: 'p2p', to: 'account', text: 'hello', done: sendMsgDone }); console.log('正在发送p2p text消息, id=' + msg.idClient); pushMsg(msg); // pushMsg需要用户自己实现,将消息压入到自己的数据中 function sendMsgDone(error, msg) { console.log(error); console.log(msg); console.log('发送' + msg.scene + ' ' + msg.type + '消息' + (!error?'成功':'失败') + ', id=' + msg.idClient); pushMsg(msg); }
-
SDK 触发
onmsg
回调,接收方通过该回调收到消息。
收发文件消息
文件消息可附带的文件类型包括图片、音频、视频和普通文件,它们的区别在于具体的文件信息不一样。文件信息在消息对象的file
字段内定义。
文件对象类型
当发送图片消息或收到图片消息时, 消息对象(NIMMessage
)的file
字段代表图片对象, 包含以下属性:
属性 | 说明 |
---|---|
name |
图片名称 |
size |
图片大小,单位 byte |
url |
图片的 URL |
ext |
扩展字段 |
w |
图片宽度,单位 px |
h |
图片高度,单位 px |
当发送音频消息, 消息对象(NIMMessage
)的file
字段代表音频对象, 包含以下属性:
属性 | 说明 |
---|---|
name |
音频文件名称 |
size |
音频文件大小, 单位 byte |
url |
音频文件 URL |
ext |
扩展字段 |
dur |
音频时长, 单位 ms |
当发送视频消息或收到视频消息时, 消息对象(NIMMessage
)的file
字段代表视频对象, 包含以下属性:
属性 | 说明 |
---|---|
name |
视频文件名称 |
size |
视频文件大小, 单位 byte |
url |
视频文件 URL |
ext |
扩展字段 |
dur |
视频长度, 单位 ms |
w |
宽, 分辨率, 单位 px |
h |
高, 分辨率, 单位 px |
视频对象取封面(首帧图片):
获取到的视频对象后加vframe
即可,例如:原视频地址为http://img-sample.nos-eastchina1.126.net/sample.wmv
,则封面(首帧)图片地址为http://img-sample.nos-eastchina1.126.net/sample.wmv?vframe
当发送普通文件消息或收到普通文件消息时, 消息对象(NIMMessage
)的file
字段代表文件对象, 包含以下属性:
属性 | 说明 |
---|---|
name |
文件名称 |
size |
文件大小, 单位 byte |
url |
文件的 URL |
ext |
扩展字段 |
实现流程
您可通过两种方式发送文件消息,直接发送或者先上传文件再发送。
API 调用时序
具体说明
-
接收方在进行 SDK 初始化时,注册
onmsg
回调实现对消息接收事件的监听。 -
发送方调用
sendFile
方法发送文件消息。-
支持以下几种场景传入文件:
- 通过参数
fileInput
传入文件:选择 dom 节点或者节点 ID,SDK 会读取该节点下的文件,在上传完成前请不要操作该节点下的文件 - 通过参数
blob
传入 Blob 对象 - 通过参数
dataURL
传入包含 MIME type 和 base64 数据的 data URL,此用法需要浏览器支持 Blob
SDK 会先将文件上传到文件服务器, 然后把获取的文件对象在
uploaddone
回调中传给发送方, 然后将其拼装成文件消息发送出去。 - 通过参数
-
参数
type
指定了要发送的文件类型, 包括图片、音频、视频和普通文件, 对应的值分别为image
、audio
、video
和file
, 不传默认为file
。
- 文件大小限制为最大100M。
- 高级浏览器会在上传前就检测文件大小。
- IE8/IE9会在上传完成后检测文件大小。
- 消息是否存入云端(
isHistoryable
)、写入漫游(isRoamingable
)、计入未读数(isUnreadable
)等配置选项说明,请参见消息配置选项。
示例代码如下:
nim.sendFile({ scene: 'p2p', to: 'account', type: 'image', fileInput: fileInput, fastPass: '{"w":200,"h":110,"md5":"xxxxxxxxx"}', beginupload: function(upload) { // - 如果开发者传入 fileInput, 在此回调之前不能修改 fileInput // - 在此回调之后可以取消图片上传, 此回调会接收一个参数 `upload`, 调用 `upload.abort();` 来取消文件上传 }, uploadprogress: function(obj) { console.log('文件总大小: ' + obj.total + 'bytes'); console.log('已经上传的大小: ' + obj.loaded + 'bytes'); console.log('上传进度: ' + obj.percentage); console.log('上传进度文本: ' + obj.percentageText); }, uploaddone: function(error, file) { console.log(error); console.log(file); console.log('上传' + (!error?'成功':'失败')); }, beforesend: function(msg) { console.log('正在发送p2p image消息, id=' + msg.idClient); pushMsg(msg); // pushMsg需要用户自己实现,将消息压入到自己的数据中 }, done: sendMsgDone });
-
-
onmsg
回调触发,接收方通过该回调收到消息。
API 调用时序
具体说明
-
接收方在进行 SDK 初始化时,注册
onmsg
回调实现对消息接收事件的监听。 -
发送方调用
previewFile
方法上传文件。SDK 会将文件上传到文件服务器, 然后将拿到的文件对象在 done 回调中传给发送方。发送方拿到文件对象后,再调用sendFile
方法发送文件消息。调用
previewFile
时,您可通过以下方式传入文件:- 通过参数
fileInput
传入文件,选择 dom 节点或者节点 ID, SDK 会读取该节点下的文件, 在上传完成前请不要操作该节点下的文件。 - 通过参数
blob
传入 Blob 对象 - 通过参数
dataURL
传入包含 MIME type 和 base64 数据的 data URL, 此用法需要浏览器支持 Blob - 通过参数
filePath
传入文件路径(跨平台系列),支持小程序(5.1.0+)、nodejs(5.4.0+ 内测中)、react-native(5.3.0+),;该参数不支持浏览器环境
其他重要参数说明:
参数说明 fastPass
传入文件 md5 和相关信息(图片宽w、高h,音频时长dur,视频宽w、高h、时长dur),使用重复大文件加速秒传功能 commonUpload
(默认为false),表示是否使用普通上传(最大 100M 文件)。 false
:分片直传方式(每片 4M,最多 10000 片)。true
:普通上传- 文件大小限制为最大100M。
- 高级浏览器会在上传前就检测文件大小。
- IE8/IE9会在上传完成后检测文件大小。
- 消息是否存入云端(
isHistoryable
)、写入漫游(isRoamingable
)、计入未读数(isUnreadable
)等配置选项说明,请参见消息配置选项。
示例代码如下:
nim.previewFile({ type: 'image', fileInput: fileInput, uploadprogress: function(obj) { console.log('文件总大小: ' + obj.total + 'bytes'); console.log('已经上传的大小: ' + obj.loaded + 'bytes'); console.log('上传进度: ' + obj.percentage); console.log('上传进度文本: ' + obj.percentageText); }, done: function(error, file) { console.log('上传image' + (!error?'成功':'失败')); // show file to the user if (!error) { var msg = nim.sendFile({ scene: 'p2p', to: 'account', file: file, done: sendMsgDone }); console.log('正在发送p2p image消息, id=' + msg.idClient); pushMsg(msg); // pushMsg需要用户自己实现,将消息压入到自己的数据中 } } });
如果直接发送文件消息,
sendFile
方法会在beforesend
回调里传入 SDK 生成的消息 ID(idClient
), 如果先上传文件再发送, 那么此方法会直接返回idClient
。 - 通过参数
-
SDK 触发
onmsg
回调,接收方通过该回调收到消息。
收发地理位置消息
当发送地理位置消息或收到地理位置消息时, 消息对象(NIMMessage
)的geo
字段代表地理位置对象, 包含以下属性:
属性 | 说明 |
---|---|
lng |
经度 |
lat |
纬度 |
title |
地址描述 |
API 调用时序
具体说明
-
接收方在进行 SDK 初始化时,注册
onmsg
回调实现对消息接收事件的监听。 -
发送方调用
sendGeo
发送地理位置消息。消息是否存入云端(
isHistoryable
)、写入漫游(isRoamingable
)、计入未读数(isUnreadable
)等配置选项说明,请参见消息配置选项。示例代码如下:
var msg = nim.sendGeo({ scene: 'p2p', to: 'account', geo: { lng: 116.3833, lat: 39.9167, title: 'Beijing' }, done: sendMsgDone }); console.log('正在发送p2p geo消息, id=' + msg.idClient); pushMsg(msg); // pushMsg需要用户自己实现,将消息压入到自己的数据中
-
onmsg
回调触发,接收方通过该回调收到消息。
收发提示消息
提示消息(又叫做 Tip 消息)主要用于会话内的通知提醒,典型使用场景包括进入群组时出现的欢迎消息和会话过程中命中敏感词后的提示等。
调用sendTipMsg
发送提示消息。
消息是否存入云端(isHistoryable
)、写入漫游(isRoamingable
)、计入未读数(isUnreadable
)等配置选项说明,请参见消息配置选项。
示例代码如下:
var msg = nim.sendTipMsg({
scene: 'p2p',
to: 'account',
tip: 'tip content',
done: sendMsgDone
});
console.log('正在发送p2p提醒消息, id=' + msg.idClient);
pushMsg(msg); // pushMsg需要用户自己实现,将消息压入到自己的数据中
接收通知消息
一些特定场景的行为,云信服务端预置了一些系统通知消息。通知消息也是一种特定消息,开发者需解析消息中附带的信息,来获取通知内容。如最常见的通知消息————群通知事件,如有新成员进群,则群内已有成员将收到此通知消息。
通知消息属于会话内的一种消息,其对应的数据结构为 NIMMessage
,消息类型为 type.notification
。目前用于群通知。
收发自定义消息
调用sendCustomMsg
发送自定义消息。
消息是否存入云端(isHistoryable
)、写入漫游(isRoamingable
)、计入未读数(isUnreadable
)等配置选项说明,请参见消息配置选项。
在网易云信开放的旧版 web-demo 源码中,type-1为[石头剪刀布],type-2为[阅后即焚],type-3为[贴图表情],type-4为[白板教学]。如下代码用自定义消息实现了石头剪刀布
游戏:
javascriptvar value = Math.ceil(Math.random()*3);
var content = {
type: 1,
data: {
value: value
}
};
var msg = nim.sendCustomMsg({
scene: 'p2p',
to: 'account',
content: JSON.stringify(content),
done: sendMsgDone
});
console.log('正在发送p2p自定义消息, id=' + msg.idClient);
pushMsg(msg); // pushMsg需要用户自己实现,将消息压入到自己的数据中
相关参考
API 参考
API |
说明 |
---|---|
sendText |
发送文本消息 |
sendFile |
发送文件消息,包括图片消息、视频消息、音频消息和普通文件消息 |
sendGeo |
发送地理位置消息 |
sendTipMsg |
发送提示消息 |
sendCustomMsg |
发送自定义消息 |
公共参数
所有发送消息的 SDK API 都有如下参数。
参数 | 说明 |
---|---|
scene |
指定发送消息的场景,包括:
|
to |
指定消息的接收方, 发送单聊消息时填接收方的 IM 帐号, 发送群消息时填群ID(teamId ),发送超大群消息时填超大群的 ID (teamId ) |
参数 | 说明 |
---|---|
idClient |
发送消息的 SDK API (除了直接发送文件消息)会返回 SDK 生成的消息 ID。 idClient 字段从beforesend 回调中获取。 |
error |
在done 回调中可以根据error 对象和消息对象的idClient 字段来确定对应的消息的发送状态。
|
常见问题
发送消息后怎么获取消息内容
在发送消息接口的done
回调中返回NIMMessage
对象。可以通过flow
属性获取消息方向,通过to
属性获取聊天对象的accid/群组id,通过text
属性获取文本消息的内容,通过file
属性获取文件消息的文件对象,通过status
属性获取消息发送状态,通过time属性获取消息时间戳。
如何判断消息发送成功
在消息发送的done
回调中根据消息对象的status
字段和error
对象来确定消息的发送状态。如果status
为success
,error
为空则表示消息发送成功。
如何设置消息的扩展字段
单聊或群聊消息具有服务端扩展字段和客户端扩展字段。服务端扩展字段只能在消息发送前设置,会同步到其他端;客户端扩展字段在消息发送前后设置均可,不会同步到其他端。
扩展字段,请使用 JSON 格式封装,并传入非格式化的 JSON 字符串,最大长度1024字节。
具体方法如下:
-
调用发送单聊或群聊消息的方法时,构造的消息对象中,设置
localCustom
字段。 -
调用
updateLocalMsg
方法更新消息的本地扩展字段。nim.updateLocalMsg({ idClient: msg.idClient, localCustom: '{"key","value"}', done: updateLocalMsgDone })
设置消息的客户端扩展字段后,必须调用该方法,否则无法生效。
调用发送单聊或群聊消息的方法时,构造的消息对象中,设置Custom
字段。