human: 如何处理七牛云的实时音视频房间管理

gpt: [实时音视频](https://developer.qiniu.com/rtc) > 使用指南 > iOS >房间管理

#  房间管理

最近更新时间: 2022-06-30 17:23:20

**房间**
是对音视频对话空间的抽象，用于隔离不同的通话过程，保障数据的安全及独立。同一房间内的用户可以互相接收对方的音视频数据。本部分介绍如何进行房间管理，获取房间信息、用户信息以及如何实现踢人等常见功能。

>   *
> 加入、离开房间代表一次音视频通话的开始和结束，一次会话仅需调用一次加入、离开的操作即可，无需重复调用。加入房间后对音视频数据的发送和接收，可参考[发布和订阅](https://developer.qiniu.com/rtc/9260/publish-
> and-subscribe-iOS)相关流程。
>   * 加入房间需要携带相应的
> [RoomToken](https://developer.qiniu.com/rtc/quick_start/9909/the-rtc-basic-
> concept#room_token)，[RoomToken](https://developer.qiniu.com/rtc/quick_start/9909/the-
> rtc-basic-concept#room_token) 需通过您的服务端生成，签算方式可参考 [RoomToken
> 签发服务](https://developer.qiniu.com/rtc/8813/roomToken)。
>

# 房间的生命周期

  * 当用户加入的房间不存在时，七牛后台服务会自动创建对应的房间。
  * 若房间内的所有用户都已离开，那么房间维持空状态 10s 后将会自动关闭。
  * 若房间为服务端创建，且创建后无用户进入，那么房间维持空状态 30s 后将会自动关闭。
  * 若房间内的用户由于断网等原因，30s 未向七牛后台服务通信，则该用户将被视为退出房间。

# 加入房间

本地通过 [QNRTCClient](https://developer.qiniu.com/rtc/api/8836/QNRTCClient-iOS)
传入 [RoomToken](https://developer.qiniu.com/rtc/quick_start/9909/the-rtc-basic-
concept#room_token) 加入房间。

    
    
    - (void)join:(NSString *)token;
    - (void)join:(NSString *)token userData:(NSString *)userData;
    

示例代码如下：

    
    
    [rtcClient join:token];
    

>   1. 请确保在 `QNConnectionStateDisconnected` 状态下调用该接口加入房间，否则接口调用无效
>   2. 加入房间时根据业务需求，每个用户可通过 `userData` 携带自定义数据
>

关于 [RoomToken](https://developer.qiniu.com/rtc/quick_start/9909/the-rtc-basic-
concept#room_token) 在服务端的生成，可查阅 [RoomToken
签发服务](https://developer.qiniu.com/rtc/8813/roomToken)。

**本地用户收到的回调：**

成功加入房间后，会通过
[QNRTCClientDelegate.didConnectionStateChanged](https://developer.qiniu.com/rtc/api/9248/QNRTCClientDelegate#didConnectionStateChanged)
回调改变后的房间状态

    
    
    - (void)RTCClient:(QNRTCClient *)client didConnectionStateChanged:(QNConnectionState)state disconnectedInfo:(QNConnectionDisconnectedInfo *)info {
    	// 当房间状态改变时会触发此回调，成功加入房间后，回调状态为 QNConnectionStateConnected
    }
    

  * 若加入房间成功，会回调 [QNConnectionStateConnected](https://developer.qiniu.com/rtc/9261/room-management-iOS/9254) 状态。
  * 若加入房间失败，会回调 [QNConnectionStateDisconnected](https://developer.qiniu.com/rtc/9261/room-management-iOS/9254) 状态，同时可以通过 [QNConnectionDisconnectedInfo](https://developer.qiniu.com/rtc/api/8866/QNConnectionDisconnectedInfo-iOS) 获取失败的[原因](https://developer.qiniu.com/rtc/api/8866/QNConnectionDisconnectedInfo-iOS#reason)以及对应的[错误码](https://developer.qiniu.com/rtc/10084/rtc-error-code-iOS#1)

**远端用户收到的回调：**

    
    
    - (void)RTCClient:(QNRTCClient *)client didJoinOfUserID:(NSString *)userID userData:(NSString *)userData {
    	// 当远端用户加入房间时会触发此回调
    }
    

# 离开房间

本地通过调用
[QNRTCClient.leave](https://developer.qiniu.com/rtc/api/8836/QNRTCClient-
iOS#leave) 退出房间。

    
    
    - (void)leave;
    

示例代码如下：

    
    
    [rtcClient leave];
    

本地退出房间成功后，会触发如下回调：

**本地用户收到的回调：**

    
    
    - (void)RTCClient:(QNRTCClient *)client didConnectionStateChanged:(QNConnectionState)state disconnectedInfo:(QNConnectionDisconnectedInfo *)info {
    	// 当房间状态改变时会触发此回调，成功离开房间后，回调状态为 QNConnectionStateDisconnected，QNConnectionDisconnectedInfo 回调 Reason 为 QNConnectionDisconnectedReasonLeave
    }
    

**远端用户收到的回调：**

    
    
    - (void)RTCClient:(QNRTCClient *)client didLeaveOfUserID:(NSString *)userID {
    	// 当远端用户离开房间时会触发此回调
    }
    

# 房间信息

## 获取房间内远端用户信息

本地可调用
[QNRTCClient.getRemoteUser](https://developer.qiniu.com/rtc/api/8836/QNRTCClient-
iOS#getRemoteUser) 接口获取音视频通话房间中的指定用户。

    
    
    - (QNRemoteUser *)getRemoteUser:(NSString *)userID;
    

本地可调用
[QNRTCClient.remoteUserList](https://developer.qiniu.com/rtc/api/8836/QNRTCClient-
iOS#remoteUserList) 接口获取音视频通话房间中的远端用户列表。

    
    
    @property (nonatomic, strong, readonly) NSArray<QNRemoteUser *> *remoteUserList;
    

其中，[QNRemoteUser](https://developer.qiniu.com/rtc/api/8835/QNRemoteUser-iOS)
代表远端用户的信息，通过该对象可以获取指定 user 发布的音视频列表以及本地对其的订阅情况。

## 获取房间状态信息

本地可以调用
[QNRTCClient.connectionState](https://developer.qiniu.com/rtc/api/8836/QNRTCClient-
iOS#connectionState) 接口获取音视频通话的房间状态信息。

    
    
    @property (nonatomic, assign, readonly) QNConnectionState connectionState;
    

其中，[QNConnectionState](https://developer.qiniu.com/rtc/api/9254/QNTypeDefines#QNConnectionState)
包含如下状态：

    
    
    typedef NS_ENUM(NSUInteger, QNConnectionState) {
    	QNConnectionStateDisconnected = 0,    // 空闲状态，初始状态或者退出后都会进入该状态
    	QNConnectionStateConnecting,          // 正在加入的状态
    	QNConnectionStateConnected,           // 已加入的状态
    	QNConnectionStateReconnecting,        // 正在重连的状态
    	QNConnectionStateReconnected          // 重连成功的状态
    };
    

# 踢人

## 客户端踢人

客户端 SDK 未提供踢人的接口，但是踢人操作可以通过自定义消息来实现。实现步骤可参考如下：

  1. 业务侧协商定义好踢人消息的格式规范
  2. 踢人方在执行踢人操作时，向指定用户发送协商好的踢人消息
  3. 被踢方接收到踢人消息后，主动离开当前房间

示例代码参考如下：

**踢人方：**

踢人方发送协商好的踢人消息：

    
    
    [rtcClient sendMessage:@"kickOut" toUsers:@[user] messageId:messageId];
    

其中，自定义消息的使用方式可以参考
[QNRTCClient.sendMessage](https://developer.qiniu.com/rtc/api/8836/QNRTCClient-
iOS#sendMessage)。

**被踢方：**

被踢方实现
[QNRTCClientDelegate.didReceiveMessage](https://developer.qiniu.com/rtc/api/9248/QNRTCClientDelegate#didReceiveMessage)
回调接口来接收踢人消息，并在收到消息后主动离开房间：

    
    
    - (void)RTCClient:(QNRTCClient *)client didReceiveMessage:(QNMessageInfo *)message {
    	if ([message.content equalToString:@"kickOut"]) {
    		// 离开房间
    	}
    }
    

## 服务端踢人

服务端提供了踢人的接口，详情可参考[服务端文档](https://developer.qiniu.com/rtc/api/8815/api-
room)，当服务端执行踢人操作后，会触发被踢方
[QQNRTCClientDelegate.didConnectionStateChanged](https://developer.qiniu.com/rtc/api/9248/QNRTCClientDelegate#didConnectionStateChanged)
回调：

    
    
    - (void)RTCClient:(QNRTCClient *)client didConnectionStateChanged:(QNConnectionState)state disconnectedInfo:(QNConnectionDisconnectedInfo *)info {
    	if (state == QNConnectionStateDisconnected && info != null && QNConnectionDisconnectedReasonKickedOut == info.reason) {
    		// 您已被服务端踢出房间
    	}
    }
    

其中，被服务端踢出房间的场景下，[QNConnectionDisconnectedInfo](https://developer.qiniu.com/rtc/api/8866/QNConnectionDisconnectedInfo-
iOS) 回调的状态为 `QNConnectionStateDisconnected`，同时
`QNConnectionDisconnectedInfo.reason` 为
`QNConnectionDisconnectedReasonKickedOut`。

以上内容是否对您有帮助？