feat: v2.0 – réorg docker/scripts, prod, résas, abonnements Wave, Flyway base vierge
This commit is contained in:
@@ -81,25 +81,30 @@ public class ChatWebSocketNext {
|
||||
String userId = connection.pathParam("userId");
|
||||
Log.debug("[CHAT-WS-NEXT] Message reçu de " + userId + ": " + message);
|
||||
|
||||
// Parser le message JSON
|
||||
com.fasterxml.jackson.databind.ObjectMapper mapper =
|
||||
new com.fasterxml.jackson.databind.ObjectMapper();
|
||||
Map<String, Object> messageData = mapper.readValue(message, Map.class);
|
||||
|
||||
String type = (String) messageData.get("type");
|
||||
Map<String, Object> raw = mapper.readValue(message, Map.class);
|
||||
String type = (String) raw.get("type");
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> data = (Map<String, Object>) raw.get("data");
|
||||
|
||||
switch (type) {
|
||||
case "message":
|
||||
handleChatMessage(messageData, userId);
|
||||
if (data != null) handleChatMessage(data, userId);
|
||||
else Log.warn("[CHAT-WS-NEXT] Message sans 'data'");
|
||||
break;
|
||||
case "typing":
|
||||
handleTypingIndicator(messageData, userId);
|
||||
if (data != null) handleTypingIndicator(data, userId);
|
||||
break;
|
||||
case "read":
|
||||
handleReadReceipt(messageData, userId);
|
||||
if (data != null) handleReadReceipt(data, userId);
|
||||
else Log.warn("[CHAT-WS-NEXT] Read receipt sans 'data'");
|
||||
break;
|
||||
case "ping":
|
||||
// Heartbeat - ignorer
|
||||
break;
|
||||
default:
|
||||
Log.warn("[CHAT-WS-NEXT] Type de message inconnu: " + type);
|
||||
Log.warn("[CHAT-WS-NEXT] Type inconnu: " + type);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
@@ -108,16 +113,17 @@ public class ChatWebSocketNext {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gère l'envoi d'un message de chat.
|
||||
* Le message est traité par MessageService qui publiera dans Kafka.
|
||||
* Gère l'envoi d'un message de chat via WebSocket.
|
||||
* Note: L'envoi principal passe par REST (POST /messages). Cette méthode
|
||||
* est pour compatibilité si le client envoie via WebSocket.
|
||||
*/
|
||||
private void handleChatMessage(Map<String, Object> messageData, String senderId) {
|
||||
private void handleChatMessage(Map<String, Object> data, String senderId) {
|
||||
try {
|
||||
UUID senderUUID = UUID.fromString(senderId);
|
||||
UUID recipientUUID = UUID.fromString((String) messageData.get("recipientId"));
|
||||
String content = (String) messageData.get("content");
|
||||
String messageType = messageData.getOrDefault("messageType", "text").toString();
|
||||
String mediaUrl = (String) messageData.get("mediaUrl");
|
||||
UUID recipientUUID = UUID.fromString((String) data.get("recipientId"));
|
||||
String content = (String) data.get("content");
|
||||
String messageType = data.getOrDefault("messageType", "text").toString();
|
||||
String mediaUrl = (String) data.get("mediaUrl");
|
||||
|
||||
// Enregistrer le message dans la base de données
|
||||
// MessageService publiera automatiquement dans Kafka
|
||||
@@ -146,13 +152,21 @@ public class ChatWebSocketNext {
|
||||
|
||||
/**
|
||||
* Gère les indicateurs de frappe.
|
||||
* data doit contenir recipientId (ID du destinataire) et isTyping.
|
||||
*/
|
||||
private void handleTypingIndicator(Map<String, Object> messageData, String userId) {
|
||||
private void handleTypingIndicator(Map<String, Object> data, String userId) {
|
||||
try {
|
||||
UUID recipientUUID = UUID.fromString((String) messageData.get("recipientId"));
|
||||
boolean isTyping = (boolean) messageData.getOrDefault("isTyping", false);
|
||||
Object recipientIdObj = data.get("recipientId");
|
||||
if (recipientIdObj == null) {
|
||||
Log.warn("[CHAT-WS-NEXT] Typing sans recipientId - ignoré");
|
||||
return;
|
||||
}
|
||||
UUID recipientUUID = UUID.fromString(recipientIdObj.toString());
|
||||
Object isTypingObj = data.get("isTyping");
|
||||
boolean isTyping = isTypingObj instanceof Boolean ? (Boolean) isTypingObj : Boolean.parseBoolean(String.valueOf(isTypingObj));
|
||||
|
||||
String response = buildJsonMessage("typing", Map.of(
|
||||
"conversationId", data.getOrDefault("conversationId", ""),
|
||||
"userId", userId,
|
||||
"isTyping", isTyping
|
||||
));
|
||||
@@ -168,22 +182,22 @@ public class ChatWebSocketNext {
|
||||
|
||||
/**
|
||||
* Gère les confirmations de lecture.
|
||||
* Envoie type "read" (format attendu par le client Flutter).
|
||||
*/
|
||||
private void handleReadReceipt(Map<String, Object> messageData, String userId) {
|
||||
private void handleReadReceipt(Map<String, Object> data, String userId) {
|
||||
try {
|
||||
UUID messageUUID = UUID.fromString((String) messageData.get("messageId"));
|
||||
UUID messageUUID = UUID.fromString((String) data.get("messageId"));
|
||||
|
||||
// Marquer le message comme lu
|
||||
Message message = messageService.markMessageAsRead(messageUUID);
|
||||
|
||||
if (message != null) {
|
||||
// Envoyer confirmation de lecture à l'expéditeur via WebSocket
|
||||
// (sera aussi publié dans Kafka par MessageService)
|
||||
UUID senderUUID = message.getSender().getId();
|
||||
String response = buildJsonMessage("read_receipt", Map.of(
|
||||
long now = System.currentTimeMillis();
|
||||
String timestampIso = java.time.Instant.ofEpochMilli(now).toString();
|
||||
String response = buildJsonMessage("read", Map.of(
|
||||
"messageId", messageUUID.toString(),
|
||||
"readBy", userId,
|
||||
"readAt", System.currentTimeMillis()
|
||||
"userId", userId,
|
||||
"timestamp", timestampIso
|
||||
));
|
||||
|
||||
sendToUser(senderUUID, response);
|
||||
|
||||
Reference in New Issue
Block a user