mirror of
https://github.com/lorsanstand/Aether.git
synced 2026-06-19 12:05:16 +03:00
111 lines
6.2 KiB
Markdown
111 lines
6.2 KiB
Markdown
# Исправление проблемы с отправкой сообщений
|
||
|
||
## Проблема
|
||
Когда пользователь отправлял сообщение, оно не появлялось в чате ни у отправителя, ни у получателя до перезагрузки страницы.
|
||
|
||
## Корневые причины
|
||
|
||
### 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 тип совпадает со схемой
|