实现单聊消息收发
更新时间: 2024/03/15 16:12:31
网易云信 IM 即时通讯服务提供一整套即时通讯基础能力,助您快速实现多样化的即时通讯场景。
本文主要介绍通过集成 NetEase IM SDK(NIM SDK)并调用 API,快速实现单聊消息收发功能。
SDK 说明
网易云信 IM Web Elite SDK(简称 IM2)为原版 Web SDK(简称 IM1)的重构版本。IM2 继承了 IM1 的特性,提供完善的即时通讯功能开发框架和简洁的 API 接口,方便您快速将即时通讯功能集成到您的 PC/移动 Web 应用及 NodeJS、React Native、微信小程序、字节跳动小程序等跨平台应用。
相较于 IM1,IM2 做了如下改进:
- 使用 TypeScript 重构,API 出入参数定义更加完善。
- 使用 Promise API 替代回调地狱(callback hell)。
- 支持更多开发环境:现支持 IE v11.0.0 及以上版本和 chrome v4.0.0 及以上版本等浏览器,以及微信小程序、支付宝小程序、百度智能小程序和字节跳动小程序、uniapp等跨平台开发环境。
- 结构更精简。包体积降至 IM1 的 40%。
技术原理
NIM SDK 提供了如下实现方案。
上图中的流程可归纳为以下 7 个步骤:
- 开发者将应用的账号传入云信 IM 服务端,注册云信 IM 账号。
- 云信 IM 服务端返回 Token 给应用服务器。
- 应用客户端登录应用服务器。
- 应用服务器将 Token 返回给应用客户端。
- 客户端用户带 Token 登录云信 IM 服务端。
- 用户发送消息到云信 IM 服务端。
- 云信 IM 服务端将消息发送给其他用户。
上图仅以静态 Token 登录为例展示消息收发流程。网易云信 IM 还支持动态 Token 登录鉴权和第三方回调登录鉴权,相关详情请参见登录鉴权。
前提条件
- 已在云信控制台创建应用,并获取 App Key 和 App Secret。
- 已注册云信 IM 账号。云信 IM 账号用于登录 IM SDK。
云信控制台创建应用后自动开通 IM 基础版服务,文本消息收发属于 IM 基础版服务中的功能,因此不需要升级服务。如果您想实现 IM 的增值功能(例如扩展群组数),需要先升级成 IM 专业版服务,再进行后续操作。具体请参见升级服务。
实现流程
步骤 1:集成 SDK
SDK 以 npm 包的形式提供,请前往 nim-web-sdk-ng 获取 npm 包。
- 执行以下命令安装 npm 包。
npm install nim-web-sdk-ng@"<1"
SDK 结构如下:
dist/
├── CHATROOM_BROWSER_SDK.js 聊天室浏览器适配版 UMD 格式
├── CHATROOM_MINIAPP_SDK.js 聊天室小程序适配版 UMD 格式
├── CHATROOM_UNIAPP_SDK.js 聊天室 UNIAPP 适配版 UMD 格式
├── NIM_BROWSER_SDK.js IM 浏览器适配版 UMD 格式
├── NIM_MINIAPP_SDK.js IM 小程序适配版 UMD 格式
├── NIM_UNIAPP_SDK.js IM UNIAPP 适配版 UMD 格式
├── QCHAT_BROWSER_SDK.js 圈组浏览器适配版 UMD 格式
├── esm
│ ├── adapters.d.ts
│ ├── index.d.ts
│ ├── index.js ESM 模式,汇总各模块的,ES Module 格式
- 这里的小程序适配版,实际指四种小程序:微信、头条、百度、支付宝。
- ESM 模式的 SDK,导出了 IM、聊天室、圈组三个 SDK,以及适配器,对体积有比较严格的需求的建议使用这个模式。
- 根据实际开发需求引入相应的 SDK。
开发需求 |
环境 |
引入 SDK |
---|---|---|
IM 功能 | 浏览器 | import NIMSDK from 'nim-web-sdk-ng/dist/NIM_BROWSER_SDK' |
IM 功能 | uniapp | import NIMSDK from 'nim-web-sdk-ng/dist/NIM_UNIAPP_SDK' |
IM 功能 | 微信/支付宝/头条/百度小程序 | import NIMSDK from 'nim-web-sdk-ng/dist/NIM_MINIAPP_SDK' |
聊天室功能 | 浏览器 | import ChatroomSDK from 'nim-web-sdk-ng/dist/CHATROOM_BROWSER_SDK' |
聊天室功能 | uniapp | import ChatroomSDK from 'nim-web-sdk-ng/dist/CHATROOM_UNIAPP_SDK' |
聊天室功能 | 微信/支付宝/头条/百度小程序 | import ChatroomSDK from 'nim-web-sdk-ng/dist/CHATROOM_MINIAPP_SDK' |
圈组功能 | 浏览器 | import QChatSDK from 'nim-web-sdk-ng/dist/QCHAT_BROWSER_SDK' |
uniapp 和各种小程序不支持 TypeScript,目前仅支持在浏览器环境中导出 TS 声明。
- (可选)通过 ESM 形式引入 SDK。
单独引入上述 SDK,代码总体积会比较大,如果开发者对体积大小有特别的需求,可以选用 ESM 形式引入。
- SDK 的版本需要 0.6.1 及以上。
- ESM 模式的 SDK,导出 IM、聊天室、圈组三个 SDK。
- 需要开发者自行注册模块和适配器。参见
node_modules
中关于esm
模块的 TS 定义来获取模块和适配器种类。 - 对于不需要的模块,建议开发者最后在工程中进行打包(tree-shaking)。
使用 ESM 形式引入的示例代码如下:
import { NIM, browserAdapters, MsgService, SessionService } from 'nim-web-sdk-ng/dist/esm'
// ESM 模式,IM 依赖的能力需要自行注册,以便于不用的模块最后能被 tree-shaking 掉。
NIM.setAdapters(browserAppAdapters)
NIM.registerService(MsgService, 'msg')
NIM.registerService(SessionService, 'session')
步骤 2:初始化 SDK
将 SDK 集成到客户端后,需要先完成 SDK 的初始化才能使用其他功能。
本文主要介绍 NIM_BROWSER_SDK
的初始化。示例代码如下:
const nim = new NIMSDK({
appkey: 'YOUR_APPKEY',
account: 'YOUR_ACCID',
token: 'YOUR_TOKEN',
debugLevel: 'debug',
});
account
即 IM 账号中的accid
,token
即 IM 账号中的token
。- NIM 的初始化参数请参见
NIMInitializeOptions
和NIMOtherOptions
。
步骤 3:监听事件
实现文本消息收发,需要监听 msg
事件。同时,您也可以监听其他事件,具体事件类型,请参见IMEventInterface。示例代码如下:
// 事件声明
const eventList = [
'msg',//接收消息事件
]
nim.on('msg', function(msg) { console.log('Receive msg: ', msg) })
SDK 相关事件必须在 connect(登录)前声明才会生效,声明方式可以参考初始化中 eventList 中的内容。
步骤 4:登录 SDK
await nim.connect();
登录完成后,SDK 会发起同步操作,比如向服务端同步漫游消息,离线消息,好友关系等。同步的过程中会触发 syncdone
事件。您可以通过初始化的 NIMOtherOptions
中的 SyncOptions
来控制同步的内容。
步骤 5:实现文本消息收发
以下流程中,以用户 A 和 B 的文本消息交互为例,介绍如何通过 IM SDK 实现文本消息收发。
- 用户 A 向用户 B 发送消息。
目前 IM Web Elite SDK 支持多种消息类型,包括文本消息、图片消息、语音消息、视频消息、文件消息、地理位置消息、提示消息、通知消息以及自定义消息。具体请参见消息收发。 这里主要以发送文本消息为例,示例代码如下:
jsawait nim.msg.sendTextMsg({
"scene": "p2p",
"to": "{{Receiver_ACCOUNT_ID}}",
"body": "this is a text",
"onSendBefore": function(msg) {
console.log('Get msg before send', msg)
}
})
SDK 通过调用 sendTextMsg
方法实现消息发送功能。
-
监听接口根据实际情况触发接收消息事件,用户 B 收到文本消息。
-
(可选)用户登出/销毁实例。
js// 断开
await nim.disconnect()
setTimeout(function() {
// 断开后仍旧可以 connect 成功
await nim.connect()
// 销毁后就无法再次 connect 建立长连接,需要再次 new 一个实例。
await nim.destroy()
}, 5000)