Merge pull request 'corrige un bug de détection des servers online' (#38) from push-vnqkompntkws into main
All checks were successful
Build and Push Docker Image / build (push) Successful in 28m35s
All checks were successful
Build and Push Docker Image / build (push) Successful in 28m35s
Reviewed-on: #38
This commit was merged in pull request #38.
This commit is contained in:
@@ -12,7 +12,8 @@ pub struct UpnpDiscoveryManager {
|
||||
}
|
||||
|
||||
impl UpnpDiscoveryManager {
|
||||
pub fn new(device_registry: Arc<RwLock<DeviceRegistry>>,
|
||||
pub fn new(
|
||||
device_registry: Arc<RwLock<DeviceRegistry>>,
|
||||
udn_cache: Arc<Mutex<UDNRegistry>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
@@ -42,10 +43,15 @@ impl UpnpDiscoveryManager {
|
||||
|
||||
if let Some(udn) = extract_udn_from_usn(&usn) {
|
||||
if alive {
|
||||
// ✅ Check cache
|
||||
if UDNRegistry::should_fetch(self.udn_cache.clone(), &udn, max_age as u64) {
|
||||
// ✅ Fetch + parse
|
||||
if let Ok(info) = ParsedDeviceDescription::new(&udn, &location, &server_header,5) {
|
||||
// Check if we should fetch the full device description
|
||||
let should_fetch =
|
||||
UDNRegistry::should_fetch(self.udn_cache.clone(), &udn, max_age as u64);
|
||||
|
||||
if should_fetch {
|
||||
// Fetch + parse the device description
|
||||
if let Ok(info) =
|
||||
ParsedDeviceDescription::new(&udn, &location, &server_header, 5)
|
||||
{
|
||||
if let Some(renderer_info) = info.build_renderer() {
|
||||
if let Ok(mut reg) = self.device_registry.write() {
|
||||
reg.push_renderer(&renderer_info, max_age);
|
||||
@@ -56,6 +62,13 @@ impl UpnpDiscoveryManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Even if we don't fetch, we MUST update last_seen to prevent timeout
|
||||
// This is critical: SSDP Alive messages arrive more frequently than max_age/2,
|
||||
// and we need to acknowledge them to keep the device online
|
||||
if let Ok(mut reg) = self.device_registry.write() {
|
||||
reg.refresh_device_presence(&udn, max_age);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if let Ok(mut reg) = self.device_registry.write() {
|
||||
@@ -64,11 +77,8 @@ impl UpnpDiscoveryManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
fn extract_udn_from_usn(usn: &str) -> Option<String> {
|
||||
let lower = usn.trim().to_ascii_lowercase();
|
||||
if let Some(idx) = lower.find("uuid:") {
|
||||
|
||||
@@ -130,46 +130,46 @@ impl MusicRenderer {
|
||||
}
|
||||
|
||||
/// Returns the protocol.
|
||||
fn protocol(&self) -> RendererProtocol {
|
||||
pub fn protocol(&self) -> RendererProtocol {
|
||||
self.info.protocol()
|
||||
}
|
||||
|
||||
fn is_upnp(&self) -> bool {
|
||||
pub fn is_upnp(&self) -> bool {
|
||||
match &*self.backend.lock().expect("Backend mutex poisoned") {
|
||||
MusicRendererBackend::Upnp(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_openhome(&self) -> bool {
|
||||
pub fn is_openhome(&self) -> bool {
|
||||
match &*self.backend.lock().expect("Backend mutex poisoned") {
|
||||
MusicRendererBackend::OpenHome(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_linkplay(&self) -> bool {
|
||||
pub fn is_linkplay(&self) -> bool {
|
||||
match &*self.backend.lock().expect("Backend mutex poisoned") {
|
||||
MusicRendererBackend::LinkPlay(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_arylictcp(&self) -> bool {
|
||||
pub fn is_arylictcp(&self) -> bool {
|
||||
match &*self.backend.lock().expect("Backend mutex poisoned") {
|
||||
MusicRendererBackend::ArylicTcp(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_chromecast(&self) -> bool {
|
||||
pub fn is_chromecast(&self) -> bool {
|
||||
match &*self.backend.lock().expect("Backend mutex poisoned") {
|
||||
MusicRendererBackend::Chromecast(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_hybridupnparylic(&self) -> bool {
|
||||
pub fn is_hybridupnparylic(&self) -> bool {
|
||||
match &*self.backend.lock().expect("Backend mutex poisoned") {
|
||||
MusicRendererBackend::HybridUpnpArylic { .. } => true,
|
||||
_ => false,
|
||||
|
||||
@@ -257,6 +257,41 @@ impl DeviceRegistry {
|
||||
}
|
||||
}
|
||||
|
||||
/// Updates the last_seen timestamp for a device without fetching its full description.
|
||||
///
|
||||
/// This is critical for keeping devices online when SSDP Alive messages arrive
|
||||
/// more frequently than the UDN cache refresh interval (max_age/2).
|
||||
pub fn refresh_device_presence(&mut self, udn: &str, max_age: u32) {
|
||||
let lookup = udn.to_ascii_lowercase();
|
||||
|
||||
if let Some(id) = self.udn_index.get(&lookup) {
|
||||
if let Some(device) = self.devices.get(id) {
|
||||
let was_online = device.is_online();
|
||||
device.has_been_seen_now(max_age);
|
||||
|
||||
// If device was offline and came back online, broadcast Online event
|
||||
if !was_online {
|
||||
if device.is_a_music_renderer() {
|
||||
if let Ok(renderer) = device.as_music_renderer() {
|
||||
self.renderer_bus.broadcast(RendererEvent::Online {
|
||||
id: id.clone(),
|
||||
info: renderer.info().basic_info(),
|
||||
});
|
||||
}
|
||||
}
|
||||
if device.is_a_music_server() {
|
||||
if let Ok(server) = device.as_music_server() {
|
||||
self.server_bus.broadcast(MediaServerEvent::Online {
|
||||
server_id: id.clone(),
|
||||
info: server.basic_info(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn device_says_byebye(&mut self, udn: &str) {
|
||||
let lookup = udn.to_ascii_lowercase();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user