简介
通过本篇教程, 您将学习到如何准确判断 在 "进房流程" 中, 调用 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"));
}
}
});
}
}