[声网音频SDK实战教程] 如何准确判断 在 "进房流程" 中, 调用 joinChannel() 之后成功还是失败.

简介

通过本篇教程, 您将学习到如何准确判断 在 "进房流程" 中, 调用 joinChannel() 之后成功还是失败.

问题描述

一般语音房业务的设计思路是, 进入房间时会有若干顺序进行的操作, 都成功才算是进入语音房成功,
以我们APP的设计为例, 进入语音房之后要顺序执行如下操作 : 
1] 请求房间详情接口
2] 请求声网ClientRole & Token
3] 请求加入声网 Channel
4] 请求加入云信 ChatRoom

所以我们希望, 在请求加入 声网Channel时, 能够准确判断出 加入成功 和 加入失败, 好做对应的处理.

解决方案

调用 joinChannel() 之后, 如果加入成功的话, 声网是有对应的回调通知的, 如下 : 

/**
 * 加入频道回调。(TODO : 本回调用于本地用户调用 joinChannel 成功时执行)
 * <p>
 * 表示客户端已经登入服务器,且分配了频道 ID 和用户 ID。
 * 频道 ID 的分配是根据 joinChannel 方法中指定的频道名称。
 * 如果调用 joinChannel 时并未指定用户 ID,服务器就会分配一个。
 *
 * @param channel 频道名
 * @param uid     用户 ID 。如果 joinChannel 中指定了 uid,则此处返回该 ID;否则使用 Agora 服务器自动分配的 ID
 * @param elapsed 从 joinChannel 开始到发生此事件过去的时间(毫秒)
 */
@Override
public void onJoinChannelSuccess(String channel, int uid, int elapsed) {


但是, 没有对应的加入频道失败的回调通知.
我们可以通过如下方式来判断加入频道失败.


1] 调用 joinChannel()之后, 需要判断返回的错误代码, 如果不等于 Constants.ERR_OK , 就意味本次加入请求失败;

errorCode = rtcEngine.joinChannel(userAgoraInfo.getAgoraToken(), userAgoraInfo.getAgoraChannelName(), "", userAgoraInfo.getAgoraUID());
DebugLog.e(vcrSdk.TAG_AGORA, "rtcEngine.joinChannel(token = " + userAgoraInfo.getAgoraToken() + ", channelName = " + userAgoraInfo.getAgoraChannelName() + ", optionalUid = " + userAgoraInfo.getAgoraUID() + ") --> resultCode = " + errorCode);

if (errorCode != Constants.ERR_OK) {
    // TODO : 执行 joinChannel() 方法失败, 可能是参数有问题
    /**
     * -2(ERR_INALID_ARGUMENT): 参数无效。
     * -3(ERR_NOT_READY): SDK 初始化失败,请尝试重新初始化 SDK。
     * -5(ERR_REFUSED): 调用被拒绝。可能有如下两个原因:
     * 已经创建了一个同名的 RtcChannel 频道。
     * 已经通过 RtcChannel 加入了一个频道,并在该 RtcChannel 频道中发布了音视频流。
     * 由于通过 RtcEngine 加入频道会默认发布音视频流,而 SDK 不支持同时在两个频道发布音视频流,因此会报错。
     * -7(ERR_NOT_INITIALIZED): SDK 尚未初始化,就调用其 API。请确认在调用 API 之前已创建 RtcEngine 对象并完成初始化。
     */
    errorMessage = "执行joinChannel失败";
    break;
}


2] 声网会通过 onError() 回调通知, 告知我们本次joinChannel失败, 但是因为其他错误也都是执行 onError(), 所以需要我们自己定义一个标记位, 标记进房是否成功, 如果执行onError时, 还未进房成功, 那么就是joinChannel()失败了, 否则则是其他错误.


