> For the complete documentation index, see [llms.txt](https://docs.convai.com/api-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/multi-character-sessions/room-session-reference.md).

# 房间会话参考

多角色房间会话类型、其成员与状态字段，以及其命令返回的结果和异常的参考。

`MultiCharacterRoomSession` 是多角色房间名册在客户端的投影。本页列出你可读取或调用的每个公开成员 `MultiCharacterRoomSession`, `CharacterRoomMembership`, `CharacterRoomStatus`, `InteractionTargetResult`, `CharacterRosterUpdateResult`，以及 `CharacterRosterUpdateException`。SDK 会自行构建这三种结果和异常类型，因此省略了它们的构造函数。所有六种类型都位于 `Convai.Runtime.Room` 命名空间中，定义在 `SDK/Runtime/Room/MultiCharacterRoomSession.cs`.

***

### `CharacterRoomStatus`

`CharacterRoomStatus` 是一个包含三个值的枚举，位于 `CharacterRoomMembership.Status`.

| 值          | 数值  | 含义                                                   |
| ---------- | --- | ---------------------------------------------------- |
| `Starting` | `0` | 该成员关系存在于名册中，但尚未被报告为就绪或失败。                            |
| `Ready`    | `1` | 该角色已发出可接受输入的信号。                                      |
| `Failed`   | `2` | 该角色未能启动。 `CharacterRoomMembership.FailureCode` 携带原因。 |

***

### `CharacterRoomMembership`

`CharacterRoomMembership` 是一个密封类，将一个后端成员关系绑定到一个本地角色实例。下面的每个字段都是 SDK 外部可公开读取的属性。

| 成员                    | 类型                      | 说明                                                                                                                                                       |
| --------------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `MembershipId`        | `string`                | 用于定位此实例 — 将它传给 `SetInteractionTargetAsync(string, CancellationToken)`, `RemoveCharacterAsync(string, string, CancellationToken)`，或 `FindByMembershipId`. |
| `CharacterId`         | `string`                | 创建此实例所依据的 Convai 角色定义。在名册中并不唯一 — 相同的值可能出现在多个成员关系上。                                                                                                       |
| `SessionId`           | `string`                | Convai 在连接响应中为此成员关系返回的会话标识符。                                                                                                                             |
| `CharacterSessionId`  | `string`                | 跨会话延续此实例的对话，并消除重复的 `CharacterId` 值的歧义。                                                                                                                   |
| `ParticipantIdentity` | `string`                | 将此实例与其传输参与者和音频轨道匹配。请将其视为不透明值。                                                                                                                            |
| `IsInitial`           | `bool`                  | `true` 用于 Convai 标记为房间初始角色的那个成员关系。                                                                                                                       |
| `ProvisioningStatus`  | `string`                | Convai 为此条目返回的原始 provisioning 字符串。                                                                                                                       |
| `Character`           | `IConvaiCharacterAgent` | 与此成员关系绑定的本地 `ConvaiCharacter` ，或者 `null` 当名册中包含场景没有对应组件的成员关系时。                                                                                           |
| `状态`                  | `CharacterRoomStatus`   | 该成员关系的当前状态。对外只读；SDK 在内部设置它。                                                                                                                              |
| `FailureCode`         | `string`                | Convai 报告的失败原因，在 `状态` 是 `Failed`. `null` 时设置，否则为                                                                                                         |
| `ParticipantId`       | `string`                | SDK 在该成员关系的媒体出现时为其绑定的传输分配参与者。绑定后填充，而不是在连接时填充。                                                                                                            |

`CharacterRoomMembership.WaitUntilReadyAsync(CancellationToken cancellationToken = default)` 返回一个 `Task` ，当此特定成员关系达到 `Ready`时完成，或在其达到 `Failed`时出错。将其用于等待次要角色； `MultiCharacterRoomSession.WaitUntilReadyAsync` 只会对 `InitialCharacter`.

{% hint style="info" %}
`ProvisioningStatus == "dispatch_failed"` 在成员关系创建的那一刻就将其标记为 `Failed` ，在任何单独的生命周期消息到达之前。
{% endhint %}

***

### `MultiCharacterRoomSession`

`MultiCharacterRoomSession` 是一个密封类。SDK 在内部创建并更新其实例；请通过 `IConvaiRoomConnectionService.CurrentMultiCharacterSession`.

#### 属性

| 属性                   | 类型                                       | 说明                                                                       |
| -------------------- | ---------------------------------------- | ------------------------------------------------------------------------ |
| `RoomSessionId`      | `string`                                 | 持久化的房间标识符，可与 `MultiCharacterJoinOptions.RoomSessionId` 一起使用，以便稍后加入同一个房间。 |
| `ActiveMembershipId` | `string`                                 | 该 `MembershipId` 当前交互目标的值，若未设置目标则为空字符串。                                  |
| `RouteEpoch`         | `int`                                    | 每当交互目标更改时递增。用于防止目标更新受到乱序确认的影响。                                           |
| `RosterEpoch`        | `int`                                    | 每当名册更改时递增。用于防止名册更新受到乱序确认的影响。                                             |
| `PartialDispatch`    | `bool`                                   | `true` 当 Convai 在连接时未分发所有请求的角色时。该值在会话存续期间固定不变。                           |
| `角色`                 | `IReadOnlyList<CharacterRoomMembership>` | 当前名册中的每个成员关系。                                                            |
| `InitialCharacter`   | `CharacterRoomMembership`                | Convai 标记为初始的那个成员关系，或者在没有成员关系带有该标记时，名册中的第一个成员关系。对于任何有成员的房间，绝不会为 `null` 。 |
| `IsReady`            | `bool`                                   | `true` 当 `InitialCharacter.Status` 是 `Ready`。不受其他任何成员关系状态的影响。            |

#### 事件

| 事件                         | 签名                                                         | 在以下情况触发                                                                                        |
| -------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| `CharacterStatusChanged`   | `Action<CharacterRoomMembership>`                          | 某个成员关系转入 `Ready` 或 `Failed`，或一个新的成员关系被插入到名册中。                                                  |
| `CharacterAdded`           | `Action<CharacterRoomMembership>`                          | 一个成员关系被添加到名册中，来源可以是名册命令的确认，也可以是未请求的生命周期消息。                                                     |
| `CharacterRemoved`         | `Action<CharacterRoomMembership>`                          | 一个成员关系从名册中移除。                                                                                  |
| `InteractionTargetChanged` | `Action<CharacterRoomMembership, CharacterRoomMembership>` | 交互目标发生变化。第一个参数是先前的成员关系（或 `null`），第二个参数是当前成员关系（或 `null`).                                       |
| `RosterEpochChanged`       | `Action<int>`                                              | 观察到一个更新的权威名册轮次。可在没有匹配 `CharacterAdded`/`CharacterRemoved`的情况下前进，因此如果你需要的是名册变更，不要只根据添加/移除事件来推断。 |
| `Retired`                  | `操作`                                                       | 该会话被替换或清除 — 只会触发一次。请将其视为终止信号，并将处理程序重新附加到新的 `CurrentMultiCharacterSession`.                     |

