mirror of
https://github.com/lorsanstand/Aether.git
synced 2026-06-19 12:05:16 +03:00
fix: send and recive message
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
# Исправление проблемы с отправкой сообщений
|
||||
|
||||
## Проблема
|
||||
Когда пользователь отправлял сообщение, оно не появлялось в чате ни у отправителя, ни у получателя до перезагрузки страницы.
|
||||
|
||||
## Корневые причины
|
||||
|
||||
### 1. **Backend - Порядок операций**
|
||||
В файле [backend/app/chats/service.py](backend/app/chats/service.py):
|
||||
- Сообщения отправлялись через WebSocket **ДО** коммита в БД
|
||||
- Это могло привести к отправке неполных или незапомненных данных
|
||||
|
||||
**Исправление:** Перемещены вызовы `await session.commit()` **перед** `await cls._send_ws_message()` во всех трех методах:
|
||||
- `send_message()` - отправка нового сообщения
|
||||
- `update_message()` - редактирование сообщения
|
||||
- `delete_message()` - удаление сообщения
|
||||
|
||||
### 2. **Frontend - Отсутствие оптимистичного обновления**
|
||||
В файле [frontend/src/pages/ChatPage.tsx](frontend/src/pages/ChatPage.tsx):
|
||||
- Приложение ждало получения сообщения через WebSocket перед показом в UI
|
||||
- Без WebSocket подписки или задержки сообщение не отображалось
|
||||
|
||||
**Исправление:** Добавлено оптимистичное обновление UI:
|
||||
- Сообщение добавляется в UI **сразу** после отправки с временным ID (`temp-{timestamp}`)
|
||||
- При получении подтверждения через WebSocket, временное сообщение заменяется на реальное
|
||||
- Если отправка завершится с ошибкой, временное сообщение удаляется
|
||||
|
||||
### 3. **Backend - Логирование и обработка ошибок**
|
||||
В файле [backend/app/services/messenger_service.py](backend/app/services/messenger_service.py):
|
||||
- Добавлена обработка исключений при отправке WebSocket сообщений
|
||||
- Улучшено логирование (удален `print("test")`, заменен на `log.info()`)
|
||||
|
||||
## Что изменилось
|
||||
|
||||
### Backend (3 файла)
|
||||
1. **service.py** - 3 исправления:
|
||||
- `send_message()`: commit перед WebSocket отправкой
|
||||
- `update_message()`: commit перед WebSocket отправкой
|
||||
- `delete_message()`: commit перед WebSocket отправкой
|
||||
|
||||
2. **messenger_service.py** - 2 исправления:
|
||||
- Добавлен try-catch в `handle_message()`
|
||||
- Заменено логирование с `print()` на `log.info()`
|
||||
|
||||
### Frontend (1 файл)
|
||||
1. **ChatPage.tsx** - 2 исправления:
|
||||
- `handleSendMessage()`: добавлено оптимистичное обновление UI
|
||||
- `ws.onmessage()`: улучшена логика замены временных сообщений на реальные
|
||||
|
||||
## Поток отправки сообщения (новый)
|
||||
|
||||
```
|
||||
1. Пользователь нажимает "Отправить"
|
||||
↓
|
||||
2. Frontend создает временное сообщение (temp-ID) и добавляет в UI
|
||||
↓
|
||||
3. Frontend отправляет запрос к backend (/chats/message)
|
||||
↓
|
||||
4. Backend сохраняет сообщение в БД
|
||||
↓
|
||||
5. Backend коммитит транзакцию в БД
|
||||
↓
|
||||
6. Backend отправляет сообщение в Redis (pub/sub)
|
||||
↓
|
||||
7. Redis PubSub listener отправляет WebSocket всем участникам чата
|
||||
↓
|
||||
8. Frontend получает сообщение через WebSocket и заменяет temp-сообщение на реальное
|
||||
↓
|
||||
9. UI обновлена и синхронизирована со всеми участниками
|
||||
```
|
||||
|
||||
## Тестирование
|
||||
|
||||
1. **Базовое тестирование:**
|
||||
- Откройте приложение в 2 браузерах для разных пользователей
|
||||
- Отправьте сообщение из первого браузера
|
||||
- Сообщение должно появиться **сразу** в обоих браузерах
|
||||
- НЕ требуется перезагрузка страницы
|
||||
|
||||
2. **Проверка временных сообщений:**
|
||||
- В DevTools откройте Console
|
||||
- Ищите сообщение вида `temp-TIMESTAMP` в начальном списке
|
||||
- После получения WebSocket ответа, ID должно измениться на UUID
|
||||
|
||||
3. **Проверка обновлений:**
|
||||
- Отредактируйте сообщение
|
||||
- Изменение должно появиться сразу у обоих пользователей
|
||||
|
||||
4. **Проверка удаления:**
|
||||
- Удалите сообщение
|
||||
- Оно должно исчезнуть сразу у обоих пользователей
|
||||
|
||||
## Возможные проблемы и решения
|
||||
|
||||
### Проблема: Сообщения все еще не появляются
|
||||
**Решение:** Проверьте:
|
||||
1. Redis работает (`docker ps | grep redis`)
|
||||
2. Backend логирует: "Starting Redis PubSub subscriber"
|
||||
3. WebSocket подключение открыто (`ws.onopen` в Console)
|
||||
4. Сообщение отправляется: смотрите сетевые запросы в DevTools
|
||||
|
||||
### Проблема: Дублирование сообщений
|
||||
**Решение:** Может быть, если:
|
||||
1. Сообщение приходит через WebSocket и добавляется дважды
|
||||
2. Проверьте логику замены temp-сообщений в `onmessage`
|
||||
|
||||
### Проблема: Сообщение показывается с ошибкой
|
||||
**Решение:**
|
||||
1. Проверьте формат данных в backend (логи Redis)
|
||||
2. Убедитесь, что Message тип совпадает со схемой
|
||||
Reference in New Issue
Block a user