跳到主要内容

版本:5.X

快速集成直播聊天室

本教程主要描述如何使用融云 IM SDK 在 Web 端(Javascript)快速实现一个直播聊天室。

前置条件

创建融云开发者账号,获取 App Key

步骤 1:导入 SDK

使用 NPM 安装最新版本的 IM SDK

npm install @rongcloud/engine@latest @rongcloud/imlib-next@latest -S

步骤 2:初始化 SDK

创建 RongIMLib 实例。

// CMD
const RongIMLib = require('@rongcloud/imlib-next')

// ES
import * as RongIMLib from '@rongcloud/imlib-next'

在初始化方法中传入 App Key。请务必保证此过程只被执行一次。如果 App Key 不属于中国(北京)数据中心,必须在初始化配置中传入指定的导航服务器和统计服务器地址。

RongIMLib.init({ appkey: '<Your-AppKey>', navigators: ['https://nav.sg-light-edge.com'] });
  • 新加坡数据中心 Navi Server 地址:nav.sg-light-edge.com(主)、nav-b.sg-light-edge.com(备)

步骤 3:添加消息监听器

应用需要通过 SDK 提供的消息监听器接收消息与通知。[addEventListener] 方法用来接收来自于 IMLib 内的各种事件通知,同类型事件可以多次添加不同的监听函数。当前用户会通过该监听器接收所有类型的消息。

const Events = RongIMLib.Events
RongIMLib.addEventListener(Events.MESSAGES, (evt) => {
console.log(evt.messages)
})

步骤 4:建立 IM 连接

使用融云即时通讯功能前必须与融云服务器建立 IM 连接。建立 IM 连接时需要传入用户 Token。

建立 IM 时传入的用户 Token 表示用户在融云的唯一标识。您需要自行维护 App 用户注册流程,为用户分配唯一的用户标识(User ID),并使用该用户 ID 向融云申请建立 IM 连接所需使用的 Token。

步骤 4.1:获取 Token

客户端 SDK 不提供获取 Token 的 API。您需要通过融云服务端 API 获取 Token。

通过 App 层定义的用户 ID(userId)换取融云服务中使用的身份验证 Token。同一个用户 ID 可多次获取 Token,如果 Token 在有效期内,均可用于连接融云服务。同一用户 ID 如需重新获取 Token 使用同一接口。

调用融云服务端 API 必须进行身份验证。请在请求中添加以下 HTTP 标头(Header)字段:

  • App-Key: App Key
  • Nonce: 随机数
  • Timestamp: Unix 时间戳
  • Signature: 按以下顺序将 App Secret、Nonce、Timestamp 拼接成一个字符串,进行 SHA1 哈希计算。App Secret 与 App Key 对应,可从控制台 App Key 页面获取。

在获取 Token 时,HTTP 请求正文中需要传入用户 ID(userId)、名称(name)和头像(portraitUri)。

POST /user/getToken.json HTTP/1.1
Host: api.rong-api.com
App-Key: Your_AppKey
Nonce: 14314
Timestamp: 1408710653491
Signature: 45beb7cc7307889a8e711219a47b7cf6a5b000e8
Content-Type: application/x-www-form-urlencoded

userId=jlk456j5&name=Ironman&portraitUri=http%3A%2F%2Fabc.com%2Fmyportrait.jpg

用户 ID 支持大小写英文字母与数字的组合,最大长度 64 字节。注意,名称(name)和头像(portraitUri)仅供移动端远程推送时使用。在重新获取 Token 时如果传入新的数据,则会覆盖旧的名称与头像数据。

返回结果中会包含传入的用户 ID 与对应的 Token。Token 长度在 256 字节以内,您可以缓存在应用内。

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{"code":200, "userId":"jlk456j5", "token":"sfd9823ihufi"}

步骤 4.2:连接聊天服务器

在初始化完成后可建立 IM 连接,传入上一步中获取的用户 Token。

RongIMLib.connect('<Your-token>').then((res) => {
if (res.code === 0) {
console.log(res.data.userId)
}
})

一旦连接成功,SDK 的重连机制开始生效。当因为网络原因断线时,SDK 会不停重连直到连接成功为止,不需要您做额外的连接操作。

步骤 5:加入聊天室

在融云聊天室业务中,您需要先创建一个聊天室,并将用户加入聊天室,用户才能在聊天室中收发消息。

通常情况下,您通过服务端 API 创建聊天室,而用户一般通过客户端 SDK 加入聊天室。为了保持该教程的简单性,我们将直接调用客户端的创建并加入聊天室的接口 joinChatRoom,一次完成创建与加入聊天室的动作。