{% hint style="warning" %}
移除活动成员关系会先触发 `InteractionTargetChanged` ，其中被移除的成员关系作为先前值，而 `null` 作为当前值，然后再触发 `CharacterRemoved`。响应移除的代码可以依赖于目标此时已被清除。
{% endhint %}

#### 方法

| 方法                                                                   | 返回                        | 说明                                                                                                                                                                                                                                                |
| -------------------------------------------------------------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `WaitUntilReadyAsync(CancellationToken cancellationToken = default)` | `Task`                    | 在以下情况完成 `InitialCharacter` 达到 `Ready`，如果 `IsReady` 已经 `true`则立即返回。以 `InvalidOperationException` 出错，携带 `初始角色启动失败（<code>）。` 当初始角色达到 `Failed`. `<code>` 是 `FailureCode`，或 `unknown` 时使用，而 Convai 没有报告任何内容。如果连接响应已将初始角色标记为失败，则故障可能会在第一次 `await` 之前发生。 |
| `FindByCharacter(IConvaiCharacterAgent character)`                   | `CharacterRoomMembership` | 返回绑定到 `角色`，或 `null` 当 `角色` 是 `null` 的成员关系，或者返回房间中不存在的成员关系。                                                                                                                                                                                        |
| `FindByMembershipId(string membershipId)`                            | `CharacterRoomMembership` | 返回具有给定 `MembershipId`，或 `null` 当 `membershipId` 的成员关系，如果其为空或未找到则返回。                                                                                                                                                                               |

