Device Presence System
Il sistema di presenza traccia lo stato online/offline dei dispositivi GPS in tempo reale.
Architettura
Flusso Eventi
Device si connette
- Decoder rileva nuova connessione TCP
- Pubblica su stream
presence:{"unique_id": "019175767229", "event": "online", "time": 1702...} - db-persister consuma e aggiorna DB:
UPDATE devices SET status = 'online', last_update = NOW() WHERE unique_id = '...'; - websocket consuma e fa broadcast ai client:
{"type": "device_status", "data": {"deviceId": 1, "status": "online"}}
Device si disconnette
Due scenari:
| Tipo | Descrizione | Tempo rilevamento |
|---|---|---|
| Disconnessione pulita | Device invia FIN packet TCP | Immediato |
| Disconnessione sporca | Device si spegne improvvisamente | Timeout TCP (30-120s) |
Disconnessione TCP
Disconnessione "pulita" (FIN packet)
Device GPS --> FIN --> Server
Server --> ACK --> Device GPS
Server --> FIN --> Device GPS
Device GPS --> ACK --> Server
Risultato: Disconnessione immediata, il decoder rileva subito e pubblica offline
Disconnessione "sporca" (device si spegne)
Device GPS ❌ (nessun pacchetto)
Server --> aspetta... aspetta... --> TIMEOUT!
Risultato: Il server non sa che il device è morto finché non scade il timeout TCP
Soluzioni per Timeout
| Metodo | Come funziona |
|---|---|
| TCP Keep-Alive | Il server invia periodicamente pacchetti "sei vivo?" |
| Application-level heartbeat | Il device deve inviare un pacchetto ogni X secondi |
| Timeout applicativo | Se non ricevi dati per X minuti → considera offline |
Stream Redis
presence
Stream per eventi online/offline dei device.
# Visualizza ultimi 5 eventi
docker exec redis redis-cli XRANGE presence - + COUNT 5
# Leggi in tempo reale
docker exec redis redis-cli XREAD BLOCK 0 STREAMS presence $
# Conta eventi
docker exec redis redis-cli XLEN presence
Formato messaggio:
unique_id: "019175767229"
device_id: "1" # ID interno decoder (non database!)
event: "online" | "offline"
time: "1702..."
remote: "192.168.1.1:12345"
Consumer
db-persister
Consuma stream presence con consumer group persister-workers:
- Aggiorna
devices.statusnel database - Aggiorna
devices.last_update - Log:
Device XXXXX status updated to 'online'
websocket
Consuma stream presence con xread semplice:
- Cerca
device_idreale nel DB tramiteunique_id - Broadcasting
device_statusa tutti gli utenti autorizzati - Log:
Broadcasted device X status 'online' to Y users
Web App
La web-app ottiene lo status in due modi:
-
All'avvio - REST API
GET /api/devices:{"id": 1, "name": "PET", "status": "online", ...} -
In tempo reale - WebSocket:
{"type": "device_status", "data": {"deviceId": 1, "status": "online"}}
Grafana Dashboard
Dashboard Device Presence Monitor mostra:
- 🟢 Devices Online Now
- 🔴 Devices Offline (5m)
- 📈 Online/Offline Events Over Time
- 📊 Status Distribution
- 📜 Presence Events Log