Já dělám něco podobného, měřicí aplikaci co sbírá data z různých snímačů, něco nad nimi počítá, ukládá je na disk, celé se to v realtime někde ukazuje, měření se dá spustit s nějakými parametry a ukončit.
Aplikace je rozdělená na dvě nezávislé části jako klient/server, na GUI(klient) a něco co interně nazýváme "jádro"(server). Jádro se stará o samotné spouštění/ukončování měření, vyčítání zpracování ukládání dat.
GUI a jádro spolu komunikují výhradně po TCP zprávami zabalenými do Protocol buffers (dnes bych asi použil FlatBuffers). Konkrétní podoba zpráv je na tom skoro to nejdůležitější, vlastně ti určuje celou architekturu aplikace. Při návrhu zpráv se držíme zhruba těchto zásad:
- Veškerá komunikace je Request(GUI) - Response(jádro)
- GUI je možné kdykoliv ukončit a později znovu spustit, případně je dokonce možné mít připojených víc GUI najednou, aniž by to nějak ovlivnilo běh jádra. Když se GUI pustí později, dovede od jádra vyčíst stav a ukázat příslušné ovládaci a zobrazovací prvky.
- jádro a GUI spolu nemohou komunikovat nijak jinak, tj. GUI má např. zakázané hrabat do uložených datových nebo konfiguračních souborů. Tím je mj. možné mít obojí puštěné na různých počítačích.
V praxi je implementován request "Jádro, v jakém jsi stavu", to odpoví něco jako "připraven měřit, spouštím měření, měřím, ukončuji měření, ..". GUI se na stav periodicky ptá, protože se kdykoliv může přihodit, že nějaká externí událost (selhání měření, jiný klient) stav změní.
Dále je implementován request "Jádro, pošli (poslední) odměřená data", který dává smysl jen ve stavu "měří se".
Dále jsou implementovány povely jako "spusť měření, ukonči měření" atp. Důležité je, že OK odpověď od jádra neznamená "OK, spustil jsem měření", ale "OK, přijal jsem povel ke spuštění měření". GUI nesmí po přijetí kladné odpovědi na spuštění měření předpokládat, že měření skutečně běží a třeba změnit obrazovku, to dělá pouze v reakci na request "Jádro, v jakém jsi stavu".
Je toho samozřejmě mnohem víc, ale tohle je ten důležitý základ.
Tenhle přístup se nám dost vyplatil, během let jsme dokonce postupně úplně přepsali GUI (Scala -> C#) i jádro (C++ -> Rust), a nové GUI nám funguje se starým jádrem a naopak, to bylo dost praktické. Striktní oddělení a protokol jasně definují zodpovědnosti.
V principu by, abych se obloukem vrátil k původní otázce, klidně bylo možné udělat GUI klienta jako webovou aplikaci. Jestli máte prostor pro experimentování, určitě zauvažujte nad použitím jazyka Elm.