/**
 * 发生错误回调。
 * <p>
 * 表示 SDK 运行时出现了(网络或媒体相关的)错误。通常情况下,
 * SDK 上报的错误意味着 SDK 无法自动恢复,需要 App 干预或提示用户。
 * 例如启动通话失败时,SDK 会上报 ERR_START_CALL 错误。
 * App 可以提示用户启动通话失败,并调用 leaveChannel 退出频道。
 *
 * @param errorCode 错误代码,详细定义见 Error Code
 */
@Override
public void onError(int errorCode) {
    DebugLog.e(vcrSdk.TAG_AGORA, "IRtcEngineEventHandler --> onError(发生错误回调) : code = " + errorCode);

    if (errorCode == Constants.ERR_NOT_READY //
            || errorCode == Constants.ERR_NOT_INITIALIZED //
            || errorCode == Constants.ERR_ALREADY_IN_USE //
            || errorCode == Constants.ERR_INVALID_APP_ID //
            || errorCode == Constants.ERR_INVALID_CHANNEL_NAME //
            || errorCode == Constants.ERR_INVALID_TOKEN //
            || errorCode == Constants.ERR_LOAD_MEDIA_ENGINE //
            || errorCode == Constants.ERR_START_CALL) {

        // TODO : 发生了致命错误, 此时客户端可以结束声网SDK的使用了, 直接退出语聊房
        DebugLog.e(vcrSdk.TAG_AGORA, "IRtcEngineEventHandler --> onError : 发生了致命错误, 此时客户端可以结束声网SDK的使用了, 直接退出语聊房.");

        /**
         * Constants.ERR_NOT_READY :3:SDK 初始化失败。Agora 建议尝试以下处理方法:
         *
         * 检查音频设备状态
         * 检查程序集完整性
         * 尝试重新初始化 SDK
         *
         * Constants.ERR_NOT_INITIALIZED 7:SDK 尚未初始化,就调用其 API。请确认在调用 API 之前已创建 RtcEngine 对象并完成初始化。
         *
         * Constants.ERR_ALREADY_IN_USE 19:资源已被占用,不能重复使用。
         *
         * Constants.ERR_INVALID_APP_ID 101:不是有效的 APP ID。请更换有效的 APP ID 重新加入频道。
         *
         * Constants.ERR_INVALID_CHANNEL_NAME 102:不是有效的频道名。请更换有效的频道名重新加入频道。
         *
         * Constants.ERR_INVALID_TOKEN 110:生成的 Token 无效。
         *
         * 弃用:
         * 从 v2.4.1 起废弃。请改用 onConnectionStateChanged 回调中的 CONNECTION_CHANGED_INVALID_TOKEN(8)。
         * 一般有以下原因:
         *
         * 用户在控制台上启用了 App Certificate,但仍旧在代码里仅使用了 App ID。当启用了 App Certificate,必须使用 Token.
         * 字段 uid 为生成 Token 的必须字段,用户在调用 joinChannel 加入频道时必须设置相同的 uid
         *
         * Constants.ERR_LOAD_MEDIA_ENGINE 1001:加载媒体引擎失败。
         *
         * Constants.ERR_START_CALL 1002:启动媒体引擎开始通话失败。请尝试重新进入频道。
         */

        handler.post(new Runnable() {
            @Override
            public void run() {
                if (vcrSdk.isInVoiceRoom()) {
                    // 已经在语聊房中游戏了, 此时可以执行退房流程了
                    vcrSdk.userPassiveLeaveRoom("声网SDK发生了严重错误, errorCode = " + errorCode);
                } else {
                    // 应该加入语聊房流程出现了问题
                    vcrSdk.onEnterRoomFailure("加入声网Channel_异步回调onError", new ErrorBean(errorCode, "执行声网回调onError"));
                }
            }
        });
    }
}


推荐阅读
相关专栏
开发者实践
182 文章
本专栏仅用于分享音视频相关的技术文章,与其他开发者和声网 研发团队交流、分享行业前沿技术、资讯。发帖前,请参考「社区发帖指南」,方便您更好的展示所发表的文章和内容。