const chatRoomId = "chatroomId";
const count = -1;

RongIMLib.joinChatRoom(chatRoomId, {
count: count
}).then(res => {
// 加入聊天室成功
if (res.code === RongIMLib.ErrorCode.SUCCESS){
console.log(res.code)
} else {
console.log(res.code, res.msg)
}
}).catch(error => {
console.log(error)
})

count 变量的值表示加入聊天室时需要获取的历史消息数量,-1 表示加入聊天室不获取任何历史消息。

如果加入已存在的聊天室,可以调用 joinExistChatRoom 方法。

步骤 6:发送消息

发送消息需要使用 sendMessage 方法。请注意,客户端 SDK 发送消息存在频率限制,每秒最多只能发送 5 条消息。

发送普通消息:

// 定义消息投送目标会话, 这里定义一个聊天室类型会话
const conversation = { conversationType: RongIMLib.ConversationType.CHATROOM, targetId: '<目标 Id>' }
// 实例化待发送消息,RongIMLib.TextMessage 为内置文本型消息
const message = new RongIMLib.TextMessage({
// 文本内容
content: '文本内容',
})

发送媒体消息,本教程中以发送图片消息为例。该方法会先将图片、视频等媒体文件上传到融云默认的文件服务器(文件存储时长),上传成功之后再发送消息。

const conversation = {
conversationType: RongIMLib.ConversationType.CHATROOM,
targetId: 'chatroomId'
}
const msgBody = {
file, // 待上传文件
}
const hooks = {
onProgress (progress) {}, // 上传进度监听,可选
onComplete (fileInfo) { // 上传完成时的回调钩子,可选
console.log(fileInfo.url) // 文件存储地址
// 如果需要构建自定义消息,return new ABCMesssage('')
// ABCMesssage 定义通过自定义消息实现 `const ABCMesssage = RongIMLib.registerMessageType(...)`
// 无 return 返回值的情况下,SDK 默认发送 ImageMessage
}
}
const options = {
contentDisposition: 'inline' // 可选 'inline' | 'attachment',指定返回链接在浏览器中的展示形式,仅适用于海外数据中心的 App Key(使用 aws)
// ... 其他配置项,可选
},

RongIMLib.sendImageMessage(
conversation,
msgBody,
hooks,
options
).then(({ code, data: message }) => {
if (code === 0) {
// 发送成功
}
})

步骤 7:保存历史消息

开通聊天室消息云存储服务后,可将聊天室消息存储在融云服务端。客户端可以直接获取存储在服务端的消息。

const chatRoomId = "chatroomId";
const timestamp = 0;
const count = 10
const order = 0
RongIMLib.getChatroomHistoryMessages(chatRoomId, {
timestamp: timestamp,
count: count,
order: order
}).then(res => {
// 获取聊天室历史信息成功
if (res.code === 0){
console.log(res.code, res.data)
} else {
console.log(res.code, res.msg)
}
}).catch(error => {
console.log(error)
})

timestamp 为 Unix 时间戳,如果为 0 则表示获取当前最新时间点开始查询。order 表示查询顺序,默认为 0,表示获取发送时间 sentTime 早(小)于 timestamp 取值的消息。如果 order1,表示获取发送时间 sentTime 晚(大)于 timestamp 取值的消息。

步骤 8:撤回消息

如果 App 的管理员或者某普通用户希望在所有聊天室成员的聊天记录中删除一条消息,可使用撤回消息功能。消息成功撤回后,原始消息内容会在所有用户的本地与服务端历史消息记录中删除。

const conversation = {
conversationType: RongIMLib.ConversationType.CHATROOM,
targetId: 'chatroomId',
}
RongIMLib.recallMessage(conversation, {
messageUId: 'BS4O-QEBR-VJM6-9GPP',
sentTime: 1632728573423,
})
.then((res) => {
if (res.code === 0) {
console.log(res.code, res.data)
} else {
console.log(res.code, res.msg)
}
})
.catch((error) => {
console.log(error)
})

步骤 9:封禁用户

即时通讯业务支持多种封禁与禁言能力。客户端不提供相关的 API,您可以通过服务端 API 实现。

封禁指定用户

