Spectra
Un client de bureau natif pour le panneau Spectra sous Windows et Linux, écrit en C#/.NET. Un vrai binaire avec accès au système, pas un Chromium emballé. La même vue que sur le web, mais avec des performances natives et une intégration au bureau.
Un client d'administration natif pour l'hébergement de serveurs de jeu Spectra sous Windows et Linux, construit en C#/.NET sur Avalonia. La même vue que le panneau web, mais sous forme de vrai binaire branché directement sur le cœur de la plateforme et son immense API frozcore/frozmod - avec accès au système, vitesse native et une logique partagée avec le reste de Spectra, non réécrite une seconde fois.
Introduction
Spectra est une marque d'hébergement de serveurs de jeu pour laquelle nous avons construit tout le socle du panneau. Cette étude de cas porte sur une pièce, mais cruciale, de ce puzzle : le client desktop natif pour les administrateurs. Ce n'est pas une application séparée vivant à côté du panneau - c'est une autre coque au-dessus du même cœur, dialoguant avec le même backend que la version web. Pour comprendre pourquoi c'était un défi, il faut d'abord voir à quel point le système en dessous est vaste.
Le client desktop ne dessine pas de jolis écrans au-dessus du vide. Il repose sur une plateforme complète : provisionnement de serveurs, gestion de la puissance, fichiers, bases de données, télémétrie, facturation et permissions. Notre tâche était de donner à l'administrateur une fenêtre native sur tout cela - sans navigateur empaqueté et sans dupliquer une logique qui vivait déjà dans le panneau web.
Un panneau dans lequel on reste toute la journée
Un administrateur de serveurs de jeu ne consulte pas le panneau une fois par semaine. Il le garde ouvert pendant huit heures, à côté de la console, du client de jeu et de la messagerie. Dans ce mode, un onglet de navigateur de plus n'est pas un confort, c'est une cinquième roue au carrosse : il se perd dans la foule des onglets, n'a pas sa propre icône dans la barre des tâches, ignore les raccourcis système et ne voit pas les fichiers locaux.
Nous voulions offrir la même vue que le web, mais sous forme d'application qui se comporte comme le reste des programmes du bureau. Une condition ferme : pas de Chromium empaqueté. Un client qui ajoute 200 Mo de mémoire au démarrage juste pour afficher exactement la même chose manque son but avant même d'avoir fini de se lancer. Si l'administrateur doit passer ici l'essentiel de sa journée, l'application doit être légère, immédiate et "chez elle" sur son système, et non une fenêtre de navigateur de plus faisant semblant d'être un programme.
En chiffres
| Métrique | Valeur |
|---|---|
| Systèmes à partir d'une seule base de code | Windows et Linux |
| Empreinte mémoire typique | ~40 Mo |
| Cœur partagé avec le panneau web | un |
| Vues branchées à l'API | des dizaines |
Ce qu'est vraiment Spectra en dessous
Le plus grand malentendu sur un projet comme celui-ci est de penser que "ce n'est qu'un panneau". En réalité, le panneau est une fine couche au-dessus d'un backend qui fait le gros du travail : il démarre et arrête les serveurs de jeu, alloue les ressources, détient les bases de données, diffuse les logs et la console en direct, et fait respecter les limites et la facturation. Ce backend est l'importante API frozcore/frozmod - des dizaines de points d'accès, des évènements en temps réel et un modèle de permissions qui décide qui voit quoi et ce qu'il peut faire.
Le client desktop doit dialoguer avec exactement la même API que le panneau web. Il n'y a pas de "version desktop simplifiée" : si l'administrateur change la limite de mémoire d'un serveur ou redémarre une instance, il le fait par le même contrat que celui qu'utilise le web. Ainsi, avant même qu'un seul écran n'existe, il fallait comprendre et maîtriser l'échelle de cette API - et c'était la vraie partie du défi, pas l'apparence de la fenêtre.
La console et le flux de logs fonctionnent en direct. Ce n'est pas un rafraîchissement toutes les quelques secondes, mais un flux continu d'évènements venant du backend - le client desktop s'y abonne exactement comme le web, si bien que l'administrateur voit la sortie d'un serveur à l'instant même où elle se produit.
Un cœur, deux coques
La logique métier - autorisation, modèle du serveur, commandes d'alimentation, flux de logs, mise en correspondance des permissions avec cette API - vit dans une seule bibliothèque .NET. Le panneau web et le client desktop sont deux coques au-dessus de ce cœur unique, si bien qu'une correction dans une règle de permission ou dans la manière de traiter un point d'accès atterrit aux deux endroits à la fois. Toute une classe de bugs "fonctionne sur le web, casse sur le desktop" disparaît tout simplement.
Avalonia dessine la couche de vue. Ce n'est pas un webview - les contrôles se rendent directement via Skia, par le même chemin sous Windows et Linux, si bien que l'application a un aspect identique sur les deux. Au passage, elle obtient un accès réel au système de fichiers, au presse-papiers et aux notifications qu'une page empaquetée n'a jamais eu.
Pile
| Couche | Choix | Pourquoi ainsi |
|---|---|---|
| Langage et runtime | C# / .NET | un seul langage pour la logique et l'UI, de bons outils |
| Couche de vue | Avalonia (Skia) | rendu natif, identique sous Windows et Linux |
| Cœur métier | bibliothèque .NET partagée | la même logique et le même client API que le panneau web |
| Couche réseau | client frozcore/frozmod typé | un contrat, le web et le desktop parlent la même langue |
| Distribution | self-contained publish | un binaire, pas d'installation de runtime chez le client |
Intégration avec une API géante
C'était la partie la plus lourde. Le backend de Spectra expose des dizaines d'opérations : cycle de vie du serveur, console, fichiers, bases de données, planifications de tâches, sauvegardes, utilisateurs et permissions, télémétrie des ressources. Pour éviter que le client desktop ne se transforme en enchevêtrement d'appels, nous avons enveloppé toute l'API dans un unique client typé dans le cœur - avec un seul endroit pour l'autorisation, les reprises et la gestion des erreurs.
chaque point d'accès frozcore/frozmod derrière une interface unique, avec autorisation et reprises au même endroit, pour que ni le web ni le desktop ne répètent cette logique.
console, logs et télémétrie sous forme d'abonnements aux évènements, et non de scrutation en boucle ; le même mécanisme que dans le panneau web.
ce qu'un administrateur peut voir et faire découle des mêmes règles que sur le web, calculées dans le cœur et non "à l'œil" dans l'UI.
les réponses de l'API atterrissent directement dans les contrôles natifs d'Avalonia, sans DOM intermédiaire.
Envelopper toute l'API dans un seul client dans le cœur a payé double : un changement de contrat côté backend est une unique correction dans la bibliothèque, que le web et le desktop reçoivent dans le même commit. Aucune dérive de version, aucun "chez moi ça marche".
Performance et nativité
Puisque la condition limite était "pas de Chromium empaqueté", la performance n'était pas un supplément mais l'objectif. Avalonia dessine l'interface directement, sans moteur de navigateur à l'intérieur, si bien qu'un binaire contenant le panneau complet pèse une fraction de ce que pèserait la même vue dans Electron, et démarre en une fraction de seconde.
Empreinte mémoire au démarrage (indicatif, Mo)
À cela s'ajoute tout ce qu'un navigateur n'a jamais donné : un accès réel au système de fichiers (vous pointez les fichiers du serveur directement depuis le disque, sans les téléverser d'abord dans un navigateur), les raccourcis système, les notifications natives et une icône dans la barre des tâches. Pour quelqu'un qui reste dans le panneau toute la journée, ce n'est pas de la cosmétique mais un gain de temps quotidien.
Ce que la collaboration a réellement apporté
L'administrateur obtient un programme qui démarre en une fraction de seconde, se tient dans la barre des tâches comme toute autre application et affiche exactement les données du panneau web - car en dessous, c'est le même code et la même API. Les raccourcis système fonctionnent, on peut choisir des fichiers sur le disque sans les téléverser d'abord dans un navigateur, la console et les logs défilent en direct, et la fenêtre ne se perd pas dans un fouillis d'onglets. Au lieu d'une "page dans une fenêtre", l'administrateur obtient un outil qui donne l'impression de faire partie de son système.
Du côté de Spectra, le gain est tout aussi concret et durable. Une seule logique et un seul client API au lieu de deux tenus à la main en accord signifient que développer la plateforme ne se multiplie pas par le nombre de coques. Une nouvelle règle de permission, un nouveau point d'accès dans le backend ou un changement dans le modèle du serveur atterrit sur le web et le desktop dans le même commit. Toute une classe de bugs de synchronisation disparaît, et le client desktop cesse d'être un projet séparé à maintenir.
Le plus important, cependant, c'est que le desktop n'est pas une "version légère". Il dialogue avec la même API frozcore/frozmod complète que le panneau web, si bien que l'administrateur n'a jamais à revenir au navigateur pour une fonctionnalité qui manquerait à l'application - car il n'en manquait aucune. C'est la différence entre une page empaquetée et un vrai client de plateforme natif : ce dernier grandit avec le backend au lieu de traîner derrière lui.
Plus de projets
D'autres réalisations de la même catégorie - découvrez comment nous abordons des défis similaires.
Vous avez un projet similaire ?
Contactez-nous - le devis est gratuit et arrive sous une heure.




Comment nous avons tout assemblé
Avec un cœur contenant le client API et une coque sur Avalonia, l'ensemble s'assemblait de manière reproductible. L'essentiel était qu'une seule source produise deux binaires autonomes, réellement testés sur les deux systèmes, et pas seulement compilés pour les deux.
autorisation, modèle du serveur, commandes et client API ont été détachés de la vue web et déplacés dans une bibliothèque séparée qui ne sait rien de qui la dessine.
la même disposition d'écrans que le web, mais en contrôles natifs, branchée au cœur par de simples appels, non par du HTTP vers lui-même.
publish vers win-x64 et linux-x64 depuis la même source, chacun comme binaire autonome.
la même chose exécutée réellement sous Windows et sous Linux, branchée au vrai backend, et pas seulement compilée pour les deux.
dotnet publish -c Release -r win-x64 --self-contained true dotnet publish -c Release -r linux-x64 --self-contained true