Real-Time Data Flow - Testing & Verification Guide
Questo documento descrive i flussi di dati real-time fondamentali di Visla e come verificarli. Γ essenziale per il testing e il debugging del sistema.
π― Overviewβ
I dati GPS fluiscono dal dispositivo fisico fino alle app attraverso questa pipeline:
βββββββββββ TCP βββββββββββ Redis ββββββββββββ WS ββββββββββββ
β Device β βββββββΊ β Decoder β ββββββββββΊ β Services β βββββββΊ β Frontend β
β (GPS) β β (Java) β Streams β (Python) β β (Web/App)β
βββββββββββ βββββββββββ ββββββββββββ ββββββββββββ
1. π‘ Flusso Presenza (Online/Offline)β
Pipeline Completaβ
Device TCP Connect β Decoder (Java) β Redis Stream 'presence'
β β
SessionManager WebSocket Consumer
β β
publish("online") Devices Service (DB)
β β
Device TCP Disconnect ββββΊ Frontend (WS message)
publish("offline")
Come Verificareβ
1.1 Decoder (Java) - Verifica sessioni attiveβ
# SSH sul server
ssh pi@192.168.68.80
# Mostra sessioni TCP attive
docker logs decoder 2>&1 | grep -i "session\|online\|offline" | tail -20
1.2 Redis Stream - Verifica eventi presenceβ
# Leggi ultimi eventi dal stream presence
docker exec redis redis-cli XREAD COUNT 10 STREAMS presence 0
# Output atteso:
# "protocolId": "351840620257810"
# "event": "online" | "offline"
# "time": "1705829999999"
1.3 WebSocket Service - Verifica consumerβ
# Log del websocket consumer
docker logs websocket 2>&1 | grep -i "presence" | tail -20
1.4 Database - Verifica stato persistitoβ
docker exec postgres psql -U devices -d devices -c \
"SELECT device_id, name, status, last_update FROM user_device_attributes;"
1.5 Frontend - Verifica stato UIβ
- Apri DevTools β Network β WebSocket
- Cerca messaggi con
type: "device_status" - Verifica che lo stato UI corrisponda
β οΈ Problemi Comuni e Soluzioniβ
| Problema | Causa | Soluzione |
|---|---|---|
| Device sempre OFFLINE al reload | Timezone mancante in lastUpdate | Aggiungere Z suffix ai datetime |
| Device OFFLINE dopo 5min | Fallback frontend attivo | Verificare che decoder invii dati |
| Stato non si aggiorna real-time | Consumer non attivo | Riavviare websocket service |
| Status "online" in DB ma device spento | Decoder non ha inviato "offline" | Verificare SessionManager |
2. π Flusso Posizioniβ
Pipeline Completaβ
Device GPS Fix β Decoder β Redis 'positions:raw' β Positions Service
β
Validation + DB
β
Redis 'positions:validated'
β
WebSocket Consumer
β
Frontend (mappa)
Come Verificareβ
2.1 Decoder - Posizioni ricevuteβ
docker logs decoder 2>&1 | grep -i "position\|lat\|lon" | tail -10
2.2 Redis - Stream posizioniβ
# Posizioni grezze (dal decoder)
docker exec redis redis-cli XLEN positions:raw
# Posizioni validate (pronte per frontend)
docker exec redis redis-cli XLEN positions:validated
# Leggi ultimi messaggi
docker exec redis redis-cli XREAD COUNT 5 STREAMS positions:validated 0
2.3 Database - Posizioni salvateβ
docker exec postgres psql -U positions -d positions -c \
"SELECT device_id, latitude, longitude, fix_time
FROM positions ORDER BY id DESC LIMIT 5;"
2.4 Frontend - Posizioni sulla mappaβ
- DevTools β Network β WS
- Cerca messaggi
type: "position" - Verifica coordinate e timestamp
Dati Trasmessi con le Posizioniβ
Le "posizioni" in realtΓ contengono molto piΓΉ delle coordinate:
| Categoria | Campi |
|---|---|
| Posizione | latitude, longitude, altitude, speed, course |
| Tempo | deviceTime, fixTime, serverTime |
| QualitΓ GPS | satellites, hdop, valid |
| Batteria | batteryLevel, battery (voltage), charging |
| Rete | rssi (GSM signal), network |
| Veicolo | ignition, power (12V/24V), odometer |
| Allarmi | alarm, alarms[] |
3. β° Formato Timestamp e Timezoneβ
Regola Fondamentaleβ
Tutti i timestamp devono essere in UTC con suffix
Z
β
Corretto: "2026-01-21T09:58:10.252626Z"
β Errato: "2026-01-21T09:58:10.252626" (senza Z = interpretato come local time)
Chi Converte in Local Time?β
| Layer | ResponsabilitΓ |
|---|---|
| Decoder | Salva sempre in UTC |
| Database | Timestamp senza timezone (ma sempre UTC) |
| API Backend | Restituisce con suffix Z |
| Frontend | Converte in timezone utente da user.timezone |
Conversione Frontendβ
// L'utente ha impostato Europe/Rome
const userTimezone = user.timezone; // "Europe/Rome"
// Timestamp dal backend (UTC)
const serverTime = new Date("2026-01-21T10:00:00Z");
// Converti in local
const localTime = serverTime.toLocaleString('it-IT', {
timeZone: userTimezone
});
// Output: "21/01/2026, 11:00:00" (UTC+1)
Come Verificareβ
# API restituisce Z suffix?
curl -s http://localhost:3000/api/devices | jq '.[0].lastUpdate'
# Deve terminare con "Z"
4. π Altri Flussi Real-Timeβ
4.1 Eventiβ
Decoder β Positions Service (detect event) β Events Service β Redis 'events'
β
WebSocket + Notifications
Tipi di eventi:
deviceOnline/deviceOfflinedeviceMoving/deviceStoppedgeofenceEnter/geofenceExitalarm(SOS, vibration, speeding, etc.)ignitionOn/ignitionOff
4.2 Geofenceβ
Position Update β Geofence Service β Check intersections
β
Event: geofenceEnter/Exit
β
Notification Service
4.3 Notifiche Pushβ
Event Generated β Notification Service β FCM/APNs
β
Check user preferences
β
Send push / email / call
5. π§ͺ Checklist di Verificaβ
Pre-Deploy Checklistβ
- Presenza: Device online/offline riflette sessione TCP decoder
- Posizioni: Le coordinate arrivano dal decoder al frontend
- Timestamp: Tutti con suffix
Z(UTC) - Fallback 5min: Device senza dati per 5min = OFFLINE
- Reload pagina: Status corretto immediatamente (no flash OFFLINEβONLINE)
Componenti da Verificareβ
| Componente | Comando Verifica | Output Atteso |
|---|---|---|
| Decoder | docker logs decoder | TCP sessions, position parsing |
| Redis Streams | redis-cli XLEN presence | Count > 0 se device attivi |
| Positions Service | docker logs positions | Processing positions |
| WebSocket | docker logs websocket | Broadcasting to clients |
| Devices DB | Query user_device_attributes | status = online/offline |
Test End-to-Endβ
- Accendi device GPS β Verifica
status: onlinein DB e frontend - Spegni device GPS β Verifica
status: offlineentro 2 min (decoder timeout 100s) - Muovi device β Verifica posizione aggiornata su mappa
- Entra in geofence β Verifica evento e notifica
- Ricarica pagina β Status deve essere corretto immediatamente
6. π Metriche e Monitoringβ
Latenza Attesaβ
| Hop | Latenza Tipica |
|---|---|
| Device β Decoder | 1-2s (rete mobile) |
| Decoder β Redis | < 10ms |
| Redis β WebSocket | < 10ms |
| WebSocket β Browser | < 50ms |
| Totale E2E | < 3 secondi |
Redis Stream Healthβ
# Verifica consumer groups
docker exec redis redis-cli XINFO GROUPS positions:validated
# Verifica pending messages (lag)
docker exec redis redis-cli XPENDING positions:validated websocket-positions
7. π§ Troubleshooting Comuneβ
Device sempre OFFLINEβ
# 1. Verifica decoder ha sessione attiva
docker logs decoder 2>&1 | grep "351840620257810"
# 2. Verifica presenza su Redis
docker exec redis redis-cli XREAD COUNT 10 STREAMS presence 0
# 3. Verifica DB
docker exec postgres psql -U devices -d devices -c \
"SELECT status, last_update FROM user_device_attributes WHERE device_id = 44;"
Posizioni non si aggiornanoβ
# 1. Decoder riceve dati?
docker logs decoder 2>&1 | grep -i "position" | tail -5
# 2. Positions service processa?
docker logs positions 2>&1 | tail -20
# 3. WebSocket broadcast?
docker logs websocket 2>&1 | grep -i "position" | tail -10
Notifiche non arrivanoβ
# 1. Evento generato?
docker logs events 2>&1 | grep -i "event" | tail -10
# 2. Notification service attivo?
docker logs notifications 2>&1 | tail -20
# 3. Token FCM registrato?
docker exec postgres psql -U notification -d notification -c \
"SELECT user_id, platform FROM notification_tokens;"