对 App 用户进行封禁处理,单次请求最多封禁 20 个用户 ID(userId)。minute 参数代表封禁时长,最长封禁 43200 分钟。一旦封禁,被封禁用户立即断开 IM 连接。被封禁期间用户无法与融云建立 IM 连接,无法主动使用 IM 服务。

  • 封禁:

    POST /user/block.json HTTP/1.1
    Host: api.rong-api.com
    App-Key: uwd1c0sxdlx2
    Nonce: 14314
    Timestamp: 1408710653491
    Signature: 45beb7cc7307889a8e711219a47b7cf6a5b000e8
    Content-Type: application/x-www-form-urlencoded

    userId=UserA&minute=10
  • 解除封禁:

    POST /user/unblock.json HTTP/1.1
    Host: api.rong-api.com
    App-Key: uwd1c0sxdlx2
    Nonce: 14314
    Timestamp: 1408710653491
    Signature: 45beb7cc7307889a8e711219a47b7cf6a5b000e8
    Content-Type: application/x-www-form-urlencoded

    userId=UserA

禁言聊天室用户

聊天室业务支持禁言用户功能,单次可设置最多 20 个用户(userId)在指定聊天室(chatroomId)中禁言。minute 参数代表禁言时长,最长封禁 43200 分钟。被禁言用户可以接收查看聊天室中其他用户聊天信息,但不能通过客户端 SDK 往该聊天室内发送消息。用户退出聊天室不会使禁言状态失效。

  • 禁言

    POST /chatroom/user/gag/add.json HTTP/1.1
    Host: api.rong-api.com
    App-Key: uwd1c0sxdlx2
    Nonce: 14314
    Timestamp: 1408710653491
    Signature: 45beb7cc7307889a8e711219a47b7cf6a5b000e8
    Content-Type: application/x-www-form-urlencoded

    userId=UserA&chatroomId=16&minute=1
  • 解除用户禁言:

    POST /chatroom/user/gag/rollback.json HTTP/1.1
    Host: api.rong-api.com
    App-Key: uwd1c0sxdlx2
    Nonce: 14314
    Timestamp: 1408710653491
    Signature: 45beb7cc7307889a8e711219a47b7cf6a5b000e8
    Content-Type: application/x-www-form-urlencoded

    userId=UserA&chatroomId=16

禁言聊天室

聊天室业务支持将指定聊天室(chatroomId)禁言。禁言后,该聊天室中的所有用户均不能通过客户端 SDK 往该聊天室内发送消息。如需允许部分例外用户,可将用户加入聊天室禁言用户白名单(不在本教程范围内)。如果聊天室解散,全体禁言数据会被清除。

  • 禁言聊天室

    POST /chatroom/ban/add.json HTTP/1.1
    Host: api.rong-api.com
    App-Key: uwd1c0sxdlx2
    Nonce: 14314
    Timestamp: 1408710653491
    Signature: 45beb7cc7307889a8e711219a47b7cf6a5b000e8
    Content-Type: application/x-www-form-urlencoded

    chatroomId=123
  • 取消聊天室成员全体禁言:

    POST /chatroom/ban/rollback.json HTTP/1.1
    Host: api.rong-api.com
    App-Key: uwd1c0sxdlx2
    Nonce: 14314
    Timestamp: 1408710653491
    Signature: 45beb7cc7307889a8e711219a47b7cf6a5b000e8
    Content-Type: application/x-www-form-urlencoded

    chatroomId=123

聊天室业务还支持将指定用户在应用下的所有聊天室中禁言,支持设置禁言时长。在禁言时间段内,被禁言用户在应用下的所有聊天室中都无法通过客户端 SDK 发送消息。该功能要求开通聊天室全局禁言服务。本教程暂不做介绍。

附录:如何实现聊天室点赞

您可以用自定义消息实现聊天室内点赞功能。

  1. 在调用 connect 方法前,向 SDK 注册 XappChatroomLike

    const XappChatRoomLike = RongIMLib.registerMessageType('Xapp:Chatroom:Like', true, true, [], false)
  2. 在需要点赞时,构造点赞消息,使用 sendMessage 方法发送。

    // 构建要发送的自定义消息
    const message = new XappChatroomLike()

    // 发送消息
    RongIMLib.sendMessage({
    conversationType: RongIMLib.ConversationType.CHATROOM,
    targetId: 'chatroomId'
    }, message).then(res => {
    if (res.code === 0) {
    console.log(res.code, res.data)
    } else {
    console.log(res.code)
    }
    })
  3. 聊天室内其他用户接收消息时,判断是否为 XappChatroomLike。如果接到点赞消息,可以在 UI 上展示点赞效果。

    RongCoreClient.addOnReceiveMessageListener(
    new OnReceiveMessageWrapperListener() {
    @Override
    public boolean onReceivedMessage(Message message, int left, boolean hasPackage, boolean offline) {
    MessageContent msgContent = message.getContent();
    if (msgContent instanceof XappChatroomLike) {

    }
    return false;
    }
    });