7.8 KiB
🔍 DIAGNOSTIC COMPLET - Kafka & WebSocket Temps Réel
Date : 28 janvier 2026
Problème : Messagerie, notifications et actualisations événementielles en temps réel ne fonctionnent pas avec Kafka
📋 RÉSUMÉ EXÉCUTIF
L'architecture temps réel utilise Kafka comme bus de messages entre les services métier et les WebSockets. Plusieurs problèmes critiques empêchent le bon fonctionnement :
- ❌ Heartbeat non démarré côté Flutter
- ⚠️ Serializers Kafka manquants (Quarkus auto-génère mais peut échouer)
- ⚠️ Configuration Kafka incomplète (bootstrap servers, health checks)
- ⚠️ WebSocket paths avec root-path
/afterwork - ⚠️ Bridges Kafka peuvent ne pas démarrer si Kafka indisponible
🔴 PROBLÈMES CRITIQUES IDENTIFIÉS
1. Heartbeat Non Démarré (Flutter)
Fichier : afterwork/lib/data/services/realtime_notification_service.dart
Problème : La méthode _startHeartbeat() existe mais n'est jamais appelée après une connexion réussie.
Ligne 88-101 : Après _isConnected = true, le heartbeat n'est pas démarré.
Impact :
- La connexion WebSocket peut timeout côté serveur
- Le statut de présence n'est pas maintenu
- Les notifications peuvent être perdues
Solution : Appeler _startHeartbeat() après la connexion réussie.
2. Serializers Kafka Non Explicites
Fichier : application.properties
Problème : Les serializers/deserializers sont omis avec le commentaire "Quarkus génère automatiquement". Cependant :
- Quarkus utilise Jackson pour sérialiser les DTOs
- Les DTOs doivent être correctement annotés
- En cas d'échec, les messages ne sont pas publiés dans Kafka
Solution : Ajouter explicitement les serializers Jackson ou vérifier que les DTOs sont sérialisables.
3. Configuration Kafka Bootstrap Servers
Fichier : application.properties et application-prod.properties
Problème :
- Production :
kafka-service.kafka.svc.cluster.local:9092(Kubernetes DNS) - Dev :
localhost:9092(override dansapplication-dev.properties)
Vérifications nécessaires :
- Kafka est-il déployé en production ?
- Le service DNS
kafka-service.kafka.svc.cluster.localest-il résolvable ? - Les health checks Kafka sont-ils activés ?
Solution : Vérifier le déploiement Kafka et ajouter des health checks.
4. WebSocket Paths avec Root-Path
Fichier : application-prod.properties
Problème : quarkus.http.root-path=/afterwork est configuré.
Impact potentiel :
- Les WebSockets peuvent nécessiter le path complet :
wss://api.lions.dev/afterwork/notifications/{userId} - Le frontend Flutter utilise :
ws://{baseUrl}/notifications/{userId}
Vérification : Tester si les WebSockets fonctionnent avec ou sans le root-path.
5. Bridges Kafka Peuvent Échouer Silencieusement
Fichiers : NotificationKafkaBridge.java, ChatKafkaBridge.java, etc.
Problème : Si Kafka n'est pas disponible au démarrage :
- Les bridges peuvent ne pas démarrer
- Aucune erreur visible si les exceptions sont catchées
- Les messages sont perdus sans notification
Solution : Ajouter des logs de démarrage et vérifier que les bridges sont actifs.
🟡 PROBLÈMES MOYENS
6. DTOs Événements Sans Annotations Jackson
Fichiers : NotificationEvent.java, ChatMessageEvent.java, etc.
Problème : Les DTOs utilisent Lombok mais peuvent manquer d'annotations Jackson pour la sérialisation JSON.
Solution : Vérifier que les DTOs sont correctement sérialisables avec Jackson.
7. Gestion d'Erreurs Kafka Silencieuse
Fichiers : MessageService.java, EventService.java, etc.
Problème : Les erreurs Kafka sont catchées et loggées mais ne remontent pas :
} catch (Exception e) {
System.out.println("[ERROR] Erreur lors de la publication dans Kafka : " + e.getMessage());
// Ne pas bloquer l'envoi du message si Kafka échoue
}
Impact : Les messages sont sauvegardés en DB mais pas diffusés en temps réel, sans notification à l'utilisateur.
✅ CORRECTIONS À APPLIQUER
Correction 1 : Démarrer le Heartbeat après Connexion
Fichier : afterwork/lib/data/services/realtime_notification_service.dart
_isConnected = true;
_startHeartbeat(); // ← AJOUTER CETTE LIGNE
if (!_isDisposed) {
notifyListeners();
}
Correction 2 : Ajouter Serializers Kafka Explicites
Fichier : application.properties
Ajouter pour chaque topic outgoing :
mp.messaging.outgoing.notifications.value.serializer=io.quarkus.kafka.client.serialization.JsonbSerializer
mp.messaging.outgoing.chat-messages.value.serializer=io.quarkus.kafka.client.serialization.JsonbSerializer
mp.messaging.outgoing.reactions.value.serializer=io.quarkus.kafka.client.serialization.JsonbSerializer
mp.messaging.outgoing.presence.value.serializer=io.quarkus.kafka.client.serialization.JsonbSerializer
Et pour chaque topic incoming :
mp.messaging.incoming.kafka-notifications.value.deserializer=io.quarkus.kafka.client.serialization.JsonbDeserializer
mp.messaging.incoming.kafka-chat.value.deserializer=io.quarkus.kafka.client.serialization.JsonbDeserializer
mp.messaging.incoming.kafka-reactions.value.deserializer=io.quarkus.kafka.client.serialization.JsonbDeserializer
mp.messaging.incoming.kafka-presence.value.deserializer=io.quarkus.kafka.client.serialization.JsonbDeserializer
Note : Quarkus peut utiliser Jackson au lieu de Jsonb. Vérifier la dépendance dans pom.xml.
Correction 3 : Vérifier les DTOs avec Annotations Jackson
Fichiers : Tous les DTOs d'événements
Ajouter si nécessaire :
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown = true)
public class NotificationEvent {
@JsonProperty("userId")
private String userId;
// ...
}
Correction 4 : Ajouter Logs de Démarrage des Bridges
Fichiers : Tous les bridges Kafka
Ajouter dans chaque bridge :
@PostConstruct
public void init() {
Log.info("[KAFKA-BRIDGE] Bridge démarré pour topic: notifications");
}
Correction 5 : Améliorer la Gestion d'Erreurs Kafka
Fichiers : Services qui publient dans Kafka
Au lieu de :
} catch (Exception e) {
System.out.println("[ERROR] Erreur Kafka");
}
Utiliser :
} catch (Exception e) {
Log.error("[ERROR] Erreur publication Kafka", e);
// Optionnel: Notifier l'utilisateur ou retry
}
🧪 TESTS DE VALIDATION
Test 1 : Vérifier Connexion Kafka
# En production (Kubernetes)
kubectl exec -it kafka-pod -- kafka-console-consumer --bootstrap-server localhost:9092 --topic notifications --from-beginning
Test 2 : Vérifier WebSocket
// Dans la console navigateur
const ws = new WebSocket('wss://api.lions.dev/afterwork/notifications/{userId}');
ws.onopen = () => console.log('Connected');
ws.onmessage = (e) => console.log('Message:', e.data);
Test 3 : Vérifier Heartbeat Flutter
- Ouvrir les logs Flutter
- Vérifier que des "Ping envoyé" apparaissent toutes les 30 secondes
📊 CHECKLIST DE VÉRIFICATION
- Kafka est déployé et accessible
- Les topics Kafka existent (
notifications,chat.messages,reactions,presence.updates) - Les bridges Kafka démarrent sans erreur
- Les WebSockets se connectent correctement
- Le heartbeat Flutter fonctionne
- Les messages sont publiés dans Kafka
- Les messages sont routés vers WebSocket
- Les clients reçoivent les notifications