mirror of
https://github.com/lorsanstand/Aether.git
synced 2026-06-19 12:05:16 +03:00
6.2 KiB
6.2 KiB
Исправление проблемы с отправкой сообщений
Проблема
Когда пользователь отправлял сообщение, оно не появлялось в чате ни у отправителя, ни у получателя до перезагрузки страницы.
Корневые причины
1. Backend - Порядок операций
В файле 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:
- Приложение ждало получения сообщения через WebSocket перед показом в UI
- Без WebSocket подписки или задержки сообщение не отображалось
Исправление: Добавлено оптимистичное обновление UI:
- Сообщение добавляется в UI сразу после отправки с временным ID (
temp-{timestamp}) - При получении подтверждения через WebSocket, временное сообщение заменяется на реальное
- Если отправка завершится с ошибкой, временное сообщение удаляется
3. Backend - Логирование и обработка ошибок
В файле backend/app/services/messenger_service.py:
- Добавлена обработка исключений при отправке WebSocket сообщений
- Улучшено логирование (удален
print("test"), заменен наlog.info())
Что изменилось
Backend (3 файла)
-
service.py - 3 исправления:
send_message(): commit перед WebSocket отправкойupdate_message(): commit перед WebSocket отправкойdelete_message(): commit перед WebSocket отправкой
-
messenger_service.py - 2 исправления:
- Добавлен try-catch в
handle_message() - Заменено логирование с
print()наlog.info()
- Добавлен try-catch в
Frontend (1 файл)
- ChatPage.tsx - 2 исправления:
handleSendMessage(): добавлено оптимистичное обновление UIws.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 обновлена и синхронизирована со всеми участниками
Тестирование
-
Базовое тестирование:
- Откройте приложение в 2 браузерах для разных пользователей
- Отправьте сообщение из первого браузера
- Сообщение должно появиться сразу в обоих браузерах
- НЕ требуется перезагрузка страницы
-
Проверка временных сообщений:
- В DevTools откройте Console
- Ищите сообщение вида
temp-TIMESTAMPв начальном списке - После получения WebSocket ответа, ID должно измениться на UUID
-
Проверка обновлений:
- Отредактируйте сообщение
- Изменение должно появиться сразу у обоих пользователей
-
Проверка удаления:
- Удалите сообщение
- Оно должно исчезнуть сразу у обоих пользователей
Возможные проблемы и решения
Проблема: Сообщения все еще не появляются
Решение: Проверьте:
- Redis работает (
docker ps | grep redis) - Backend логирует: "Starting Redis PubSub subscriber"
- WebSocket подключение открыто (
ws.onopenв Console) - Сообщение отправляется: смотрите сетевые запросы в DevTools
Проблема: Дублирование сообщений
Решение: Может быть, если:
- Сообщение приходит через WebSocket и добавляется дважды
- Проверьте логику замены temp-сообщений в
onmessage
Проблема: Сообщение показывается с ошибкой
Решение:
- Проверьте формат данных в backend (логи Redis)
- Убедитесь, что Message тип совпадает со схемой