增加了发布通道
This commit is contained in:
@@ -60,25 +60,44 @@ Communication flows through two bridge layers:
|
||||
|
||||
**Event flow**: Go library → event queue → single consumer goroutine → JNI callback → Kotlin callback → ViewModel
|
||||
|
||||
### Android Layer Structure
|
||||
### Android MVVM + Repository Pattern
|
||||
|
||||
```
|
||||
android/app/src/main/java/com/tsmobile/app/
|
||||
├── MainActivity.kt # Entry point
|
||||
├── TSBridge.kt # Go bridge wrapper
|
||||
├── ui/
|
||||
│ ├── components/ # Reusable UI components
|
||||
│ ├── screens/ # Top-level screens
|
||||
│ ├── navigation/NavGraph.kt # App navigation
|
||||
│ └── theme/ # Material Design 3 theme
|
||||
└── viewmodel/ # State management
|
||||
├── ChannelViewModel.kt # Channel list & navigation
|
||||
├── ChatViewModel.kt # Text messaging
|
||||
├── ServerViewModel.kt # Connection & server info
|
||||
└── VoiceViewModel.kt # Voice communication
|
||||
Go Library → TSBridge (JNI) → ServerViewModel (callbacks) → Repository (state) → ViewModels → Compose Screens
|
||||
User Actions → Compose UI → ViewModel methods → TSBridge → Go Library
|
||||
```
|
||||
|
||||
State flows from ViewModels → Screens via `StateFlow`. User actions flow back via ViewModel methods.
|
||||
**Repository** (`data/Repository.kt`): Singleton object, single source of truth for shared state — channels, clients, channel→clients mapping, current channel, unread counts. Uses `ConcurrentHashMap` for thread-safe message archives (max 500 per session, keyed by `targetMode_targetId`).
|
||||
|
||||
**ViewModels**: Cross-references set by `NavGraph` (e.g. `serverViewModel.channelViewModel = channelViewModel`). `ServerViewModel` dispatches all bridge callbacks to other ViewModels.
|
||||
|
||||
**State machines** (sealed classes in `data/Models.kt`): `ConnectionState`, `MessageSendState`, `MessageDeliveryState`, `VoiceState`, `SyncState`, `ChannelSwitchState` — use `when` for pattern matching.
|
||||
|
||||
### Voice System Ownership Split
|
||||
|
||||
- **Go side** owns the full decode/mix pipeline: per-client jitter buffers, Opus decoders, stereo mixing. Delivers mixed PCM16 as 20ms frames (48kHz, interleaved stereo) via `onPCM` callback. Speaking detection: 400ms silence timeout.
|
||||
- **Kotlin side** owns capture: `AudioRecord` (mono, 48kHz) → `OpusEncoder` → `TSBridge.sendVoice()`. Noise suppressor support. Speaking detection via RMS threshold (0.015).
|
||||
|
||||
### Message Delivery Confirmation
|
||||
|
||||
Messages appear immediately as `PENDING` in UI. Server echo (`OnTextMessage` with matching content) confirms → `SENT`. 10-second timeout → `FAILED`. Duplicate detection prevents self-message re-archival.
|
||||
|
||||
### Navigation Routes
|
||||
|
||||
Four routes in `NavGraph.kt`: `server_config` (connection form) → `channel_list` (channel tree + members) → `chat` (text chat) → `kicked` (kick notification). Navigation driven by `ConnectionState` changes via `LaunchedEffect`.
|
||||
|
||||
### Known SDK Limitations
|
||||
|
||||
- **No channel CRUD events**: The SDK does not fire events for channel create/update/delete. Channel list is refreshed after 5 minutes of staleness or before channel switch operations.
|
||||
- **Unreliable ChannelID in enter events**: `notifycliententerview` ChannelID is not effective per SDK docs. Client enter/leave events trigger a full `clientlist` refresh instead of incremental updates.
|
||||
- **Auto-reconnect disabled by default**: Frequent reconnect attempts cause server-side rate limiting/bans.
|
||||
|
||||
### Thread Safety
|
||||
|
||||
- `TSClient.mu` mutex protects Go-side client access
|
||||
- `TSBridge.connectLock` synchronizes Kotlin-side connection lifecycle
|
||||
- `connectionGeneration` counter prevents stale callbacks from reaching current session
|
||||
- Event queue PCM events capped at 12 with oldest eviction to prevent buildup
|
||||
|
||||
## Critical Build Details
|
||||
|
||||
@@ -102,6 +121,10 @@ The `go/_patches/github.com/honeybbq/teamspeak-go/` directory contains modified
|
||||
|
||||
Do not remove this directory or the replace directive.
|
||||
|
||||
### Go Module and CGo
|
||||
|
||||
Go module name is `tsmobile`. Unlike upstream teamspeak-go (zero CGO), this project enables CGO for the Android libopus decoder. Pre-built static libraries live in `go/teamspeak/.opus/lib/{abi}/libopus.a` for all four Android ABIs.
|
||||
|
||||
## Common Issues
|
||||
|
||||
### "javac: 非法字符" or "GBK unmappable character"
|
||||
@@ -119,8 +142,13 @@ Missing `-Wl,--hash-style=both` flag. Rebuild AAR with correct flags.
|
||||
### "Unresolved reference: teamspeak"
|
||||
AAR not compiled or not in `android/app/libs/teamspeak.aar`. Run Step 1 of manual build.
|
||||
|
||||
## Error Conventions
|
||||
|
||||
- **Go bridge**: Empty string return = success, non-empty = error message. All IDs are strings for JSON transport.
|
||||
- **Kotlin**: Chinese-language user-facing errors. `ServerViewModel.classifyError()` maps raw errors to friendly messages. `ChannelViewModel.mapMoveError()` handles channel switch errors.
|
||||
|
||||
## Testing
|
||||
|
||||
Run from IDE with connected device or emulator. Check Logcat in IDE for runtime logs.
|
||||
|
||||
No automated test suite currently exists.
|
||||
Go unit tests exist for the audio receive pipeline (`go/teamspeak/receive_audio_test.go`): `cd go && go test ./teamspeak/`
|
||||
|
||||
Reference in New Issue
Block a user