

# IVS 广播 SDK：令牌交换 \$1 实时直播功能
<a name="broadcast-mobile-token-exchange"></a>

通过令牌交换，您可以升级或降级参与者令牌功能以及更新移动广播 SDK 中的令牌属性，而无需参与者重新连接。这对于联合主持等场景非常实用，即参与者可以首先使用仅限订阅的功能，以后再需要发布功能的场景。

限制：
+ 令牌交换仅支持在服务器上使用[密钥对](https://docs.aws.amazon.com//ivs/latest/RealTimeUserGuide/getting-started-distribute-tokens.html#getting-started-distribute-tokens-self-signed)创建的令牌，不支持通过 [CreateParticipantToken API](https://docs.aws.amazon.com/ivs/latest/RealTimeAPIReference/API_CreateParticipantToken.html) 创建的令牌。
+ 如果您使用令牌交换功能来更改驱动服务器端合成布局的属性（例如 featuredParticipantAttribute 和 participantOrderAttribute），则在参与者重新连接之前，活动合成的布局不会更新。

## 交换令牌
<a name="broadcast-mobile-token-exchange-exchanging-tokens"></a>

交换令牌的过程十分简单：在 `Stage`/`IVSStage` 对象上调用 `exchangeToken` API 并提供新令牌即可。如果新令牌的 `capabilities` 与原令牌不同，则会立即评估新令牌的功能。例如，假设原令牌没有 `publish` 功能而新令牌有，则会调用用于发布的舞台策略函数，从而让主机应用程序决定是要使用该新功能立即发布，还是等待。此过程也适用于已移除的功能：如果原令牌具有 `publish` 功能而新令牌没有，则参与者无需调用用于发布的舞台策略函数即可立即取消发布。

交换令牌时，原令牌和新令牌中以下有效载荷字段的值必须相同：
+ `topic`
+ `resource`
+ `jti`
+ `whip_url`
+ `events_url`

这些字段是不可变的。修改不可变字段的令牌交换会导致 SDK 立即拒绝该交换。

其余字段是可以更改的，包括：
+ `attributes`
+ `capabilities`
+ `user`
+ `_id`
+ `iat`
+ `exp`

### iOS
<a name="broadcast-mobile-token-exchange-exchanging-tokens-ios"></a>



```
let stage = try IVSStage(token: originalToken, strategy: self)
stage.join()
stage.exchangeToken(newToken)
```

### Android
<a name="broadcast-mobile-token-exchange-exchanging-tokens-android"></a>



```
val stage = Stage(context, originalToken, strategy)
stage.join()
stage.exchangeToken(newToken)
```

## 接收更新
<a name="broadcast-mobile-token-exchange-receiving-updates"></a>

`StageRenderer`/`IVSStageRenderer` 中的某个函数收到有关通过交换令牌来更新其 `userId` 或 `attributes` 的远程参与者已发布的更新。尚未发布的远程参与者如果最终发布，则将通过现有的 `onParticipantJoined`/`participantDidJoin` renderer 函数公开更新后的`userId` 和 `attributes`。

### iOS
<a name="broadcast-mobile-token-exchange-receiving-updates-ios"></a>



```
class MyStageRenderer: NSObject, IVSStageRenderer {
    func stage(_ stage: IVSStage, participantMetadataDidUpdate participant: IVSParticipantInfo) {
        // participant will be a new IVSParticipantInfo instance with updated properties.
    }
}
```

### Android
<a name="broadcast-mobile-token-exchange-receiving-updates-android"></a>



```
private val stageRenderer = object : StageRenderer {
    override fun onParticipantMetadataUpdated(stage: Stage, participantInfo: ParticipantInfo) {
        // participantInfo will be a new ParticipantInfo instance with updated properties.
    }
}
```

## 更新可见性
<a name="broadcast-mobile-token-exchange-visibility"></a>

当参与者通过交换令牌以更新其 `userId` 或 `attributes` 时，这些更改的可见性取决于其当前的发布状态：
+ **如果参与者*尚未*发布：**该更新将以静默方式处理。如果最终发布，则所有 SDK 都将通过初始发布事件收到更新后的 `userId` 和 `attributes`。
+ **如果参与者*已经*发布：**该更新将立即广播。但是，仅移动 SDKs v1.37.0\$1 会收到该通知。对于 Web SDK、早期版本的移动 SDK 和服务器端合成的参与者，在参与者取消发布并重新发布前不会看到该更改。

下表澄清了支持矩阵：


| 参与者状态 | 观察者：移动 SDK 1.37.0\$1 | 观察者：早期版本的移动 SDK、Web SDK、服务器端合成 | 
| --- | --- | --- | 
| 尚未发布（然后开始） | ✅ 可见（通过参与者加入的事件在发布时可见） | ✅ 可见（通过参与者加入的事件在发布时可见） | 
| 已发布（从未重新发布） | ✅ 可见（通过参与者元数据更新事件立即可见） | ❌ 不可见 | 
| 已发布（取消发布并重新发布） | ✅ 可见（通过参与者元数据更新事件立即可见） | ⚠️ 最终可见（通过参与者加入的事件在重新发布时可见） | 