Architettura waiter_ui e Transport
L'app cameriere (waiter_ui) e un'applicazione Flutter progettata per tablet Android. Comunica con il sistema POS tramite un layer di trasporto astratto che supporta sia connessioni cloud (NATS) sia comunicazione diretta LAN (WebSocket).
Struttura del Progetto
Il modulo waiter_ui segue l'architettura Flutter della piattaforma con Riverpod per lo state management e Isar per lo storage locale. I componenti principali sono:
- Splash screen: inizializza il trasporto tramite
TransportFactoryprima della connessione - Providers: gestiscono l'istanza Dio per le chiamate REST e il
waiterDbServiceProviderper l'accesso al database locale - Schermate operative: mappa sale, presa comanda, riepilogo tavolo, pagamento
RealtimeTransport: Astrazione del Trasporto
Il pattern centrale e l'interfaccia RealtimeTransport, che definisce un contratto comune per la messaggistica real-time. Le implementazioni concrete sono:
NatsTransport: comunicazione via server NATS cloud. Utilizza il pacchettodart_nats(importato esclusivamente in questo file). Adatto a installazioni con connessione internet stabile.LanWsTransport: client WebSocket che si connette al dispositivo master (cassa) sulla rete locale. Non richiede internet.LanMasterTransport: server WebSocket eseguito sulla cassa che funge da hub per i client LAN.AutoTransport: strategia di failover che utilizza il cloud come canale primario e commuta automaticamente su LAN in caso di disconnessione.
Tutti i consumer utilizzano RealtimeMessage (wrapper leggero) e accedono ai dati tramite la proprietà .data, non .string.
TransportFactory e Configurazione
La classe TransportFactory crea l'istanza di trasporto corretta in base alla configurazione salvata nel modello Isar WorkstationConfig:
| Campo | Descrizione |
|---|---|
transportMode | cloud, lan o auto |
isMaster | Se true, avvia LanMasterTransport |
lanServerPort | Porta del server WebSocket LAN (default: 8080) |
masterAddress | Indirizzo del master (se discovery disabilitato) |
autoDiscovery | Abilita la ricerca mDNS del master |
Il wiring avviene in splash_screen.dart: TransportFactory.create() viene invocato prima di connect().
Discovery mDNS
In modalita LAN con autoDiscovery attivo, il client utilizza LanDiscoveryService basato sul pacchetto bonsoir (v5.1.3) per individuare automaticamente il dispositivo master. Il servizio registrato e di tipo _pos-master._tcp. Questo elimina la necessita di configurare manualmente l'indirizzo IP del master.
Heartbeat e Protocollo LAN
Il protocollo LAN utilizza un envelope JSON per ogni messaggio:
{
"type": "message",
"deviceId": "waiter-01",
"subject": "orders.new",
"payload": { }
}
Il sistema di heartbeat invia un ping ogni 15 secondi. Dopo 3 ping consecutivi senza risposta, la connessione viene considerata in timeout. Questo meccanismo e implementato sia in LanMasterServer (lato cassa) che in LanWsTransport (lato cameriere).
Il matching dei subject supporta wildcard: * (singolo livello) e > (tutti i livelli successivi), compatibile con le convenzioni NATS.
FAQ
D: Dove viene importato dart_nats?
Esclusivamente in nats_transport.dart. Tutti gli altri file usano l'astrazione RealtimeTransport e RealtimeMessage.
D: Come si aggiunge un nuovo tipo di trasporto?
Implementare l'interfaccia RealtimeTransport e registrare la nuova classe in TransportFactory.create() con un nuovo valore di transportMode.
D: Il failover AutoTransport e trasparente per l'utente? Si, la commutazione avviene automaticamente. L'utente vede solo un breve indicatore di riconnessione nella barra superiore.