互动消息是用于加强直播间消息沟通、提升交互体验的服务。提供了丰富、易集成的SDK,可在用户开发的直播应用中轻松集成评论、弹幕、点赞等能力。本文介绍Web端集成互动消息的操作步骤。
前提条件
客户端集成前,请确保已经完成服务端集成,并提供客户端访问的获取鉴权Token的接口。服务端集成操作指引,请参见服务端集成。
浏览器支持
Web端SDK依赖浏览器对WebRTC技术的支持,支持的浏览器版本如下:
Chrome 63+
Firefox 62+
Opera 50+
Edge 79+
Safari 11+
集成SDK
在script标签中引入SDK。
<script src="https://g.alicdn.com/apsara-media-box/imp-interaction/1.3.2/alivc-im.iife.js"></script>
使用以下文件为SDK增加类型定义,提升开发体验。下载地址参见alivc-im.iife.d.ts.zip。
使用SDK
SDK使用需遵循如下操作顺序:
初始化
登录
相关操作
登出
反初始化
其中相关操作包含群组操作和消息操作,详细说明如下:
SDK操作
群组操作
创建群组(需要以管理员身份进行登录才能操作)
关闭群组(仅限群主/群管理员操作)
进入群组
离开群组
查询群组信息
修改群组信息(仅限群主/群管理员操作)
查询群组最近成员列表
查询群组全部成员(仅限群主/群管理员操作)
对群组进行禁言(仅限群主/群管理员操作)
对群组取消禁言(仅限群主/群管理员操作)
对群组的用户进行禁言(仅限群主/群管理员操作)
对群组的用户取消禁言(仅限群主/群管理员操作)
查询群组内被禁言的用户列表(仅限群主/群管理员操作)
消息操作
单发消息
群发消息
查询最近群发消息列表
查询全部群发消息(仅限群主/群管理员操作)
删除/撤回群消息
查询历史消息
注意事项
各ID需遵循以下规则:
appid :最长64位,仅限于A~Z,a~z, 0~9及“-”, 不能包含其他字符
userid:最长64位,仅限于A~Z,a~z, 0~9及“-”, 不能包含其他字符
groupid:最长64位,仅限于A~Z,a~z, 0~9及“-”, 不能包含其他字符
初始化
使用前需要进行初始化,可以在相关业务模块的主入口设置。
示例代码
const { ImEngine, ImLogLevel } = AliVCInteraction;
// 获取引擎单例
const engine = ImEngine.createEngine();
try {
await engine.init({
deviceId: "xxxx", // 设备ID,可选传入
appId: "APP_ID", // 开通应用后可以在控制台上拷贝
appSign: "APP_SIGN", // 开通应用后可以在控制台上拷贝
logLevel: ImLogLevel.ERROR, // 日志级别,调试时使用 ImLogLevel.DBUG
});
// 需确认init异步操作成功后,才可以继续执行login等操作
// 初始化成功,监听事件
// 处理回调事件 AliVCIMEngineListenerProtocol
engine.on("connecting", () => {
console.log("connecting");
});
engine.on("connectfailed", (err) => {
console.log(`connect failed: ${err.message}`);
});
engine.on("connectsuccess", () => {
console.log("connect success");
});
engine.on("disconnect", (code: number) => {
console.log(`disconnect: ${code}`);
});
engine.on("tokenexpired", async (cb) => {
console.log("token expired");
// 这里需要更新为获取新的登录信息的代码
const auth = await getLoginAuth();
cb(null, {
timestamp: 22123123, // 服务端返回timestamp值
nonce: 'nonce', // 服务端返回nonce值
role: 'admin', // 是否为admin角色,如果不需要可以设置为空
token: 'xxx' // 服务端返回token值
});
});
} catch (error) {
// init 错误码含义
// 1001:重复初始化、1002:创建底层引擎失败、-1:底层重复初始化、-2:初始化配置信息有误
console.log(`Init Fail: code:${error.code}, message: ${error.msg}`);
}
登录
登录需要鉴权信息,请确保已完成前提条件设置,并已通过服务端获取到了鉴权信息,包括timestamp、nonce、token等值。
示例代码
// 请确保init异步操作成功后,再执行此操作
await engine.login({
user: {
userId: 'abc', // 当前app登录的用户id
userExtension: '{}', // 用户扩展信息,可以是头像、昵称等封装为json字符串
},
userAuth: {
timestamp: 22123123, // 服务端返回timestamp值
nonce: 'nonce', // 服务端返回nonce值
role: 'admin', // 是否为admin角色,如果不需要可以设置为空
token: 'xxx' // 服务端返回token值
},
});
群组操作
以下操作需要确保login异步操作成功后,方可执行。
获取群组管理器
// 必须确保已经初始化,否则会返回空值
const groupManager = engine.getGroupManager();
添加和移除群组操作监听器
// 在适当的时机(例如进入房间后,且完成登录后)添加群组操作事件监听器
groupManager.on('exit', (groupId: string, reason: number) => {
// 退出群组
console.log(`group ${groupId} close, reason: ${reason}`);
})
groupManager.on('memberchange', (groupId: string, memberCount: number, joinUsers: ImUser[], leaveUsers: ImUser[]) => {
// 有人进入或离开群组
console.log(`group ${groupId} member change, memberCount: ${memberCount}, joinUsers: ${joinUsers.map(u => u.userId).join(',')}, leaveUsers: ${leaveUsers.map(u => u.userId).join('')}`);
})
groupManager.on('mutechange', (groupId: string, status) => {
// 群组的禁言状态发生了变化
console.log(`group ${groupId} mute change`);
})
groupManager.on('infochange', (groupId: string, info) => {
// 有人离开了群组
console.log(`group ${groupId} info change`);
})
// 如需移除监听某个事件,请使用 off 方法取消对应的事件
groupManager.off('infochange');
// 如需移除监听所有事件,则使用 removeAllListeners 方法
groupManager.removeAllListeners();
创建群组
需要以管理员身份进行登录才能调用成功。
await groupManager.createGroup({
groupId: '', // 群组ID,为空时,系统创建新群组后会返回唯一ID
groupName: 'xxx', // 群组昵称,一定要设置,否则会失败
groupMeta: 'xxx' // 群组扩展信息,如果有多个字段可以考虑封装为JSON字符串
});
关闭群组
仅限群主/群管理员调用,否则会调用失败。
// 参数为 groupId
await groupManager.closeGroup('xxx');
进入群组
// 参数为 groupId
await groupManager.joinGroup('xxx');
离开群组
// 参数为 groupId
await groupManager.leaveGroup('xxx');
查询群组信息
// 参数为 groupId
const groupInfo = await groupManager.queryGroup('xxx');
修改群组信息
支持修改群扩展信息和设置管理员,仅限群主/群管理员调用,否则会调用失败。
await groupManager.modifyGroup({
groupId: 'xxx', // 群组ID
forceUpdateAdmins: true, // 是否强制修改群管理员
admins: ['xxx'], // 群管理员ID 列表,需要清空时传空数组且 forceUpdateAdmins 传 true
forceUpdateGroupMeta: true, // 是否强制修改群扩展信息
groupMeta: 'xxx' // 群信息扩展信息Meta,需要清空时传空字符串且 forceUpdateGroupMeta 传 true
});
查询群组最近成员列表
// 参数为 groupId
const recentGroupUserInfo = groupManager.listRecentGroupUser(groupId);
查询群组全部成员
仅限群主/群管理员调用,否则会调用失败。
const recentGroupUserInfo = groupManager.listGroupUser({
groupId: 'xxx', // 群组ID
nextpagetoken: 12, // 默认表示第一页,遍历时服务端会返回,客户端获取下一页时,应带上
pageSize: 10, // 最大不超过50
sortType: ImSortType.ASC // 排序方式,ASC-先加入优先,DESC-后加入优先
});
对群组进行禁言
仅限群主/群管理员调用,否则会调用失败。
// 参数为 groupId
await groupManager.muteAll('xxx');
对群组取消禁言
仅限群主/群管理员调用,否则会调用失败。
// 参数为 groupId
await groupManager.cancelMuteAll('xxx');
对群组的用户进行禁言
仅限群主/群管理员调用,否则会调用失败。
await groupManager.muteUser({
groupId: 'xxx', // 群组ID
userList: ['xxx'] // 需要禁言的用户ID列表
});
对群组的用户取消禁言
仅限群主/群管理员调用,否则会调用失败。
await groupManager.cancelMuteUser({
groupId: 'xxx', // 群组ID
userList: ['xxx'] // 需要取消禁言的用户ID列表
});
查询群组内被禁言的用户列表
仅限群主/群管理员调用,否则会调用失败。
// 参数为 groupId
const muteUsersInfo = await groupManager.listMuteUsers('xxx');
消息操作
获取消息管理器
// 必须确保已经初始化,否则会返回空值
const messageManager = await engine.getMessageManager();
添加和移除消息操作监听器
// 收到其他用户发来的单聊消息
messageManager.on("recvc2cmessage", (msg) => {
console.log('recvc2cmessage', msg);
});
// 收到群聊消息
messageManager.on("recvgroupmessage", (msg, groupId) => {
console.log('recvgroupmessage', msg, groupId);
});
// 群消息删除
messageManager.on('deletegroupmessage', (msgId, groupId) => {
console.log(`group ${groupId} delete message ${msgId}`)
});
// 如需移除监听某个事件,请使用 off 方法取消对应的事件
messageManager.off('recvgroupmessage');
// 如需移除监听所有事件,则使用 removeAllListeners 方法
messageManager.removeAllListeners();
单发消息
try {
const messageId = await messageManager.sendC2cMessage({
receiverId: 'xxx', // 接受者id
data: 'xxx', // 发送消息内容,如果是结构化可考虑使用JSON字符串
type: 88888, // 自定义消息类型,需大于10000
skipAudit: false, // 可选(默认 false),跳过安全审核,true:发送的消息不经过阿里云安全审核服务审核;false:发送的消息经过阿里云安全审核服务审核,审核失败则不发送。
level: ImMessageLevel.NORMAL // 可选(默认 NORMAL), 消息分级,需要高可靠时,使用 ImMessageLevel.HIGH
});
console.log('send success, messageId: ', messageId);
} catch (error) {
// error.code 为 424 时为对方未在线,建议待对方上线后再重发
console.log('send fail', error);
}
群发消息
// 发群组消息前请确保已加入群组
try {
const messageId = await messageManager.sendGroupMessage({
groupId: 'xxx', // 群组id
data: 'xxx', // 发送消息内容,如果是结构化可考虑使用json字符串
type: 88888, // 自定义消息类型,需大于10000
skipAudit: false, // 可选(默认 false),跳过安全审核,true:发送的消息不经过阿里云安全审核服务审核;false:发送的消息经过阿里云安全审核服务审核,审核失败则不发送。
skipMuteCheck: false, // 可选(默认 false),跳过禁言检测,true:忽略被禁言用户,还可发消息;false:当被禁言时,消息无法发送
level: ImMessageLevel.NORMAL, // 可选(默认 NORMAL), 消息分级,需要高可靠时,使用 ImMessageLevel.HIGH
noStorage: true, // 可选(默认 false)true:表示该消息不需要存储,也无法拉取查询;false:消息进行存储,可以拉取查询。如果在直播间的弹幕场景,需要设置为 false。
repeatCount: 1 // 可选(默认 1)本消息重复数量,内容完成一样的消息可以使用该字段进行聚合,并发送一次即可。
});
console.log('send success, messageId: ', messageId);
} catch (error) {
// error.code 为 425 时为未加入群组
console.log('send fail', error);
}
删除/撤回群消息
// 删除/撤回群组消息前请确保已加入群组
await messageManager.deleteMessage({
groupId: 'xxx', // 群组id
messageId: 'xxx', // 需要删除的消息 id
});
查询最近群发消息列表
// 查询群发消息列表前请确保已加入群组
const messagesInfo = await messageManager.listRecentMessage({
groupId: 'xxx', // 群组id
})
加入群组后,调用该接口可返回最近50条消息,所有类型的用户均可调用。
查询全部群发消息列表
仅限群主/群管理员调用,否则会调用失败。普通用户建议使用listRecentMessage接口获取最近50条消息。
// ImSortType.ASC 正序,ImSortType.DESC 倒序
// 查询全部群发消息列表前请确保已加入群组
const { ImSortType } = window.AliVCInteraction;
// 需要先调用 engine.getMessageManager 方法得到 messageManager 对象
const messageList = await messageManager.listMessage({
groupId: 'xxx', // 群组ID
type: 88888, // 自定义消息类型,需大于10000
nextPageToken: 12, // 不传时表示第一页,遍历时服务端会返回下一页Token,客户端获取下一页时应带上
pageSize: 10, // 默认10条,最大30条
sortType: ImSortType.ASC // 排序方式,默认为时间递增
});
查询历史消息
// ImSortType.ASC 正序,ImSortType.DESC 倒序
const { ImSortType } = window.AliVCInteraction;
// 需要先调用 engine.getMessageManager 方法得到 messageManager 对象
const messageList = messageManager.listHistoryMessage({
groupId: 'xxx', // 群组ID
type: 88888, // 消息类型,自定义消息类型需大于10000
nextPageToken: 12, // 可选,不传时表示第一页,遍历时服务端会返回下一页Token,客户端获取下一页时应带上
pageSize: 10, // 默认10条,最大30条
sortType: ImSortType.ASC, // 排序方式,默认为时间递增
beginTime: 0, // 可选(默认 0),开始时间,秒级时间戳
endTime: 0 // 可选(默认 0),结束时间,秒级时间戳
});
登出
await engine.logout();
反初始化
登出后如无需再进行登录,可以进行反初始化操作,SDK会对底层操作实例进行释放。
engine.unInit()
快速体验
前提条件
快速体验demo需要您的开发环境启动一个 HTTP 服务,如果您没有安装http-server
的npm包,可以先执行npm install --global http-server
指令全局安装。
步骤一:创建目录
创建一个demo文件夹,并按照下方文件目录结构创建好quick.html
、quick.js
两个文件。
- demo
- quick.html
- quick.js
步骤二:编辑quick.html
将下方代码复制到quick.html,并保存。
示例代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>互动消息 quick start</title>
<link rel="stylesheet" href="https://g.alicdn.com/code/lib/bootstrap/5.3.0/css/bootstrap.min.css" />
</head>
<body class="container">
<h1 class="mt-2">互动消息 quick start</h1>
<div class="toast-container position-fixed top-0 end-0 p-3">
<div id="loginToast" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
<div class="toast-header">
<strong class="me-auto">登录消息</strong>
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
<div class="toast-body" id="loginToastBody"></div>
</div>
</div>
<div class="row mt-3">
<div class="col-6">
<form id="loginForm">
<div class="form-group mb-2">
<label for="userId" class="form-label">用户ID</label>
<input class="form-control form-control-sm" id="userId" placeholder="请输入英文字母或数字" />
</div>
<div class="form-group mb-2">
<label for="groupId" class="form-label">群组ID</label>
<input class="form-control form-control-sm" id="groupId" placeholder="加入群组前请确认是否已存在,不存在先创建" />
</div>
<div class="mb-2">
<button id="loginBtn" type="button" class="btn btn-primary btn-sm">登录</button>
<button id="joinBtn" type="button" class="btn btn-primary btn-sm">加入群组</button>
<button id="createBtn" type="button" class="btn btn-primary btn-sm">创建群组</button>
<button id="leaveBtn" type="button" class="btn btn-secondary btn-sm" disabled>离开群组</button>
<button id="logoutBtn" type="button" class="btn btn-secondary btn-sm" disabled>登出</button>
</div>
<p class="mb-2">假如群组ID已存在,可以一键登录+加入群组</p>
<div class="mb-2">
<button id="oneLoginBtn" type="button" class="btn btn-primary btn-sm">一键登录+加入群组</button>
<button id="oneLogoutBtn" type="button" class="btn btn-secondary btn-sm" disabled>一键离开群组+登出</button>
</div>
</form>
<form id="msgForm" action="#" class="mt-4">
<div class="form-group mb-2">
<label for="msgText" class="form-label">消息</label>
<input class="form-control form-control-sm" id="msgText" />
</div>
<div class="mb-2">
<button id="sendBtn" type="button" class="btn btn-primary btn-sm" disabled>发送</button>
</div>
</form>
</div>
<div class="col-6">
<h5>
消息展示
<button id="clearBtn" type="button" class="btn btn-secondary btn-sm float-end">清空</button>
</h5>
<div id="msgList" class="mt-4"></div>
</div>
</div>
<script src="https://g.alicdn.com/code/lib/jquery/3.7.1/jquery.min.js"></script>
<script src="https://g.alicdn.com/code/lib/bootstrap/5.3.0/js/bootstrap.min.js"></script>
<script crossorigin="anonymous" src="https://g.alicdn.com/apsara-media-box/imp-interaction/1.3.2/alivc-im.iife.js"></script>
<script src="./quick.js"></script>
</body>
</html>
步骤三:编辑quick.js
将下方代码复制到quick.js,并将AppId、AppKey、AppSign粘贴至代码指定变量中保存。
示例代码
// 请从控制台复制对应的值填入下面 AppId、 AppKey、AppSign 变量当中
// 注意:这里仅作为本地快速体验使用,实际开发请勿在前端泄露 AppKey
const AppId = '';
const AppKey = '';
const AppSign = '';
const { ImEngine, ImLogLevel, ImMessageLevel } = window.AliVCInteraction;
// 获取引擎单例
const engine = ImEngine.createEngine();
let groupManager;
let messageManager;
let joinedGroupId;
const sha256 = async (message) => {
// Convert the message string to an ArrayBuffer
const encoder = new TextEncoder();
const data = encoder.encode(message);
// Calculate the hash using the subtle crypto API
const result = await crypto.subtle.digest('SHA-256', data).then((buffer) => {
// Convert the ArrayBuffer to a hexadecimal string
let hash = Array.prototype.map.call(new Uint8Array(buffer), (x) => ('00' + x.toString(16)).slice(-2)).join('');
return hash;
});
return result;
};
const getLoginAuth = async (userId, role) => {
const nonce = 'AK_4';
const timestamp = Math.floor(Date.now() / 1000) + 3600 * 3;
const pendingShaStr = `${AppId}${AppKey}${userId}${nonce}${timestamp}${role}`;
const appToken = await sha256(pendingShaStr);
return {
nonce,
timestamp,
token: appToken,
role,
};
};
function showToast(baseId, message) {
$(`#${baseId}Body`).text(message);
const toast = new bootstrap.Toast($(`#${baseId}`));
toast.show();
}
function showMessage(text) {
$('#msgList').append(`<div class="mb-2">${text}</div>`);
}
function listenEngineEvents() {
// 处理回调事件 AliVCIMEngineListenerProtocol
engine.on("connecting", () => {
console.log("connecting");
});
engine.on("connectfailed", (err) => {
console.log(`connect failed: ${err.message}`);
});
engine.on("connectsuccess", () => {
console.log("connect success");
});
engine.on("disconnect", (code) => {
console.log(`disconnect: ${code}`);
});
engine.on("tokenexpired", async (cb) => {
console.log("token expired");
// 这里需要更新为获取新的登录信息的代码
// const auth = await getLoginAuth(userId, role);
// cb(null, auth);
});
}
function listenGroupEvents() {
if (!groupManager) {
return;
}
// 在适当的时机(例如进入房间后,且完成登录后)添加群组操作事件监听器
groupManager.on('exit', (groupId, reason) => {
// 退出群组
showMessage(`group ${groupId} close, reason: ${reason}`);
})
groupManager.on('memberchange', (groupId, memberCount, joinUsers, leaveUsers) => {
// 有人进入或离开群组
showMessage(`group ${groupId} member change, memberCount: ${memberCount}, joinUsers: ${joinUsers.map(u => u.userId).join(',')}, leaveUsers: ${leaveUsers.map(u => u.userId).join('')}`);
})
groupManager.on('mutechange', (groupId, status) => {
// 群组的禁言状态发生了变化
showMessage(`group ${groupId} mute change`);
})
groupManager.on('infochange', (groupId, info) => {
// 有人离开了群组
showMessage(`group ${groupId} info change`);
})
}
function listenMessageEvents() {
if (!messageManager) {
return;
}
// 收到群聊消息
messageManager.on("recvgroupmessage", (msgData, groupId) => {
console.log('recvgroupmessage', msgData, groupId);
showMessage(`receive group: ${msgData.groupId}, type: ${msgData.type}, data: ${msgData.data}`);
});
}
async function login(userId) {
// 先初始化,注意别忘了加 await
await engine.init({
deviceId: "xxxx", // 设备ID,可选传入
appId: AppId, // 开通应用后可以在控制台上拷贝
appSign: AppSign, // 开通应用后可以在控制台上拷贝
logLevel: ImLogLevel.ERROR, // 日志级别,调试时使用 ImLogLevel.DBUG
});
// 初始化成功,监听事件
listenEngineEvents();
const role = 'admin'; // 是否为admin角色,如果不需要可以设置为空
// 获取登录信息
const authData = await getLoginAuth(userId, role);
// 初始化成功再登录,注意别忘了加 await
await engine.login({
user: {
userId, // 当前app登录的用户id
userExtension: '{}', // 用户扩展信息,可以是头像、昵称等封装为json字符串
},
userAuth: {
timestamp: authData.timestamp, // 服务端返回timestamp值
nonce: authData.nonce, // 服务端返回nonce值
role: authData.role, // 是否为admin角色,如果不需要可以设置为空
token: authData.token, // 服务端返回token值
},
});
// 必须确保已经初始化,否则会返回空值
groupManager = engine.getGroupManager();
messageManager = engine.getMessageManager();
}
async function logout() {
await engine.logout();
engine.unInit();
groupManager = undefined;
messageManager = undefined;
}
async function joinGroup(groupId) {
if (!groupManager) {
return;
}
await groupManager.joinGroup(groupId);
joinedGroupId = groupId;
listenGroupEvents();
listenMessageEvents();
}
async function leaveGroup() {
if (!groupManager || !joinedGroupId) {
return;
}
await groupManager.leaveGroup(joinedGroupId);
groupManager.removeAllListeners();
messageManager.removeAllListeners();
}
$('#loginBtn').click(() => {
const userId = $('#userId').val();
if (!userId) {
return;
}
login(userId)
.then(() => {
console.log('初始化、登录成功');
showToast('loginToast', '初始化、登录成功');
$('#loginBtn').prop('disabled', true);
$('#logoutBtn').prop('disabled', false);
})
.catch((err) => {
console.log('初始化、登录失败', err.code, err.msg);
});
});
$('#oneLoginBtn').click(async () => {
const userId = $('#userId').val();
const groupId = $('#groupId').val();
if (!userId || !groupId) {
return;
}
try {
await login(userId);
showToast('loginToast', '初始化、登录成功');
$('#loginBtn').prop('disabled', true);
$('#logoutBtn').prop('disabled', false);
await joinGroup(groupId);
showMessage(`加入群组 ${groupId} 成功`);
$('#joinBtn').prop('disabled', true);
$('#leaveBtn').prop('disabled', false);
$('#sendBtn').prop('disabled', false);
$('#oneLoginBtn').prop('disabled', true);
$('#oneLogoutBtn').prop('disabled', false);
} catch (error) {
console.log('一键登录+加入群组', err.code, err.msg);
}
});
$('#joinBtn').click(() => {
const groupId = $('#groupId').val();
if (!groupId || !groupManager) {
return;
}
joinGroup(groupId)
.then(() => {
showMessage(`加入群组 ${groupId} 成功`);
$('#joinBtn').prop('disabled', true);
$('#leaveBtn').prop('disabled', false);
$('#sendBtn').prop('disabled', false);
})
.catch((err) => {
console.log('加入群组失败', err.code, err.msg);
});
});
$('#logoutBtn').click(() => {
logout()
.then(() => {
console.log('登出成功');
showToast('loginToast', '登出成功');
$('#loginBtn').prop('disabled', false);
$('#logoutBtn').prop('disabled', true);
})
.catch((err) => {
console.log('初始化、登录失败', err.code, err.msg);
});
});
$('#leaveBtn').click(() => {
leaveGroup()
.then(() => {
showMessage('离开群组成功');
$('#leaveBtn').prop('disabled', true);
$('#sendBtn').prop('disabled', true);
$('#joinBtn').prop('disabled', false);
})
.catch((err) => {
console.log('离开群组失败', err.code, err.msg);
});
});
$('#oneLogoutBtn').click(async () => {
try {
// 先离开群组,无论成功与否,都继续执行 logout
await leaveGroup();
} catch (error) {
console.log(error);
}
try {
await logout();
showToast('loginToast', '登出成功');
$('#loginBtn').prop('disabled', false);
$('#logoutBtn').prop('disabled', true);
$('#leaveBtn').prop('disabled', true);
$('#sendBtn').prop('disabled', true);
$('#joinBtn').prop('disabled', false);
$('#oneLogoutBtn').prop('disabled', true);
$('#oneLoginBtn').prop('disabled', false);
} catch (error) {
console.log(error);
}
});
$('#createBtn').click(() => {
const groupId = $('#groupId').val();
if (!groupManager) {
return;
}
groupManager.createGroup(
{
groupId, // 群组ID,为空时,系统创建新群组后会返回唯一ID
groupName: 'xxx', // 群组昵称,一定要设置,否则会失败
groupMeta: 'xxx' // 群组扩展信息,如果有多个字段可以考虑封装为JSON字符串
}
)
.then((res) => {
console.log('创建群组成功', res);
})
.catch((err) => {
console.log('创建群组失败', err.code, err.msg);
});
});
$('#sendBtn').click(() => {
const text = $('#msgText').val();
if (!messageManager || !joinedGroupId) {
return;
}
messageManager.sendGroupMessage({
groupId: joinedGroupId, // 群组id
data: text, // 发送消息内容,如果是结构化可考虑使用json字符串
type: 88888, // 自定义消息类型,需大于10000
skipAudit: false, // 可选(默认 false),跳过安全审核,true:发送的消息不经过阿里云安全审核服务审核;false:发送的消息经过阿里云安全审核服务审核,审核失败则不发送。
skipMuteCheck: false, // 可选(默认 false),跳过禁言检测,true:忽略被禁言用户,还可发消息;false:当被禁言时,消息无法发送
level: ImMessageLevel.NORMAL, // 可选(默认 NORMAL), 消息分级,需要高可靠时,使用 ImMessageLevel.HIGH
noStorage: true, // 可选(默认 false)true:表示该消息不需要存储,也无法拉取查询;false:消息进行存储,可以拉取查询。如果在直播间的弹幕场景,需要设置为 false。
repeatCount: 1 // 可选(默认 1)本消息重复数量,内容完成一样的消息可以使用该字段进行聚合,并发送一次即可。
})
.then((res) => {
console.log('群消息发送成功', res);
$('#msgText').val('');
})
.catch((err) => {
console.log('群消息发送失败', err.code, err.msg);
});
});
$('#clearBtn').click(() => {
$('#msgList').empty();
});
步骤四:运行体验
在终端中进入demo文件夹,然后执行
http-server -p 8080
,启动一个HTTP服务。浏览器中新建标签页,访问
localhost:8080/quick.html
,在界面上填入用户ID ,单击登录按钮。在界面上填入群组ID,单击加入群组按钮。
浏览器中再新建一个标签页,访问
localhost:8080/quick.html
,在界面上填入与上一步相同的群组ID和另一个用户ID,单击登录、加入群组按钮。在界面上消息文本输入框输入要发送的消息,单击发送按钮,即可发送群消息。发送成功后,两个用户将收到服务端下发的对应消息。