消息收发

更新时间: 2024/03/15 16:12:31

Netease IM Web SDK(以下简称“NIM SDK”)支持收发多种消息类型,助您快速实现多样化的消息业务场景。

NIM SDK 支持的消息类型包括文本消息、文件(包括音视、视频、图片等)消息、地理位置消息、提示消息、通知消息、和自定义消息。SDK 中定义消息对象的结构为NIMMessage,相同类型的消息,通过在调用相应类型的消息发送接口时配置scene参数进行区分,该参数值配置为p2p时表示为单聊消息,为team时表示为群聊消息,为superTeam时表示为超大群消息。

本文介绍通过网易云信 NIM SDK 实现消息收发的技术原理、前提条件以及具体的实现流程。

本节的示例代码皆以发送单聊消息(scenep2p)为例。如需发送群消息, 请将scene的值替换为team, 将to的值替换为群 ID(teamId)。如需发送超大群消息,请将scene的值替换为superTeam,将to替换为超大群的 ID(teamId)。

API使用限制

发送消息的方法调用均存在频控,一分钟内默认最多可调用 300 次。

前提条件

在实现消息收发之前,请确保:

实现消息收发

初始化配置

在收发送消息前,用户需要在初始化时按需完成消息相关参数配置。 例如,为了保证能接收到消息,必须注册onmsg回调来监听消息接收。

以下仅列出于消息强相关的初始化参数,完整的初始化参数参见NIMGetInstanceOptions

参数
类型
说明
shouldIgnoreNotification function 该参数类型为函数(function),表示是否要忽略某条通知类消息。该方法会将接收到的通知类消息对象,按照用户上层定义的逻辑进行过滤, 如果该方法返回 true,那么 SDK 将忽略此条通知类消息
onmsg function 消息(NIMMessage)到达事件的回调当前登录帐号在其它端发送消息之后也会收到此回调, 此时消息对象的from字段就是当前登录的帐号。
onroamingmsgs function 同步漫游消息的回调。每个会话对应一个回调, 会传入消息数组
onofflinemsgs function 同步离线消息对象的回调, 每个会话对象对应一个回调, 会传入消息数组

在支持数据库且启用了多 tab 同时登录时,多个 tab 页同时断线重连之后, 只会有一个 tab 页负责存储漫游消息和离线消息, 即只会有一个 tab 页会收到onroamingmsgsonofflinemsgs回调, 其它 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调用时序

uml diagram

具体说明

  1. 接收方在进行 SDK 初始化时,注册onmsg回调实现对消息接收事件的监听。

  2. 发送方调用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);
    }
    
  3. 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 调用时序

uml diagram

具体说明

  1. 接收方在进行 SDK 初始化时,注册onmsg回调实现对消息接收事件的监听。

  2. 发送方调用sendFile方法发送文件消息。

    • 支持以下几种场景传入文件:

      • 通过参数fileInput传入文件:选择 dom 节点或者节点 ID,SDK 会读取该节点下的文件,在上传完成前请不要操作该节点下的文件
      • 通过参数blob传入 Blob 对象
      • 通过参数dataURL传入包含 MIME type 和 base64 数据的 data URL,此用法需要浏览器支持 Blob

      SDK 会先将文件上传到文件服务器, 然后把获取的文件对象在uploaddone回调中传给发送方, 然后将其拼装成文件消息发送出去。

    • 参数type指定了要发送的文件类型, 包括图片、音频、视频和普通文件, 对应的值分别为imageaudiovideofile, 不传默认为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
    });
    
    
  3. onmsg回调触发,接收方通过该回调收到消息。

先上传文件再发送

API 调用时序

uml diagram

具体说明

  1. 接收方在进行 SDK 初始化时,注册onmsg回调实现对消息接收事件的监听。

  2. 发送方调用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

  3. SDK 触发onmsg回调,接收方通过该回调收到消息。

收发地理位置消息

当发送地理位置消息或收到地理位置消息时, 消息对象(NIMMessage)的geo字段代表地理位置对象, 包含以下属性:

属性 说明
lng 经度
lat 纬度
title 地址描述

API 调用时序

uml diagram

具体说明

  1. 接收方在进行 SDK 初始化时,注册onmsg回调实现对消息接收事件的监听。

  2. 发送方调用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需要用户自己实现,将消息压入到自己的数据中
    
    
  3. 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 指定发送消息的场景,包括:
  • p2p:单聊消息
  • team:群聊消息
  • superTeam:超大群消息
to 指定消息的接收方, 发送单聊消息时填接收方的 IM 帐号, 发送群消息时填群ID(teamId),发送超大群消息时填超大群的 ID (teamId)
公共回参
参数 说明
idClient 发送消息的 SDK API (除了直接发送文件消息)会返回 SDK 生成的消息 ID。 直接发送文件消息时,idClient字段从beforesend回调中获取。
error done回调中可以根据error对象和消息对象的idClient字段来确定对应的消息的发送状态。
  • 如果error为空, 那么表明idClient对应的消息发送成功
  • 如果error不为空, 表明idClient对应的消息发送失败, error包含详细的错误信息

常见问题

发送消息后怎么获取消息内容

在发送消息接口的done回调中返回NIMMessage对象。可以通过flow属性获取消息方向,通过to属性获取聊天对象的accid/群组id,通过text属性获取文本消息的内容,通过file属性获取文件消息的文件对象,通过status属性获取消息发送状态,通过time属性获取消息时间戳。

如何判断消息发送成功

在消息发送的done回调中根据消息对象的status字段和error对象来确定消息的发送状态。如果statussuccesserror为空则表示消息发送成功。

如何设置消息的扩展字段

单聊或群聊消息具有服务端扩展字段和客户端扩展字段。服务端扩展字段只能在消息发送前设置,会同步到其他端;客户端扩展字段在消息发送前后设置均可,不会同步到其他端。

扩展字段,请使用 JSON 格式封装,并传入非格式化的 JSON 字符串,最大长度1024字节。


具体方法如下:

更新客户端扩展字段
  1. 调用发送单聊或群聊消息的方法时,构造的消息对象中,设置localCustom字段。

  2. 调用updateLocalMsg方法更新消息的本地扩展字段。

    nim.updateLocalMsg({
    idClient: msg.idClient, localCustom: '{"key","value"}',
    done: updateLocalMsgDone
    })
    

    设置消息的客户端扩展字段后,必须调用该方法,否则无法生效。

更新服务端扩展字段

调用发送单聊或群聊消息的方法时,构造的消息对象中,设置Custom字段。

此文档是否对你有帮助?
有帮助
去反馈
  • API使用限制
  • 前提条件
  • 实现消息收发
  • 初始化配置
  • 收发文本消息
  • 收发文件消息
  • 文件对象类型
  • 实现流程
  • 收发地理位置消息
  • 收发提示消息
  • 接收通知消息
  • 收发自定义消息
  • 相关参考
  • API 参考
  • 公共参数
  • 常见问题
  • 发送消息后怎么获取消息内容
  • 如何判断消息发送成功
  • 如何设置消息的扩展字段