# 断开连接
> 用户流程:主动断开 / 网络异常断开 / 被踢出 → 清理会话 → 返回主页
> 对应程序流程:TsClient.disconnect() 或 onDisconnected(error) 或 onKicked(reason) → 停止写操作 → 清理会话状态
---
## 一、状态树
### Client 总状态树(断开相关部分)
```mermaid
flowchart TD
ROOT[Client 生命周期状态树
断开相关部分]
ROOT --> D[断开过程 Disconnecting
正在主动或被动结束会话]
ROOT --> X[已结束 Terminated
当前会话资源已清理]
D --> D1[GracefulDisconnect
用户调用 TsClient.disconnect 优雅退出]
D --> D2[UnexpectedDisconnect
网络或服务端导致 onDisconnected]
D --> D3[Kicked
onKicked 表示自己被踢]
X --> X1[清理命令请求
取消未完成的业务操作]
X --> X2[清理语音与传输
停止语音和文件连接]
X --> X3[清理会话状态
移除频道成员等临时事实]
```
---
## 二、时序:主动断开、异常断开与被踢
```mermaid
sequenceDiagram
participant UI as 上层应用
展示连接状态并触发退出
participant VM as ViewModel
收集 EventBus 事件
participant BRIDGE as TSBridge
管理连接生命周期
participant SDK as Go SDK (gomobile)
管理连接与断开事件
participant TS as TeamSpeak 服务器
关闭或终止客户端会话
participant STORE as 会话数据仓库
保存当前连接的临时事实
alt 用户主动断开
UI->>VM: DisconnectRequested
VM->>VM: 状态改为 disconnecting
VM->>BRIDGE: TSBridge.disconnect()
BRIDGE->>SDK: gomobile Disconnect
SDK->>TS: shutdown reason
TS-->>SDK: 连接关闭
SDK-->>BRIDGE: OnDisconnected 回调
BRIDGE->>BRIDGE: EventBus.emit(Disconnected)
BRIDGE->>VM: EventBus 分发 Disconnected 事件
else 网络或服务器异常
TS--xSDK: UDP 会话中断
SDK-->>BRIDGE: OnDisconnected 回调
BRIDGE->>BRIDGE: EventBus.emit(Disconnected)
BRIDGE->>VM: EventBus 分发 Disconnected 事件
else 自己被踢
TS-->>SDK: notifyclientleftview reasonid=4/5
SDK-->>BRIDGE: OnKicked 回调
BRIDGE->>BRIDGE: EventBus.emit(Kicked)
BRIDGE->>VM: EventBus 分发 Kicked 事件
end
VM->>VM: 停止语音与文件传输
VM->>STORE: 清理频道、成员和 Pending
STORE-->>UI: 返回已断开或失败页面
```
---
## 三、事件依赖
### 断开相关前置依赖矩阵
| 操作或事件 | 必须依赖 | 建议依赖 | 依赖失败时的处理 |
| --- | --- | --- | --- |
| `Disconnected` 事件 | 已注册 EventBus 事件收集 | 保存断开原因 | 停止全部依赖连接的操作 |
| `Kicked` 事件 | 已注册 EventBus 事件收集 | 区分 reasonid 4 和 5 | 清理会话且不伪装为普通成员离开 |
### 事件依赖图(断开阶段)
```mermaid
flowchart TD
DISCONNECTED[EventBus Disconnected 事件
接收连接终止事件] --> STOP[停止依赖操作
禁止命令、语音和新文件传输]
KICKED[EventBus Kicked 事件
接收自己被踢事件] --> STOP
STOP --> CLEAN[清理会话状态
移除当前连接的实体与 Pending]
```
### 服务端通知映射
| 服务端通知 | TSBridge 回调 → EventBus 事件 | 上层状态依赖 | 中文说明 |
| --- | --- | --- | --- |
| `notifyclientleftview`,`reasonid=4/5` 且为自己 | `OnKicked` → `Kicked` | 当前会话、语音、导航 | SDK 将自己被踢转换为独立事件 |
### 生命周期约束(断开相关)
- `TSBridge.disconnect()` 用于主动优雅退出;`Disconnected` 事件用于观察最终断开结果或异常断开。
- `Kicked` 事件来源于 `notifyclientleftview` 的特定原因,必须与普通成员离开区分。
- 断开后应停止语音、拒绝新命令,并清理只属于当前会话的状态。
### 权威性划分
| 数据 | 推荐权威来源 | 原因 |
| --- | --- | --- |
| 被踢状态 | EventBus `Kicked` 事件 | SDK 已从离开事件原因中识别自己被踢 |
### 统一实现原则(断开相关)
- **断开时统一清理当前会话资源。** 防止旧成员、频道和 Pending 污染下一次连接。