fix: subscription event loop, session_id for reconnect, audio feature gate

- Fix event_rx consumed by take() - now locks and polls each time
- Add session_id to restart subscription on reconnect
- Remove duplicate code in Connect handler
- Gate audio behind optional cpal feature (needs ALSA dev libs)
- tsclientlib audio feature disabled in workspace (needs cmake)
- 69 tests passing, clippy clean
This commit is contained in:
ReTeamSpeak
2026-05-12 23:06:19 +09:00
parent 2bbd1c41fd
commit 0d805269b5
2 changed files with 29 additions and 20 deletions
+2
View File
@@ -18,6 +18,7 @@ serde_json = { workspace = true }
tracing = { workspace = true }
tracing-subscriber = { workspace = true }
chrono = { workspace = true }
cpal = { version = "0.15", optional = true }
shared = { workspace = true }
tscore = { workspace = true }
@@ -27,3 +28,4 @@ tsproto-packets = { workspace = true }
[features]
default = []
audio = ["dep:cpal"]
+27 -20
View File
@@ -115,6 +115,7 @@ struct App {
query_error: Option<String>,
error: Option<String>,
identity_level: u8,
session_id: u64,
}
impl App {
@@ -157,6 +158,7 @@ impl App {
query_error: None,
error: None,
identity_level: 0,
session_id: 0,
};
(app, Task::none())
@@ -203,14 +205,11 @@ impl App {
Some(self.password.clone())
};
let handle_store = self.handle.clone();
self.error = None;
self.connected = false;
let event_rx_store = self.event_rx.clone();
self.error = None;
self.connected = false;
self.session_id += 1;
Task::perform(
async move {
@@ -579,24 +578,32 @@ impl App {
return Subscription::none();
}
let event_rx = self.event_rx.clone();
let session_id = self.session_id;
Subscription::run_with_id(
1u64,
session_id,
iced::stream::channel(100, move |mut sender| async move {
let rx = {
let mut guard = event_rx.lock().await;
guard.take()
};
let Some(mut rx) = rx else { return };
while let Some(event) = rx.recv().await {
let is_disconnect = matches!(
event,
TsEvent::Disconnected | TsEvent::Error(_)
);
if sender.send(Message::TsEvent(event)).await.is_err() {
break;
}
if is_disconnect {
break;
loop {
let event = {
let mut guard = event_rx.lock().await;
match guard.as_mut() {
Some(rx) => rx.recv().await,
None => break,
}
};
match event {
Some(event) => {
let is_disconnect = matches!(
event,
TsEvent::Disconnected | TsEvent::Error(_)
);
if sender.send(Message::TsEvent(event)).await.is_err() {
break;
}
if is_disconnect {
break;
}
}
None => break,
}
}
}),