Spectra
Natywny klient desktopowy panelu Spectra na Windows i Linux, napisany w C#/.NET. Prawdziwe binarium z dostępem do systemu, nie opakowany Chromium. Ten sam widok co web, ale z natywną wydajnością i integracją z pulpitem.
Natywny klient administracyjny hostingu Spectra na Windows i Linux, zbudowany w C#/.NET na Avalonii. Ten sam obraz co panel web, ale jako prawdziwe binarium spięte wprost z rdzeniem platformy i jej ogromnym API frozcore/frozmod - z dostępem do systemu, natywną szybkością i logiką współdzieloną z resztą Spectry, a nie przepisaną drugi raz.
Wprowadzenie
Spectra to marka hostingu serwerów gier, dla której zbudowaliśmy pełne zaplecze panelowe. Ten case study dotyczy jednej, ale kluczowej części tej układanki: natywnego klienta desktopowego dla administratorów. To nie jest osobna aplikacja żyjąca obok panelu - to kolejna skóra na tym samym rdzeniu, rozmawiająca z tym samym backendem co wersja web. Żeby zrozumieć, dlaczego było to wyzwanie, najpierw trzeba zobaczyć, jak duży jest system pod spodem.
Klient desktopowy nie renderuje ładnych ekranów nad pustką. Stoi na pełnej platformie: provisioning serwerów, zarządzanie mocą, pliki, bazy danych, telemetria, rozliczenia i uprawnienia. Naszym zadaniem było dać administratorowi natywne okno na to wszystko - bez opakowanej przeglądarki i bez dublowania logiki, która i tak już żyła w panelu web.
Panel, w którym siedzi się cały dzień
Administrator serwerów gier nie zagląda do panelu raz na tydzień. Ma go otwartego przez osiem godzin obok konsoli, klienta gry i komunikatora. W takim trybie kolejna karta w przeglądarce to nie wygoda, tylko piąte koło u wozu: ginie w tłoku zakładek, nie ma własnej ikony na pasku, nie reaguje na skróty systemowe i nie widzi plików lokalnych.
Chcieliśmy dać ten sam widok co web, ale jako aplikację, która zachowuje się jak reszta programów na pulpicie. Jeden twardy warunek: bez opakowanego Chromium. Klient, który dokłada 200 MB pamięci na starcie tylko po to, żeby wyświetlić dokładnie to samo, mija się z celem, zanim zdąży się w pełni uruchomić. Skoro administrator ma tu spędzać większość dnia, aplikacja musi być lekka, natychmiastowa i „swoja" na jego systemie, a nie kolejnym oknem przeglądarki udającym program.
W liczbach
| Metryka | Wartość |
|---|---|
| Systemy z jednego kodu | Windows i Linux |
| Typowy ślad pamięci | ~40 MB |
| Wspólny rdzeń z panelem web | jeden |
| Widoki spięte z API | dziesiątki |
Czym właściwie jest Spectra pod spodem
Największym nieporozumieniem przy takim projekcie jest myślenie, że „to tylko panel". W rzeczywistości panel to cienka warstwa nad backendem, który robi ciężką robotę: uruchamia i zatrzymuje serwery gier, przydziela zasoby, trzyma bazy danych, streamuje logi i konsolę na żywo, pilnuje limitów i rozliczeń. Ten backend to rozbudowane API rodziny frozcore/frozmod - dziesiątki endpointów, zdarzenia w czasie rzeczywistym i model uprawnień, który decyduje, kto co widzi i co może zrobić.
Klient desktopowy musi rozmawiać dokładnie z tym samym API co panel web. Nie ma tu „uproszczonej wersji na desktop": jeśli administrator zmienia limit pamięci serwera albo restartuje instancję, robi to przez ten sam kontrakt, przez który robi to web. Dlatego zanim powstał choćby jeden ekran, trzeba było zrozumieć i ujarzmić skalę tego API - i to była realna część wyzwania, a nie sam wygląd okna.
Konsola i strumień logów działają na żywo. To nie odświeżanie co kilka sekund, tylko ciągły strumień zdarzeń z backendu - klient desktopowy subskrybuje go tak samo jak web, więc administrator widzi wyjście serwera w tej samej chwili, w której ono powstaje.
Jeden rdzeń, dwie skorupy
Logika domenowa - autoryzacja, model serwera, komendy zasilania, strumień logów, mapowanie uprawnień na to API - żyje w jednej bibliotece .NET. Panel web i klient desktopowy to dwie skorupy nad tym samym rdzeniem, więc poprawka w regule uprawnień albo w obsłudze endpointu ląduje w obu miejscach naraz. Znika cała klasa błędów „na webie działa, na desktopie nie".
Warstwę widoku rysuje Avalonia. To nie webview - kontrolki renderują się wprost przez Skia, tą samą ścieżką na Windows i na Linuksie, więc aplikacja wygląda identycznie na obu. Przy okazji dostaje realny dostęp do systemu plików, schowka i powiadomień, czego opakowana strona nigdy nie miała.
Stos
| Warstwa | Wybór | Po co tak |
|---|---|---|
| Język i runtime | C# / .NET | jeden język na logikę i UI, dobre narzędzia |
| Warstwa widoku | Avalonia (Skia) | natywny render, identyczny na Windows i Linux |
| Rdzeń domenowy | wspólna biblioteka .NET | ta sama logika i ten sam klient API co panel web |
| Warstwa sieci | typowany klient frozcore/frozmod | jeden kontrakt, web i desktop mówią tym samym |
| Dystrybucja | self-contained publish | jedno binarium, bez instalowania runtime u klienta |
Integracja z gigantycznym API
To była najcięższa część. Backend Spectry wystawia dziesiątki operacji: cykl życia serwera, konsola, pliki, bazy danych, harmonogramy zadań, kopie zapasowe, użytkownicy i uprawnienia, telemetria zasobów. Żeby klient desktopowy nie zamienił się w plątaninę wywołań, owinęliśmy całe API w jeden typowany klient w rdzeniu - z jednym miejscem na autoryzację, ponawianie i obsługę błędów.
wszystkie endpointy frozcore/frozmod za jednym interfejsem, z autoryzacją i ponawianiem w jednym miejscu, żeby ani web, ani desktop nie powtarzały tej logiki.
konsola, logi i telemetria jako subskrypcje zdarzeń, a nie odpytywanie w pętli; ten sam mechanizm co w panelu web.
to, co administrator może zobaczyć i zrobić, wynika z tych samych reguł co na webie, liczonych po stronie rdzenia, a nie „na oko" w UI.
odpowiedzi API trafiają wprost do natywnych kontrolek Avalonii, bez pośrednika w postaci DOM-u.
Owinięcie całego API w jeden klient w rdzeniu opłaciło się podwójnie: zmiana kontraktu po stronie backendu to jedna poprawka w bibliotece, którą web i desktop dostają tym samym commitem. Zero rozjazdu wersji, zero „a u mnie działa".
Wydajność i natywność
Skoro warunkiem brzegowym było „bez opakowanego Chromium", wydajność nie była dodatkiem, tylko celem. Avalonia rysuje interfejs bezpośrednio, bez silnika przeglądarki w środku, więc binarium z pełnym panelem waży ułamek tego, co ważyłby ten sam widok w Electronie, a startuje w ułamku sekundy.
Ślad pamięci na starcie (orientacyjnie, MB)
Do tego dochodzi to, czego przeglądarka nigdy nie dała: realny dostęp do systemu plików (pliki serwera wskazujesz wprost z dysku, bez wgrywania ich najpierw do przeglądarki), skróty systemowe, natywne powiadomienia i ikona na pasku zadań. Dla kogoś, kto siedzi w panelu cały dzień, to nie kosmetyka, tylko codzienna oszczędność czasu.
Jak to wszystko spięliśmy
Mając rdzeń z klientem API i skorupę na Avalonii, całość składała się w powtarzalny sposób. Kluczowe było to, żeby jedno źródło dawało dwa samodzielne binaria, realnie przetestowane na obu systemach, a nie tylko kompilujące się na oba.
autoryzacja, model serwera, komendy i klient API zostały odcięte od widoku web i przeniesione do osobnej biblioteki, która nie wie nic o tym, kto ją rysuje.
ten sam układ ekranów co web, ale w natywnych kontrolkach, spięty z rdzeniem przez zwykłe wywołania, nie przez HTTP do samego siebie.
publish na win-x64 i linux-x64 z tego samego źródła, każdy jako samodzielne binarium.
to samo uruchamiane realnie na Windowsie i na Linuksie, z wpięciem do prawdziwego backendu, nie tylko kompilujące się na oba.
Jaki jest finalny efekt współpracy?
Administrator dostaje program, który startuje w ułamku sekundy, trzyma się paska zadań jak każda inna aplikacja i pokazuje dokładnie te dane co panel web - bo pod spodem to ten sam kod i to samo API. Skróty systemowe działają, pliki z dysku da się wskazać bez wgrywania ich najpierw do przeglądarki, konsola i logi lecą na żywo, a okno nie ginie w gąszczu zakładek. Zamiast „strony w oknie" administrator dostaje narzędzie, które czuje się jak część jego systemu.
Po stronie Spectry zysk jest równie konkretny i wieloletni. Jedna logika i jeden klient API zamiast dwóch utrzymywanych ręcznie w zgodzie oznaczają, że rozwój platformy nie mnoży się przez liczbę skórek. Nowa reguła uprawnień, nowy endpoint w backendzie czy zmiana w modelu serwera ląduje w webie i na desktopie tym samym commitem. Znika cała klasa błędów synchronizacji, a klient desktopowy przestaje być osobnym projektem do utrzymania.
Najważniejsze jest jednak to, że desktop nie jest „wersją light". Rozmawia z tym samym, pełnym API frozcore/frozmod co panel web, więc administrator nie musi wracać do przeglądarki po funkcje, których w aplikacji zabrakło - bo nie zabrakło żadnej. To jest różnica między opakowaną stroną a prawdziwym, natywnym klientem platformy: ten drugi rośnie razem z backendem, zamiast ciągnąć się za nim.
Więcej projektów
Inne realizacje z tej samej kategorii - zobacz, jak podchodzimy do podobnych wyzwań.
Masz podobny projekt?
Napisz do nas - wycena jest bezpłatna i wraca w godzinę.



