BetterFrame/kiosk/src/main.rs
Mitchell R 16ab165b06 feat: live updates via WebSocket — server pushes, kiosk reloads
Server side:
- service-coordinator-ws: full WS implementation using ws package
- Auth via ?token=<kiosk_key> query param
- Coordinator registry for cross-plugin notification
- Admin mutations call notifyKiosks() → server pushes reload-bundle
- 30s ping/pong heartbeat

Kiosk side:
- Rust ws_client with tokio runtime + tokio-tungstenite
- Auto-reconnect with exponential backoff (1s → 60s cap)
- On reload-bundle: re-fetches bundle, re-renders layout
- Pong replies to server pings

Also fix: auto-suffix kiosk name on UNIQUE collision (re-pair with
same hostname no longer fails).
2026-05-10 22:15:58 +02:00

32 lines
1,012 B
Rust

mod server;
mod bundle;
mod pipeline;
mod ui;
mod ws_client;
pub enum ServerMsg {
ReloadBundle,
}
use gtk4::prelude::{ApplicationExt, ApplicationExtManual};
use gstreamer::prelude::PluginFeatureExtManual;
use tracing::info;
use tracing_subscriber::EnvFilter;
fn main() {
tracing_subscriber::fmt()
.with_env_filter(EnvFilter::from_default_env().add_directive("betterframe_kiosk=info".parse().unwrap()))
.init();
gstreamer::init().expect("Failed to init GStreamer");
// Demote Pi5 hw H265 decoder — rejects non-standard resolutions like 960x1080
if let Some(factory) = gstreamer::ElementFactory::find("v4l2slh265dec") {
factory.set_rank(gstreamer::Rank::NONE);
info!("demoted v4l2slh265dec to NONE (sw fallback)");
}
let app = ui::build_app();
// Pass empty args to GTK — server URL handled via env or argv directly
app.set_flags(gtk4::gio::ApplicationFlags::NON_UNIQUE);
std::process::exit(app.run_with_args::<&str>(&[]).into());
}