在线咨询
专属客服在线解答,提供专业解决方案
工单支持
专业技术支持团队,随时响应服务需求

语聊房 PaaS 方案怎么接入?

声网的语聊房 PaaS 方案(聊天室 SDK)把 RTC 和 IM 打包提供,但它们在客户端仍然是两套独立的初始化流程。除此之外,房间的创建、列表、生命周期管理需要一个云服务层(声网示例里用的是内部云服务),生产环境要自己部署对应的服务端。


一. 接入前要准备的东西

声网 AppID 和 Token:登录 console.shengwang.cn 创建项目,获取 AppID。调试阶段可以从控制台生成有效期 24 小时的临时 Token,上线前必须自己部署 Token 服务,由服务端根据用户 ID 和频道名动态签发,不能把 App Certificate 写在客户端里。

IM 账号和 Token:聊天室 SDK 内置 Easemob IM,获取 IM 用户名和 IM Token。IM Token 和 RTC Token 是两套独立的鉴权体系,不能混用。

服务端:房间列表、房间创建记录、麦位状态持久化这些数据需要服务端支撑。声网示例项目提供了参考实现,但明确标注”仅供快速集成使用,不适用于商业用途”,上线前需要自行实现房间管理服务。


二. 两套 SDK 的初始化顺序

PaaS 方案接入的第一个容易踩的坑是初始化顺序。RtcEngine 和 IM ChatClient 有各自的初始化入口,推荐顺序是:先登录 IM,再初始化 RtcEngine。

第一步:登录 IM

ChatClient.getInstance().loginWithToken(uid, imToken, object : CallBack {
    override fun onSuccess() {
        // IM 登录成功,再执行后续初始化
    }
    override fun onError(code: Int, error: String?) {
        // 处理登录失败
    }
})

IM 登录是异步的,成功回调之后才能操作 IM 聊天室(加入、发消息等)。进房流程里不要在 IM 登录成功前就调用 joinChatRoom,否则会报鉴权错误。

第二步:初始化 RtcEngine

val config = RtcEngineConfig()
config.mAppId = "YourAppId"
config.mContext = applicationContext
val rtcEngine = RtcEngineEx.create(config)

RtcEngine 初始化只需要 AppID,不需要 Token,Token 在加入频道(joinChannel)时才用到。初始化放在 Application 层,整个应用生命周期内只创建一次。


三. 创建和加入房间

房主创建房间

创建房间涉及两层操作:在服务端创建房间记录,以及让 RTC 和 IM 分别加入对应的频道/聊天室。

// 1. 通过服务端创建房间(获取 roomId、channelId 等信息)
voiceServiceProtocol.createRoom(roomInfo) { error, room ->
    if (error != null) return@createRoom

    // 2. 加入 RTC 频道
    rtcEngine?.joinChannel(rtcToken, room.channelId, "", rtcUid)

    // 3. 加入 IM 聊天室
    ChatClient.getInstance().chatroomManager()
        .joinChatRoom(room.chatroomId, object : ValueCallBack {
            override fun onSuccess(value: ChatRoom?) { }
            override fun onError(error: Int, errorMsg: String?) { }
        })
}

RTC 加入频道和 IM 加入聊天室是两个独立的异步操作,两个都成功之后才算真正进房。建议用计数器或 CountDownLatch 等方式等两者都完成后再更新 UI 状态,避免麦位界面和消息通道一个就绪一个还没好的中间状态。

听众加入房间

听众侧不需要创建房间,直接拿到 roomId 后查询房间信息,再用相同的方式加入 RTC 频道和 IM 聊天室:

// 获取房间列表,找到目标房间
voiceServiceProtocol.fetchRoomList(page, size) { error, list ->
    val room = list.find { it.roomId == targetRoomId } ?: return@fetchRoomList

    // 加入 RTC 频道(听众角色)
    rtcEngine?.joinChannel(rtcToken, room.channelId, "", rtcUid)

    // 加入 IM 聊天室
    ChatClient.getInstance().chatroomManager()
        .joinChatRoom(room.chatroomId, callBack)
}

四. 麦位管理的接入逻辑

麦位控制是聊天室 SDK 的内置核心功能之一,SDK 提供了上麦、下麦、禁言、锁麦、换麦等麦位操作 API,底层通过 IM 信令实现状态同步,但开发者调用的是 SDK 封装好的麦位接口,不需要自己拼 IM 自定义消息。

PaaS 方案和 UIKit 在麦位这层的实质差异在于 UI:SDK 提供能力 API,但麦位的视觉呈现(卡片样式、状态动效、申请弹窗)需要自己实现。断线重连后 SDK 会重新同步麦位状态,并发冲突的处理也在 SDK 内部,不需要自己写状态机。具体 API 以声网聊天室 SDK 当前版本文档为准,见 麦位管理指南


五. 退出和资源释放

退出房间要按顺序清理两套 SDK 的资源,遗漏任何一步都可能导致下次进房时出现状态残留:

// 1. 离开 RTC 频道
rtcEngine?.leaveChannel()

// 2. 离开 IM 聊天室
ChatClient.getInstance().chatroomManager().leaveChatRoom(chatroomId)

// 3. 通知服务端更新房间状态
voiceServiceProtocol.leaveRoom(roomId)

// 如果是房主销毁房间,还需要额外销毁聊天室
// ChatClient.getInstance().chatroomManager().destroyChatRoom(chatroomId, callBack)

// 4. 应用退出时销毁 RtcEngine(不是每次退房都调,只在应用退出时调一次)
RtcEngineEx.destroy()

RtcEngineEx.destroy() 是重量级操作,销毁后重新创建需要时间。如果用户频繁进出房间,不要每次退房都销毁,保留 RtcEngine 实例在应用层复用,退房只调 leaveChannel,下次进房直接 joinChannel。


六. 生产环境的服务端搭建要点

声网的聊天室 SDK 文档里明确说明:示例项目使用的云服务是声网内部实现,开发者在生产环境中需要自行实现同等能力的服务。最少需要实现以下几个服务端接口:

  • Token 服务:根据用户 ID 和频道名签发 RTC Token,IM Token 的生成也需要服务端支持
  • 房间管理服务:创建房间(写库)、房间列表查询(分页)、房间销毁(清理记录和 IM 聊天室)
  • 用户鉴权:进房前验证用户身份,防止未授权用户绕过前端直接调 RTC joinChannel

如果业务里还有礼物系统、积分打赏,服务端还要增加对应的写入接口,这些都不在 SDK 范围内,需要自己实现。


七. PaaS 和 UIKit 的关键差异回顾

事项 PaaS SDK UIKit(AUIVoiceRoom)
RTC + IM 初始化 分别初始化,顺序自己管 AUIVoiceRoomUIKit.init() 一次搞定
UI 完全自己实现 AUIVoiceRoomView 开箱即用
麦位管理 SDK 内置 API,UI 自己实现 AScenesKit 内部处理,含 UI
后端服务 生产环境全部自建 开源后端项目可直接部署(Spring Boot + Docker)
灵活度 完全自由 受 AScenesKit 组件边界约束

 

在声网,连接无限可能

想进一步了解「对话式 AI 与 实时互动」?欢迎注册,开启探索之旅。

本博客为技术交流与平台行业信息分享平台,内容仅供交流参考,文章内容不代表本公司立场和观点,亦不构成任何出版或销售行为。