***

### `InteractionTargetResult`

`InteractionTargetResult` 是一个由 `SetInteractionTargetAsync` 和 `ClearInteractionTargetAsync`.

| 属性                     | 类型       | 说明                                                          |
| ---------------------- | -------- | ----------------------------------------------------------- |
| `CommandId`            | `string` | SDK 为交互目标命令分配的标识符。                                          |
| `ActiveMembershipId`   | `string` | 该会话上的规范 `ActiveMembershipId` ，位于此命令应用之后。                    |
| `PreviousMembershipId` | `string` | 该 `MembershipId` 在此命令之前处于活动状态的那个。                           |
| `RouteEpoch`           | `int`    | 该 `RouteEpoch` 此命令产生的值。                                     |
| `Changed`              | `bool`   | `true` 当此命令的结果确实移动了规范目标时。 `false` 当由于其路由轮次未超过 `RouteEpoch`. |

***

### `CharacterRosterUpdateResult`

`CharacterRosterUpdateResult` 是一个密封类，由 `AddCharacterAsync` 和 `RemoveCharacterAsync`.

| 属性                   | 类型                                       | 说明                                       |
| -------------------- | ---------------------------------------- | ---------------------------------------- |
| `CommandId`          | `string`                                 | SDK 为名册命令分配的标识符。                         |
| `Added`              | `IReadOnlyList<CharacterRoomMembership>` | 此命令添加的成员关系。仅移除成员关系时为空。                   |
| `Removed`            | `IReadOnlyList<CharacterRoomMembership>` | 此命令移除的成员关系。仅添加成员关系时为空。                   |
| `ActiveMembershipId` | `string`                                 | 该会话上的规范 `ActiveMembershipId` ，位于此命令应用之后。 |
| `RouteEpoch`         | `int`                                    | 该 `RouteEpoch` 此命令之后的值。                  |
| `RosterEpoch`        | `int`                                    | 该 `RosterEpoch` 此命令产生的值。                 |

***

### `CharacterRosterUpdateException`

`CharacterRosterUpdateException` 是一个继承自 `InvalidOperationException`的密封类。名册命令的 `Task` 在 Convai 的确认报告的状态不是 `success` 或 `ok`.

| 成员        | 类型            | 说明                                          |
| --------- | ------------- | ------------------------------------------- |
| `代码`      | `string`      | 确认中的后端错误代码。当 Convai 没有报告任何内容时为空字符串。         |
| `Message` | `string` （继承） | 确认中的后端错误消息，或者 `角色名册更新失败。` 当 Convai 没有报告消息时。 |

SDK 测试确认恰好有两个 `代码` 值： `roster_epoch_mismatch` 和 `unauthorized_sender`。后端上可能存在其他代码；不要假定该集合仅限于这两个。

此异常不同于 `ConvaiOperationException` 连接尝试因客户端侧名册验证而抛出的异常 — 参见 [连接 API 参考](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/multi-character-sessions/connection-api-reference.md#exceptions-and-timeouts) 了解该路径。

***

### 相关参考

{% content-ref url="/pages/634a0663b206a73fe4e2113edd3096e48b351d9a" %}
[连接 API 参考](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/multi-character-sessions/connection-api-reference.md)
{% endcontent-ref %}

{% content-ref url="/pages/1de47e20d64086de6ea2148c4871a665eec92182" %}
[多角色会话工作原理](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/multi-character-sessions/how-multi-character-sessions-work.md)
{% endcontent-ref %}

{% content-ref url="/pages/9febe55e8fa6244952665a225b37a964cd41c375" %}
[房间就绪状态](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/multi-character-sessions/readiness-and-partial-dispatch.md)
{% endcontent-ref %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/multi-character-sessions/room-session-reference.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
