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 = { workspace = true }
tracing-subscriber = { workspace = true } tracing-subscriber = { workspace = true }
chrono = { workspace = true } chrono = { workspace = true }
cpal = { version = "0.15", optional = true }
shared = { workspace = true } shared = { workspace = true }
tscore = { workspace = true } tscore = { workspace = true }
@@ -27,3 +28,4 @@ tsproto-packets = { workspace = true }
[features] [features]
default = [] default = []
audio = ["dep:cpal"]
+27 -20
View File
@@ -115,6 +115,7 @@ struct App {
query_error: Option<String>, query_error: Option<String>,
error: Option<String>, error: Option<String>,
identity_level: u8, identity_level: u8,
session_id: u64,
} }
impl App { impl App {
@@ -157,6 +158,7 @@ impl App {
query_error: None, query_error: None,
error: None, error: None,
identity_level: 0, identity_level: 0,
session_id: 0,
}; };
(app, Task::none()) (app, Task::none())
@@ -203,14 +205,11 @@ impl App {
Some(self.password.clone()) Some(self.password.clone())
}; };
let handle_store = self.handle.clone(); let handle_store = self.handle.clone();
self.error = None;
self.connected = false;
let event_rx_store = self.event_rx.clone(); let event_rx_store = self.event_rx.clone();
self.error = None; self.error = None;
self.connected = false; self.connected = false;
self.session_id += 1;
Task::perform( Task::perform(
async move { async move {
@@ -579,24 +578,32 @@ impl App {
return Subscription::none(); return Subscription::none();
} }
let event_rx = self.event_rx.clone(); let event_rx = self.event_rx.clone();
let session_id = self.session_id;
Subscription::run_with_id( Subscription::run_with_id(
1u64, session_id,
iced::stream::channel(100, move |mut sender| async move { iced::stream::channel(100, move |mut sender| async move {
let rx = { loop {
let mut guard = event_rx.lock().await; let event = {
guard.take() let mut guard = event_rx.lock().await;
}; match guard.as_mut() {
let Some(mut rx) = rx else { return }; Some(rx) => rx.recv().await,
while let Some(event) = rx.recv().await { None => break,
let is_disconnect = matches!( }
event, };
TsEvent::Disconnected | TsEvent::Error(_) match event {
); Some(event) => {
if sender.send(Message::TsEvent(event)).await.is_err() { let is_disconnect = matches!(
break; event,
} TsEvent::Disconnected | TsEvent::Error(_)
if is_disconnect { );
break; if sender.send(Message::TsEvent(event)).await.is_err() {
break;
}
if is_disconnect {
break;
}
}
None => break,
} }
} }
}), }),