Ajout de la prise en charge de l'hôte du serveur pour les renderers

Cette mise à jour ajoute la prise en charge de l'adresse IP du serveur hébergeant les renderers UPnP. Cela permet d'afficher l'adresse IP des renderers dans l'interface utilisateur lorsqu'ils ont des noms identiques. Les modifications incluent :

- Mise à jour des types pour inclure le champ server_host
- Extraction de l'adresse IP depuis la location UPnP
- Affichage de l'adresse IP dans l'interface utilisateur pour les renderers avec des noms en double
- Modification des appels à register_device pour désactiver le SSDP lors de l'enregistrement des renderers

Cela améliore la clarté de l'interface utilisateur en permettant de distinguer les renderers avec des noms identiques mais hébergés sur des serveurs différents.
This commit is contained in:
2026-03-01 17:53:59 +01:00
parent de74c7b431
commit f9cd3063fb
7 changed files with 30 additions and 8 deletions

View File

@@ -74,7 +74,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let renderer_instance = server
.write()
.await
.register_device(MEDIA_RENDERER.clone())
.register_device(MEDIA_RENDERER.clone(), true)
.await
.expect("Failed to register MediaRenderer");
@@ -85,7 +85,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let server_instance = server
.write()
.await
.register_device(MEDIA_SERVER.clone())
.register_device(MEDIA_SERVER.clone(), true)
.await
.expect("Failed to register MediaServer");

View File

@@ -116,6 +116,15 @@ const offlineRenderers = computed(() =>
allRenderers.value.filter((r: RendererSummary) => !r.online),
);
// Noms de renderers qui apparaissent plus d'une fois (online + offline)
const duplicateNames = computed(() => {
const counts = new Map<string, number>();
for (const r of allRenderers.value) {
counts.set(r.friendly_name, (counts.get(r.friendly_name) ?? 0) + 1);
}
return new Set([...counts.entries()].filter(([, n]) => n > 1).map(([name]) => name));
});
function close() {
emit("update:modelValue", false);
}
@@ -296,7 +305,7 @@ async function handleTransferQueue(event: Event, targetRendererId: string) {
getProtocolLabel(
renderer.protocol,
)
}}
}}{{ duplicateNames.has(renderer.friendly_name) && renderer.server_host ? ` [${renderer.server_host}]` : '' }}
</span>
</div>
<div class="renderer-details">
@@ -383,7 +392,7 @@ async function handleTransferQueue(event: Event, targetRendererId: string) {
</div>
<div class="renderer-info">
<p class="renderer-name">
{{ renderer.friendly_name }}
{{ renderer.friendly_name }}{{ duplicateNames.has(renderer.friendly_name) && renderer.server_host ? ` [${renderer.server_host}]` : '' }}
</p>
<p
v-if="renderer.model_name"

View File

@@ -32,6 +32,7 @@ export interface RendererSummary {
protocol: RendererProtocolSummary;
capabilities: RendererCapabilitiesSummary;
online: boolean;
server_host?: string;
}
export interface RendererState {

View File

@@ -28,6 +28,8 @@ pub struct RendererSummary {
pub capabilities: RendererCapabilitiesSummary,
/// Renderer en ligne
pub online: bool,
/// Adresse IP du serveur hébergeant ce renderer (extraite de la location UPnP)
pub server_host: Option<String>,
}
/// Protocole exposé par le renderer

View File

@@ -102,6 +102,13 @@ async fn list_renderers(State(state): State<ControlPointState>) -> Json<Vec<Rend
.into_iter()
.map(|r| {
let info = r.info();
// Extraire le host depuis la location URL (ex: "http://192.168.1.10:8080/...")
let server_host = info.location()
.split("://").nth(1)
.and_then(|s| s.split('/').next())
.and_then(|s| s.split(':').next())
.map(|h| h.to_string())
.filter(|h| !h.is_empty());
RendererSummary {
id: r.id().0.clone(),
friendly_name: r.friendly_name().to_string(),
@@ -109,6 +116,7 @@ async fn list_renderers(State(state): State<ControlPointState>) -> Json<Vec<Rend
protocol: protocol_summary(&info.protocol()),
capabilities: capability_summary(&info.capabilities()),
online: r.is_online(),
server_host,
}
})
.collect::<Vec<_>>()

View File

@@ -97,6 +97,7 @@ pub trait UpnpServerExt {
async fn register_device(
&mut self,
device: Arc<Device>,
with_ssdp: bool,
) -> Result<Arc<DeviceInstance>, DeviceError>;
/// Retourne le nombre de devices enregistrés.
@@ -232,6 +233,7 @@ impl UpnpServerExt for Server {
async fn register_device(
&mut self,
device: Arc<Device>,
with_ssdp: bool,
) -> Result<Arc<DeviceInstance>, DeviceError> {
use tracing::info;
@@ -259,8 +261,8 @@ impl UpnpServerExt for Server {
.register(di.clone())
.map_err(|e| DeviceError::UrlRegistrationError(e))?;
// Annoncer via SSDP (si initialisé)
if self.ssdp_enabled() {
// Annoncer via SSDP (si initialisé et demandé)
if with_ssdp && self.ssdp_enabled() {
let ssdp_opt = SSDP_SERVER.read().unwrap();
if let Some(ref ssdp) = *ssdp_opt {
use crate::config_ext::UpnpConfigExt;
@@ -507,7 +509,7 @@ mod tests {
"Test Renderer".to_string(),
));
let instance = server.register_device(device).await.unwrap();
let instance = server.register_device(device, false).await.unwrap();
// Vérifier que le device est dans le registre
assert_eq!(server.device_count(), 1);

View File

@@ -263,7 +263,7 @@ impl RendererRegistry {
let mut server = server_arc.write().await;
server
.register_device(Arc::new(device))
.register_device(Arc::new(device), false)
.await
.map_err(|e| WebRendererError::RegistrationError(e.to_string()))?
};