本文详细介绍如何建立一个简单的项目并使用声网 RTM SDK 实现消息发送与接收。
登录 RTM 系统包括以下流程:
发送和接收点对点消息包括以下流程:
发送和接收频道消息包括以下流程:
参考以下步骤创建一个声网项目:
声网会给每个项目自动分配一个 App ID 作为项目唯一标识。
在声网控制台的项目管理页面,找到你的项目,点击 App ID 右侧的 图标,即可获取项目的 App ID。
参考以下步骤获取 App 证书:
在声网控制台的项目管理页面,找到你的项目,点击配置。
点击主要证书下面的复制图标,即可获取项目的 App 证书。
为提高项目的安全性,声网推荐使用 Token 对即将登录 RTM 系统的用户进行鉴权。
为了方便测试,声网服务器提供部署签发 RTM Token 的功能。参考以下步骤获取 RTM Token:
login
时,请确保填入的用户 ID 与生成 RTM Token 时填入的用户 ID 一致。新建一个目录 RTM_quickstart
。在目录下运行 npm init
创建一个 package.json
文件,然后创建以下文件
index.html
index.js
此时你的目录中包含以下文件:
RTM_quickstart
├─ index.html
├─ index.js
└─ package.json
你可以选择以下方法集成 SDK。本示例使用 npm 进行集成。
下载声网 RTM SDK for Web。将 libs
中的 JS 文件保存到你的项目下。
在 HTML 文件中,对 JS 文件进行引用。
<script src="path to the JS file"></script>
(可选)你可以通过下面的步骤开启智能提示和类型检查:
将压缩包中路径为 libs/agora-rtm-sdk.d.ts
的文件保存到你所操作的项目下。
在你的 JS 或 TS 文件开头加入下面的注释(其中 path to the TS file
替换为 agora-rtm-sdk.d.ts
的路径):
/// <reference path="path to the TS file" />
在 package.json
中的 dependencies
字段中加入 agora-rtm-sdk
及对应版本:
{
"name": "web",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
"agora-rtm-sdk": "latest"
},
"author": "",
"license": "ISC"
}
在你的 JS 或 TS 文件中导入 AgoraRTM
模块:
import AgoraRTM from 'agora-rtm-sdk'
index.html
的内容如下。<script src="./dist/bundle.js"></script>
用来引用 webpack 打包之后的bundle.js
文件。webpack 的配置会在后续步骤提及。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>RTM Quickstart</title>
<script src="./dist/bundle.js"></script>
</head>
<body>
<h1 class="left-align">RTM Quickstart</h1>
<form id="loginForm">
<div class="col" style="min-width: 433px; max-width: 443px">
<div class="card" style="margin-top: 0px; margin-bottom: 0px;">
<div class="row card-content" style="margin-bottom: 0px; margin-top: 10px;">
<div class="input-field">
<label>User ID</label>
<input type="text" placeholder="User ID" id="userID">
</div>
<div class="row">
<div>
<button type="button" id="login">LOGIN</button>
<button type="button" id="logout">LOGOUT</button>
</div>
</div>
<div class="input-field">
<label>Channel name: demoChannel</label>
</div>
<div class="row">
<div>
<button type="button" id="join">JOIN</button>
<button type="button" id="leave">LEAVE</button>
</div>
</div>
<div class="input-field channel-padding">
<label>Channel Message</label>
<input type="text" placeholder="channel message" id="channelMessage">
<button type="button" id="send_channel_message">SEND</button>
</div>
<div class="input-field">
<label>Peer Id</label>
<input type="text" placeholder="peer id" id="peerId">
</div>
<div class="input-field channel-padding">
<label>Peer Message</label>
<input type="text" placeholder="peer message" id="peerMessage">
<button type="button" id="send_peer_message">SEND</button>
</div>
</div>
</div>
</div>
</form>
<hr>
<div id="log"></div>
</body>
</html>
index.js
的内容如下。本文使用 import 的方法导入 SDK,并使用 webpack 对 JS 文件进行打包,以避免浏览器兼容性问题。你需要分别将代码中的 "<Your app ID>"
和 "<Your token>"
替换为你之前获取的 App ID 和 Token。
import AgoraRTM from 'agora-rtm-sdk'
// login 方法参数
let options = {
uid: "",
token: ""
}
// 你的 app ID
const appID = "<Your app ID>"
// 你的 token
options.token = "<Your token>"
// 初始化客户端
const client = AgoraRTM.createInstance(appID)
// 客户端事件监听
// 显示对端发送的消息
client.on('MessageFromPeer', function (message, peerId) {
document.getElementById("log").appendChild(document.createElement('div')).append("Message from: " + peerId + " Message: " + message)
})
// 显示连接状态变化
client.on('ConnectionStateChanged', function (state, reason) {
document.getElementById("log").appendChild(document.createElement('div')).append("State changed To: " + state + " Reason: " + reason)
})
let channel = client.createChannel("demoChannel")
channel.on('ChannelMessage', function (message, memberId) {
document.getElementById("message").appendChild(document.createElement("div")).append(memberId + ": " + message.text);
})
// 显示频道
channel.on('MemberJoined', function (memberId) {
document.getElementById("log").appendChild(document.createElement('div')).append(memberId + " joined the channel")
})
// 频道成员
channel.on('MemberLeft', function (memberId) {
document.getElementById("log").appendChild(document.createElement('div')).append(memberId + " left the channel")
})
// 按钮行为定义
window.onload = function () {
// 按钮逻辑
// 登录
document.getElementById("login").onclick = async function () {
options.uid = document.getElementById("userID").value.toString()
await client.login(options)
}
// 登出
document.getElementById("logout").onclick = async function () {
await client.logout()
}
// 创建并加入频道
document.getElementById("join").onclick = async function () {
// Channel event listeners
// Display channel messages
await channel.join().then (() => {
document.getElementById("log").appendChild(document.createElement('div')).append("You have successfully joined channel " + channel.channelId)
})
}
// 离开频道
document.getElementById("leave").onclick = async function () {
if (channel != null) {
await channel.leave()
}
else
{
console.log("Channel is empty")
}
}
// 发送点对点消息
document.getElementById("send_peer_message").onclick = async function () {
let peerId = document.getElementById("peerId").value.toString()
let peerMessage = document.getElementById("peerMessage").value.toString()
await client.sendMessageToPeer(
{ text: peerMessage },
peerId,
).then(sendResult => {
if (sendResult.hasPeerReceived) {
document.getElementById("log").appendChild(document.createElement('div')).append("Message has been received by: " + peerId + " Message: " + peerMessage)
} else {
document.getElementById("log").appendChild(document.createElement('div')).append("Message sent to: " + peerId + " Message: " + peerMessage)
}
})
}
// 发送频道消息
document.getElementById("send_channel_message").onclick = async function () {
let channelMessage = document.getElementById("channelMessage").value.toString()
if (channel != null) {
await channel.sendMessage({ text: channelMessage }).then(() => {
document.getElementById("log").appendChild(document.createElement('div')).append("Channel message: " + channelMessage + " from " + channel.channelId)
}
)
}
}
}
本文使用 webpack 对项目进行打包,并使用 webpack-dev-server
运行项目。
在 package.json
的 dependencies
字段中添加 webpack
,webpack-cli
,webpack-dev-server
。并在 scripts
字段中增加 build
和 start:dev
命令。
{
"name": "web",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "webpack --config webpack.config.js",
"start:dev": "webpack serve --open --config webpack.config.js"
},
"dependencies": {
"agora-rtm-sdk": "latest",
"webpack": "5.28.0",
"webpack-dev-server": "3.11.2",
"webpack-cli": "4.5.0"
},
"author": "",
"license": "ISC"
}
在项目根目录添加 webpack.config.js
文件,用于配置 webpack。文件内容如下:
const path = require('path');
module.exports = {
entry: './index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, './dist'),
},
devServer: {
compress: true,
port: 9000
}
};
此时你的目录中包含以下文件:
RTM_quickstart
├─ index.html
├─ index.js
├─ package.json
└─ webpack.config.js
在项目根目录运行以下命令,安装依赖项。
$ npm install
运行以下命令使用 webpack 构建并运行项目。
# 使用 webpack 打包
$ npm run build
# 使用 webpack-dev-server 运行项目
$ npm run start:dev
运行成功后,你可以发送和接收点对点消息和频道消息。
RTM 支持多个相互独立的 RtmClient 实例。
在收发点对点消息或进行其他频道操作前,请确保你已成功登录声网 RTM 系统。
使用频道核心功能前必须通过调用 createChannel 方法创建频道实例。
你可以创建多个 RtmClient 客户端实例,但是每个客户端实例最多只能同时加入 20 个频道。每个频道的 channelId
参数应该不同。
当你不再使用某个实例时,可以通过调用继承的 removeAllListeners
方法删除它的所有监听函数。
接收到的 RtmMessage 消息对象不能重复利用再用于消息发送。
我们在 GitHub 上提供一个开源的示例项目供你参考。
同时,你可以通过我们的在线 Web 应用快速体验声网云信令相关功能。