本文详细介绍如何建立一个简单的项目并使用声网 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.htmlindex.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 应用快速体验声网云信令相关功能。