docs: добавлены руководства по диагностике WebSocket 1006
- WEBSOCKET_1006_QUICK_GUIDE.md - быстрая шпаргалка (5 минут) - WEBSOCKET_1006_PRIORITY_CHECK.md - приоритетная диагностика - WEBSOCKET_1006_DIAGNOSTIC_PLAN.md - полный план диагностики - WEBSOCKET_1006_SUMMARY.md - сводка по проблеме - Обновлен README.md с ссылками на документацию
This commit is contained in:
parent
432224b3ba
commit
c7a3f475e3
21
README.md
21
README.md
@ -318,6 +318,27 @@ python manage.py send_pending_notifications --batch-size=100
|
||||
- Настройте файрвол
|
||||
- Используйте переменные окружения для секретов
|
||||
|
||||
## Документация и troubleshooting
|
||||
|
||||
### Руководства по функциям
|
||||
- [MESSAGE_EDITING_ANALYSIS.md](MESSAGE_EDITING_ANALYSIS.md) - Редактирование сообщений
|
||||
- [POLLS_IMPLEMENTATION.md](POLLS_IMPLEMENTATION.md) - Система опросов
|
||||
- [PERSONAL_CALENDAR_FEATURE.md](PERSONAL_CALENDAR_FEATURE.md) - Персональный календарь
|
||||
- [REACTIONS_FROM_DATABASE.md](REACTIONS_FROM_DATABASE.md) - Система реакций
|
||||
- [REQUESTS_RECIPIENTS_PLAN.md](REQUESTS_RECIPIENTS_PLAN.md) - Система получателей заявок
|
||||
|
||||
### WebSocket диагностика
|
||||
- **[WEBSOCKET_1006_QUICK_GUIDE.md](WEBSOCKET_1006_QUICK_GUIDE.md)** ⚡ - **Быстрая шпаргалка (5 минут)**
|
||||
- [WEBSOCKET_1006_PRIORITY_CHECK.md](WEBSOCKET_1006_PRIORITY_CHECK.md) - Приоритетная диагностика
|
||||
- [WEBSOCKET_1006_DIAGNOSTIC_PLAN.md](WEBSOCKET_1006_DIAGNOSTIC_PLAN.md) - Полный план диагностики
|
||||
- [WEBSOCKET_KEEPALIVE_FIX.md](WEBSOCKET_KEEPALIVE_FIX.md) - Исправление keepalive
|
||||
- [WEBSOCKET_UNIFIED_MIGRATION.md](WEBSOCKET_UNIFIED_MIGRATION.md) - Миграция на унифицированный WS
|
||||
|
||||
### Рефакторинг и оптимизация
|
||||
- [REFACTORING_SUMMARY.md](REFACTORING_SUMMARY.md) - Общий итог рефакторинга
|
||||
- [CACHE_OPTIMIZATION_SUMMARY.md](CACHE_OPTIMIZATION_SUMMARY.md) - Оптимизация кеширования
|
||||
- [API_REFACTORING_TESTING.md](API_REFACTORING_TESTING.md) - Тестирование API
|
||||
|
||||
## Лицензия
|
||||
|
||||
Проприетарное ПО © 2024-2025 Robotail
|
||||
|
||||
643
WEBSOCKET_1006_DIAGNOSTIC_PLAN.md
Normal file
643
WEBSOCKET_1006_DIAGNOSTIC_PLAN.md
Normal file
@ -0,0 +1,643 @@
|
||||
# План диагностики ошибки WebSocket 1006
|
||||
|
||||
## Описание проблемы
|
||||
У некоторых пользователей возникает ошибка **1006 (Abnormal Closure)** при попытке установить WebSocket соединение с сервером `172.11.0.11`.
|
||||
|
||||
Код 1006 означает аномальное закрытие соединения без отправки Close frame, что обычно указывает на проблемы:
|
||||
- На уровне прокси-сервера (Nginx)
|
||||
- Сетевые проблемы
|
||||
- Проблемы с аутентификацией/авторизацией
|
||||
- Таймауты или неправильная конфигурация
|
||||
|
||||
---
|
||||
|
||||
## Этап 1: Сбор информации о проблеме
|
||||
|
||||
### 1.1 Определите паттерн
|
||||
- [ ] **Какие пользователи затронуты?**
|
||||
- Все пользователи или только некоторые?
|
||||
- Есть ли общие признаки (отдел, роль, браузер, ОС)?
|
||||
|
||||
- [ ] **Когда происходит ошибка?**
|
||||
- При первом подключении к странице?
|
||||
- После определенного периода работы?
|
||||
- При переходе на определенные страницы (чаты, уведомления)?
|
||||
|
||||
- [ ] **Воспроизводимость**
|
||||
- Постоянная ошибка или периодическая?
|
||||
- Можно ли воспроизвести на других устройствах под той же учетной записью?
|
||||
|
||||
### 1.2 Проверьте браузер пользователя
|
||||
Попросите пользователя открыть **DevTools** → **Console/Network** и проверить:
|
||||
|
||||
```javascript
|
||||
// В консоли браузера:
|
||||
// 1. Проверить URL подключения
|
||||
console.log('WebSocket URL:', window.userWebSocket?.ws?.url);
|
||||
|
||||
// 2. Проверить статус соединения
|
||||
console.log('WebSocket state:', window.userWebSocket?.ws?.readyState);
|
||||
// 0 = CONNECTING, 1 = OPEN, 2 = CLOSING, 3 = CLOSED
|
||||
|
||||
// 3. Проверить код закрытия
|
||||
window.userWebSocket?.ws?.addEventListener('close', (event) => {
|
||||
console.log('Close Code:', event.code);
|
||||
console.log('Close Reason:', event.reason);
|
||||
console.log('Was Clean:', event.wasClean);
|
||||
});
|
||||
```
|
||||
|
||||
**Ожидаемые значения:**
|
||||
- URL: `ws://172.11.0.11/ws/` или `wss://172.11.0.11/ws/` (для HTTPS)
|
||||
- State: 1 (OPEN) при успешном подключении
|
||||
- Code: 1006 при ошибке
|
||||
- Reason: обычно пустая при 1006
|
||||
- wasClean: false при 1006
|
||||
|
||||
---
|
||||
|
||||
## Этап 2: Диагностика на сервере
|
||||
|
||||
### 2.1 Проверьте текущую конфигурацию Nginx
|
||||
|
||||
```bash
|
||||
# Подключитесь к серверу
|
||||
ssh igor@172.11.0.11
|
||||
|
||||
# Проверьте конфигурацию Nginx
|
||||
sudo cat /etc/nginx/sites-enabled/eusrr
|
||||
|
||||
# Проверьте на ошибки
|
||||
sudo nginx -t
|
||||
```
|
||||
|
||||
**✅ ТЕКУЩАЯ КОНФИГУРАЦИЯ ПРАВИЛЬНАЯ!**
|
||||
|
||||
Ваша конфигурация уже содержит:
|
||||
- ✅ Отдельный блок `location /ws/` для WebSocket (и для HTTP:80, и для HTTPS:443)
|
||||
- ✅ Заголовки `Upgrade` и `Connection "upgrade"`
|
||||
- ✅ `proxy_http_version 1.1`
|
||||
- ✅ Большие таймауты (7 дней)
|
||||
- ✅ `proxy_buffering off` для реалтайм данных
|
||||
|
||||
**Это означает, что проблема НЕ в базовой конфигурации Nginx!**
|
||||
|
||||
Переходите к следующим этапам диагностики.
|
||||
|
||||
### 2.2 Проверьте логи Nginx
|
||||
|
||||
```bash
|
||||
# Логи ошибок Nginx
|
||||
sudo tail -f /var/log/nginx/error.log
|
||||
|
||||
# Логи доступа (фильтр по WebSocket)
|
||||
sudo tail -f /var/log/nginx/access.log | grep '/ws/'
|
||||
|
||||
# Поиск ошибок 1006 или подключений WebSocket
|
||||
sudo grep -i "websocket\|upgrade\|101\|400\|502\|504" /var/log/nginx/error.log | tail -20
|
||||
```
|
||||
|
||||
**Что искать:**
|
||||
- `upstream prematurely closed connection` - Gunicorn закрыл соединение
|
||||
- `upstream timed out` - таймаут от backend
|
||||
- `no live upstreams` - backend недоступен
|
||||
- `400 Bad Request` - проблема с заголовками
|
||||
- `502 Bad Gateway` - backend не отвечает
|
||||
- `504 Gateway Timeout` - таймаут соединения
|
||||
|
||||
### 2.3 Проверьте логи приложения (Gunicorn/Django)
|
||||
|
||||
```bash
|
||||
# Логи приложения EUSRR
|
||||
sudo journalctl -u eusrr -f
|
||||
|
||||
# Фильтр по WebSocket событиям
|
||||
sudo journalctl -u eusrr -f | grep -i "websocket\|consumer\|connection"
|
||||
|
||||
# Последние ошибки
|
||||
sudo journalctl -u eusrr --since "1 hour ago" | grep -i "error\|exception\|traceback"
|
||||
```
|
||||
|
||||
**Что искать:**
|
||||
- `Consumer connected` / `Consumer disconnected` - логи подключений
|
||||
- `Authentication failed` - проблемы с JWT/токеном
|
||||
- `Exception in consumer` - ошибки в коде consumer
|
||||
- Трассировки ошибок Python
|
||||
|
||||
### 2.4 Проверьте статус сервисов
|
||||
|
||||
```bash
|
||||
# Статус Nginx
|
||||
sudo systemctl status nginx
|
||||
|
||||
# Статус приложения
|
||||
sudo systemctl status eusrr
|
||||
|
||||
# Статус Redis (для channels)
|
||||
sudo systemctl status redis
|
||||
|
||||
# Проверьте подключение к Redis
|
||||
redis-cli ping
|
||||
# Ожидается: PONG
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Этап 3: Тестирование WebSocket подключения
|
||||
|
||||
### 3.1 Прямое подключение к Gunicorn (без Nginx)
|
||||
|
||||
Временно проверьте, работает ли WebSocket напрямую:
|
||||
|
||||
```bash
|
||||
# На сервере проверьте порт Gunicorn (обычно 9000)
|
||||
sudo netstat -tlnp | grep 9000
|
||||
|
||||
# Попробуйте подключиться через curl
|
||||
curl -i -N \
|
||||
-H "Connection: Upgrade" \
|
||||
-H "Upgrade: websocket" \
|
||||
-H "Sec-WebSocket-Version: 13" \
|
||||
-H "Sec-WebSocket-Key: test" \
|
||||
http://127.0.0.1:9000/ws/
|
||||
```
|
||||
|
||||
**Ожидается:**
|
||||
- Код ответа `101 Switching Protocols` при успехе
|
||||
- Код `400` или `403` если есть проблемы с аутентификацией
|
||||
|
||||
### 3.2 Тест через Nginx
|
||||
|
||||
```bash
|
||||
# С локальной машины
|
||||
curl -i -N \
|
||||
-H "Connection: Upgrade" \
|
||||
-H "Upgrade: websocket" \
|
||||
-H "Sec-WebSocket-Version: 13" \
|
||||
-H "Sec-WebSocket-Key: test" \
|
||||
http://172.11.0.11/ws/
|
||||
```
|
||||
|
||||
Если ответ `502` или `504` - проблема в Nginx конфигурации.
|
||||
|
||||
### 3.3 Тест с аутентификацией
|
||||
|
||||
Создайте простой HTML файл для теста:
|
||||
|
||||
```html
|
||||
<!-- test_ws.html -->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>WS Test</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>WebSocket Test</h1>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
const log = document.getElementById('log');
|
||||
|
||||
// Замените на реальный JWT токен пользователя
|
||||
const token = 'YOUR_JWT_TOKEN_HERE';
|
||||
|
||||
const ws = new WebSocket(`ws://172.11.0.11/ws/?token=${token}`);
|
||||
|
||||
ws.onopen = () => {
|
||||
log.innerHTML += '<p style="color:green">✅ Connected!</p>';
|
||||
console.log('WebSocket opened');
|
||||
};
|
||||
|
||||
ws.onmessage = (event) => {
|
||||
log.innerHTML += `<p>📩 Message: ${event.data}</p>`;
|
||||
console.log('Message:', event.data);
|
||||
};
|
||||
|
||||
ws.onerror = (error) => {
|
||||
log.innerHTML += '<p style="color:orange">⚠️ Error occurred</p>';
|
||||
console.error('WebSocket error:', error);
|
||||
};
|
||||
|
||||
ws.onclose = (event) => {
|
||||
log.innerHTML += `<p style="color:red">❌ Closed: Code ${event.code}, Reason: ${event.reason || 'none'}</p>`;
|
||||
console.log('Close event:', event);
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Этап 4: Исправление типичных проблем
|
||||
|
||||
### 4.1 Проблема: Отсутствует отдельный блок для WebSocket
|
||||
|
||||
**✅ У ВАС УЖЕ НАСТРОЕНО ПРАВИЛЬНО!**
|
||||
|
||||
Ваша конфигурация уже содержит правильный блок `location /ws/` с нужными параметрами.
|
||||
|
||||
**Пропустите этот пункт и переходите к 4.2**
|
||||
|
||||
### 4.2 Проблема: Короткие таймауты
|
||||
|
||||
**Симптомы:**
|
||||
- Соединение работает, но закрывается через 30-60 секунд
|
||||
- Код 1006 после периода неактивности
|
||||
|
||||
**Решение:**
|
||||
Увеличьте таймауты в Nginx (см. 4.1) и проверьте Gunicorn:
|
||||
|
||||
```bash
|
||||
# Проверьте настройки Gunicorn
|
||||
sudo cat /etc/systemd/system/eusrr.service
|
||||
|
||||
# Должен быть параметр --timeout
|
||||
# ExecStart=.../gunicorn ... --timeout 300
|
||||
```
|
||||
|
||||
Если таймаут мал, увеличьте:
|
||||
```bash
|
||||
sudo nano /etc/systemd/system/eusrr.service
|
||||
# Измените --timeout 300 (или добавьте если нет)
|
||||
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl restart eusrr
|
||||
```
|
||||
|
||||
### 4.3 Проблема: Ошибки аутентификации JWT
|
||||
|
||||
**Симптомы:**
|
||||
- Код 1006 сразу при подключении
|
||||
- В логах Django: `Authentication failed` или `Invalid token`
|
||||
|
||||
**Проверка:**
|
||||
```python
|
||||
# На сервере
|
||||
cd /home/igor/EUSRR/backend
|
||||
source venv/bin/activate
|
||||
python manage.py shell
|
||||
|
||||
from rest_framework_simplejwt.tokens import AccessToken
|
||||
from users.models import User
|
||||
|
||||
# Проверьте токен конкретного пользователя
|
||||
user = User.objects.get(username='имя_пользователя')
|
||||
token = AccessToken.for_user(user)
|
||||
print(f"Token: {token}")
|
||||
print(f"Valid: {token.check_exp(current_time=None)}")
|
||||
```
|
||||
|
||||
**Решение:**
|
||||
- Убедитесь, что токен передается правильно: `?token=...`
|
||||
- Проверьте срок действия токена (`ACCESS_TOKEN_LIFETIME` в settings.py)
|
||||
- Убедитесь, что `JWTAuthMiddleware` правильно настроен в `asgi.py`
|
||||
|
||||
### 4.4 Проблема: Проблемы с CORS/Same-Origin Policy
|
||||
|
||||
**Симптомы:**
|
||||
- Ошибка только при подключении с определенных доменов
|
||||
- В консоли браузера: CORS ошибки
|
||||
|
||||
**Решение:**
|
||||
Добавьте в Nginx заголовки CORS для WebSocket:
|
||||
|
||||
```nginx
|
||||
location /ws/ {
|
||||
# ... существующие настройки ...
|
||||
|
||||
# CORS для WebSocket (если нужно)
|
||||
add_header 'Access-Control-Allow-Origin' '*' always;
|
||||
add_header 'Access-Control-Allow-Credentials' 'true' always;
|
||||
}
|
||||
```
|
||||
|
||||
### 4.5 Проблема: Redis недоступен
|
||||
|
||||
**Симптомы:**
|
||||
- WebSocket подключается, но не работает channel layer
|
||||
- В логах: `Connection refused` к Redis
|
||||
|
||||
**Проверка:**
|
||||
```bash
|
||||
# Проверьте Redis
|
||||
redis-cli ping
|
||||
|
||||
# Проверьте настройки в Django
|
||||
cd /home/igor/EUSRR/backend
|
||||
grep -A 10 "CHANNEL_LAYERS" eusrr_backend/settings.py
|
||||
```
|
||||
|
||||
**Решение:**
|
||||
```bash
|
||||
# Запустите Redis если не работает
|
||||
sudo systemctl start redis
|
||||
sudo systemctl enable redis
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Этап 5: Специфичные сценарии
|
||||
|
||||
### 5.1 Проблема только у некоторых пользователей
|
||||
|
||||
**Возможные причины:**
|
||||
1. **Корпоративный firewall** блокирует WebSocket
|
||||
2. **Антивирус** блокирует соединения
|
||||
3. **VPN/прокси** на стороне клиента
|
||||
4. **Браузерные расширения** (блокировщики рекламы, privacy tools)
|
||||
|
||||
**Диагностика:**
|
||||
- Попросите пользователя попробовать в режиме инкогнито
|
||||
- Попробуйте с другого устройства в той же сети
|
||||
- Попробуйте с мобильного интернета (вне корп. сети)
|
||||
- Отключите временно антивирус/расширения браузера
|
||||
|
||||
### 5.2 Проблема только в определенное время
|
||||
|
||||
**Возможные причины:**
|
||||
1. Высокая нагрузка на сервер
|
||||
2. Сетевые проблемы в определенное время
|
||||
3. Бэкапы или cron задачи нагружающие сервер
|
||||
|
||||
**Диагностика:**
|
||||
```bash
|
||||
# Мониторинг нагрузки
|
||||
htop
|
||||
|
||||
# Статистика соединений
|
||||
sudo netstat -an | grep :9000 | wc -l
|
||||
|
||||
# Проверьте cron задачи
|
||||
crontab -l
|
||||
sudo crontab -l
|
||||
```
|
||||
|
||||
### 5.3 Проблема после обновления кода
|
||||
|
||||
**Проверьте:**
|
||||
1. Миграции базы данных применены
|
||||
2. Статика собрана
|
||||
3. Сервисы перезапущены
|
||||
|
||||
```bash
|
||||
cd /home/igor/EUSRR/backend
|
||||
source venv/bin/activate
|
||||
|
||||
# Миграции
|
||||
python manage.py migrate
|
||||
|
||||
# Статика
|
||||
python manage.py collectstatic --noinput
|
||||
|
||||
# Перезапуск
|
||||
sudo systemctl restart eusrr
|
||||
sudo systemctl reload nginx
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Этап 6: Мониторинг и логирование
|
||||
|
||||
### 6.1 Добавьте расширенное логирование
|
||||
|
||||
В `user_consumer.py` добавьте детальные логи:
|
||||
|
||||
```python
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class UserConsumer(AsyncJsonWebsocketConsumer):
|
||||
async def connect(self):
|
||||
logger.info(f"[WS] Connection attempt from {self.scope.get('client')}")
|
||||
logger.info(f"[WS] User: {self.scope.get('user')}")
|
||||
logger.info(f"[WS] Headers: {dict(self.scope.get('headers', []))}")
|
||||
|
||||
# ... existing code ...
|
||||
|
||||
async def disconnect(self, code):
|
||||
logger.warning(f"[WS] Disconnect: user={self.user.username if self.user else 'unknown'}, code={code}")
|
||||
# ... existing code ...
|
||||
```
|
||||
|
||||
### 6.2 Настройте мониторинг WebSocket соединений
|
||||
|
||||
```bash
|
||||
# Скрипт для мониторинга WebSocket
|
||||
cat > /home/igor/monitor_ws.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
while true; do
|
||||
echo "=== $(date) ==="
|
||||
echo "Active WebSocket connections:"
|
||||
sudo netstat -an | grep :9000 | grep ESTABLISHED | wc -l
|
||||
echo ""
|
||||
sleep 10
|
||||
done
|
||||
EOF
|
||||
|
||||
chmod +x /home/igor/monitor_ws.sh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Этап 7: Чек-лист быстрой проверки
|
||||
|
||||
Для быстрой диагностики выполните:
|
||||
|
||||
```bash
|
||||
# 1. Сервисы работают?
|
||||
sudo systemctl status nginx eusrr redis
|
||||
|
||||
# 2. Порты слушают?
|
||||
sudo netstat -tlnp | grep -E ":(80|9000|6379)"
|
||||
|
||||
# 3. Ошибки в логах за последний час?
|
||||
sudo journalctl -u eusrr --since "1 hour ago" | grep -i error
|
||||
sudo grep -i error /var/log/nginx/error.log | tail -20
|
||||
|
||||
# 4. Конфигурация Nginx правильная?
|
||||
sudo nginx -t
|
||||
|
||||
# 5. Redis работает?
|
||||
redis-cli ping
|
||||
|
||||
# 6. WebSocket блок существует?
|
||||
sudo grep -A 15 "location /ws/" /etc/nginx/sites-enabled/eusrr
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Этап 8: Рекомендуемая конфигурация Nginx
|
||||
|
||||
**Полная рабочая конфигурация для WebSocket:**
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name corp.robotail.local 172.11.0.11 127.0.0.1;
|
||||
|
||||
client_max_body_size 50m;
|
||||
|
||||
# Логирование
|
||||
access_log /var/log/nginx/eusrr_access.log;
|
||||
error_log /var/log/nginx/eusrr_error.log warn;
|
||||
|
||||
# Статика
|
||||
location /static/ {
|
||||
alias /home/igor/EUSRR/backend/staticfiles/;
|
||||
autoindex off;
|
||||
expires 30d;
|
||||
add_header Cache-Control "public, max-age=2592000";
|
||||
}
|
||||
|
||||
# Медиа
|
||||
location /media/ {
|
||||
alias /home/igor/EUSRR/backend/media/;
|
||||
autoindex off;
|
||||
}
|
||||
|
||||
# WebSocket - КРИТИЧЕСКИ ВАЖНО: отдельный блок перед location /
|
||||
location /ws/ {
|
||||
proxy_pass http://127.0.0.1:9000;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# WebSocket специфичные заголовки
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
|
||||
# Таймауты для долгих соединений (7 дней)
|
||||
proxy_connect_timeout 7d;
|
||||
proxy_send_timeout 7d;
|
||||
proxy_read_timeout 7d;
|
||||
|
||||
# Отключаем буферизацию для реалтайм данных
|
||||
proxy_buffering off;
|
||||
|
||||
# Дополнительные настройки для стабильности
|
||||
proxy_redirect off;
|
||||
proxy_cache_bypass $http_upgrade;
|
||||
}
|
||||
|
||||
# API и основное приложение
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:9000;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# Обычные таймауты для HTTP запросов
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
proxy_read_timeout 60s;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Применение:**
|
||||
```bash
|
||||
# Сохраните конфигурацию
|
||||
sudo nano /etc/nginx/sites-enabled/eusrr
|
||||
# Вставьте конфигурацию выше
|
||||
|
||||
# Проверьте
|
||||
sudo nginx -t
|
||||
|
||||
# Примените
|
||||
sudo systemctl reload nginx
|
||||
|
||||
# Проверьте логи
|
||||
sudo tail -f /var/log/nginx/eusrr_error.log
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Итоговый алгоритм диагностики
|
||||
|
||||
1. **Собрать информацию** (Этап 1)
|
||||
- Кто, когда, при каких условиях сталкивается с ошибкой
|
||||
|
||||
2. **Проверить сервер** (Этап 2)
|
||||
- Nginx конфигурация
|
||||
- Логи Nginx/Gunicorn/Redis
|
||||
- Статус сервисов
|
||||
|
||||
3. **Протестировать подключение** (Этап 3)
|
||||
- Напрямую к Gunicorn
|
||||
- Через Nginx
|
||||
- С аутентификацией
|
||||
|
||||
4. **Применить исправления** (Этап 4)
|
||||
- Добавить отдельный блок `/ws/`
|
||||
- Увеличить таймауты
|
||||
- Проверить JWT аутентификацию
|
||||
|
||||
5. **Специфичные случаи** (Этап 5)
|
||||
- Сетевые ограничения
|
||||
- Высокая нагрузка
|
||||
- Проблемы после обновлений
|
||||
|
||||
6. **Настроить мониторинг** (Этап 6)
|
||||
- Расширенное логирование
|
||||
- Скрипты мониторинга
|
||||
|
||||
7. **Быстрая проверка** (Этап 7)
|
||||
- Чек-лист из 6 команд
|
||||
|
||||
8. **Применить эталонную конфигурацию** (Этап 8)
|
||||
- Проверенная конфигурация Nginx
|
||||
|
||||
---
|
||||
|
||||
## Полезные команды для копирования
|
||||
|
||||
```bash
|
||||
# === Быстрая диагностика ===
|
||||
# Подключение к серверу
|
||||
ssh igor@172.11.0.11
|
||||
|
||||
# Проверка всех сервисов
|
||||
sudo systemctl status nginx eusrr redis
|
||||
|
||||
# Просмотр логов в реальном времени
|
||||
sudo journalctl -u eusrr -f | grep -i "websocket\|error"
|
||||
|
||||
# Проверка конфигурации
|
||||
sudo nginx -t
|
||||
sudo cat /etc/nginx/sites-enabled/eusrr | grep -A 20 "location /ws/"
|
||||
|
||||
# Перезапуск после изменений
|
||||
sudo systemctl reload nginx
|
||||
sudo systemctl restart eusrr
|
||||
|
||||
# === Мониторинг ===
|
||||
# Количество WebSocket соединений
|
||||
watch -n 2 'sudo netstat -an | grep :9000 | grep ESTABLISHED | wc -l'
|
||||
|
||||
# Последние ошибки
|
||||
sudo journalctl -u eusrr --since "10 minutes ago" | grep -i error
|
||||
|
||||
# === Тестирование ===
|
||||
# Тест WebSocket через curl
|
||||
curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" \
|
||||
-H "Sec-WebSocket-Version: 13" -H "Sec-WebSocket-Key: test" \
|
||||
http://172.11.0.11/ws/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Ожидаемый результат
|
||||
|
||||
После выполнения плана диагностики вы:
|
||||
1. ✅ Определите точную причину ошибки 1006
|
||||
2. ✅ Примените соответствующее исправление
|
||||
3. ✅ Настроите мониторинг для предотвращения проблем
|
||||
4. ✅ Подтвердите, что WebSocket работает стабильно
|
||||
|
||||
**Если проблема не решена после всех этапов:**
|
||||
- Сделайте полный дамп логов (Nginx + Django + Redis)
|
||||
- Проверьте сетевую инфраструктуру (firewall, routing)
|
||||
- Рассмотрите переход на WSS (WebSocket Secure) через HTTPS
|
||||
487
WEBSOCKET_1006_PRIORITY_CHECK.md
Normal file
487
WEBSOCKET_1006_PRIORITY_CHECK.md
Normal file
@ -0,0 +1,487 @@
|
||||
# WebSocket 1006 - Приоритетная диагностика
|
||||
|
||||
## ✅ Конфигурация Nginx ПРАВИЛЬНАЯ
|
||||
|
||||
Ваша текущая конфигурация Nginx уже содержит все необходимые настройки для WebSocket, поэтому проблема **НЕ** в базовой конфигурации.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Наиболее вероятные причины (в порядке убывания)
|
||||
|
||||
### 1. Проблемы с JWT аутентификацией (60% вероятность)
|
||||
|
||||
**Симптомы:**
|
||||
- Ошибка 1006 сразу при попытке подключения
|
||||
- Работает у одних пользователей, не работает у других
|
||||
- Может зависеть от времени (истекший токен)
|
||||
|
||||
**Быстрая проверка:**
|
||||
```bash
|
||||
# На сервере проверьте логи Django
|
||||
ssh igor@172.11.0.11
|
||||
sudo journalctl -u eusrr -n 100 | grep -i "websocket\|authentication\|jwt\|token"
|
||||
```
|
||||
|
||||
**Что искать в логах:**
|
||||
- `Authentication failed`
|
||||
- `Invalid token`
|
||||
- `Token has expired`
|
||||
- `User not found`
|
||||
|
||||
**Решение:**
|
||||
|
||||
1. Проверьте настройки JWT в `settings.py`:
|
||||
```bash
|
||||
cd /home/igor/EUSRR/backend
|
||||
grep -A 10 "SIMPLE_JWT" eusrr_backend/settings.py
|
||||
```
|
||||
|
||||
2. Убедитесь, что токен передается правильно в JS:
|
||||
```javascript
|
||||
// В браузере пользователя (DevTools Console)
|
||||
console.log('Token:', localStorage.getItem('access_token'));
|
||||
console.log('WS URL:', window.userWebSocket?.ws?.url);
|
||||
```
|
||||
|
||||
3. Увеличьте время жизни токена (если нужно):
|
||||
```python
|
||||
# settings.py
|
||||
SIMPLE_JWT = {
|
||||
'ACCESS_TOKEN_LIFETIME': timedelta(hours=24), # Было меньше?
|
||||
# ...
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Проблемы с CORS/Заголовками Origin (25% вероятность)
|
||||
|
||||
**Симптомы:**
|
||||
- Работает при подключении с `corp.robotail.local`, не работает с `172.11.0.11`
|
||||
- Работает в одном браузере, не работает в другом
|
||||
- В консоли браузера могут быть предупреждения о CORS
|
||||
|
||||
**Быстрая проверка:**
|
||||
```bash
|
||||
# Проверьте Access-Control заголовки
|
||||
curl -I -H "Origin: http://172.11.0.11" http://172.11.0.11/ws/
|
||||
```
|
||||
|
||||
**Решение:**
|
||||
|
||||
Добавьте CORS заголовки в блоки `/ws/` (для обоих серверов - HTTP и HTTPS):
|
||||
|
||||
```nginx
|
||||
location /ws/ {
|
||||
# ... существующие настройки ...
|
||||
|
||||
# Добавьте:
|
||||
proxy_set_header Origin $http_origin;
|
||||
|
||||
# Если нужен CORS (необязательно, но может помочь):
|
||||
add_header 'Access-Control-Allow-Origin' '$http_origin' always;
|
||||
add_header 'Access-Control-Allow-Credentials' 'true' always;
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS' always;
|
||||
add_header 'Access-Control-Allow-Headers' 'Upgrade,Connection,Sec-WebSocket-Key,Sec-WebSocket-Version' always;
|
||||
}
|
||||
```
|
||||
|
||||
Примените:
|
||||
```bash
|
||||
sudo nginx -t && sudo systemctl reload nginx
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. Проблемы на стороне клиента (10% вероятность)
|
||||
|
||||
**Симптомы:**
|
||||
- Работает у большинства, не работает у конкретных пользователей
|
||||
- Может зависеть от сети (офис vs дом)
|
||||
|
||||
**Возможные причины:**
|
||||
- Корпоративный firewall/proxy блокирует WebSocket
|
||||
- Антивирус блокирует соединения
|
||||
- Браузерные расширения (AdBlock, Privacy Badger, NoScript)
|
||||
- VPN/туннель с проблемами
|
||||
|
||||
**Диагностика:**
|
||||
|
||||
Попросите пользователя:
|
||||
|
||||
1. Открыть **режим инкогнито** (отключит расширения):
|
||||
```
|
||||
Ctrl+Shift+N (Chrome/Edge) или Ctrl+Shift+P (Firefox)
|
||||
```
|
||||
|
||||
2. Проверить в консоли браузера (F12 → Console):
|
||||
```javascript
|
||||
// Попробуйте подключиться вручную
|
||||
const token = localStorage.getItem('access_token');
|
||||
const ws = new WebSocket(`ws://172.11.0.11/ws/?token=${token}`);
|
||||
|
||||
ws.onopen = () => console.log('✅ Connected!');
|
||||
ws.onerror = (e) => console.error('❌ Error:', e);
|
||||
ws.onclose = (e) => console.log('❌ Closed:', e.code, e.reason);
|
||||
```
|
||||
|
||||
3. Попробовать с другого устройства/сети
|
||||
|
||||
**Решение:**
|
||||
- Добавить исключение в firewall/антивирус
|
||||
- Отключить проблемные расширения
|
||||
- Попробовать HTTPS (WSS) вместо HTTP (WS)
|
||||
|
||||
---
|
||||
|
||||
### 4. Redis недоступен или перегружен (3% вероятность)
|
||||
|
||||
**Симптомы:**
|
||||
- Соединение устанавливается, но сразу закрывается
|
||||
- Проблема у всех пользователей одновременно
|
||||
|
||||
**Быстрая проверка:**
|
||||
```bash
|
||||
ssh igor@172.11.0.11
|
||||
|
||||
# Проверьте Redis
|
||||
redis-cli ping
|
||||
# Должно вернуть: PONG
|
||||
|
||||
# Проверьте подключения к Redis
|
||||
redis-cli CLIENT LIST | grep -c connected
|
||||
# Должно быть разумное число (<1000)
|
||||
|
||||
# Проверьте память Redis
|
||||
redis-cli INFO memory | grep used_memory_human
|
||||
|
||||
# Проверьте статус сервиса
|
||||
sudo systemctl status redis
|
||||
```
|
||||
|
||||
**Решение:**
|
||||
|
||||
Если Redis не работает:
|
||||
```bash
|
||||
sudo systemctl restart redis
|
||||
sudo systemctl enable redis
|
||||
```
|
||||
|
||||
Если Redis перегружен (проверьте логи):
|
||||
```bash
|
||||
# Очистите кеш (ВНИМАНИЕ: это удалит все данные Redis!)
|
||||
redis-cli FLUSHALL
|
||||
|
||||
# Или перезапустите
|
||||
sudo systemctl restart redis
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. Gunicorn worker умер или перегружен (2% вероятность)
|
||||
|
||||
**Симптомы:**
|
||||
- Периодические проблемы
|
||||
- После перезапуска работает какое-то время
|
||||
|
||||
**Быстрая проверка:**
|
||||
```bash
|
||||
ssh igor@172.11.0.11
|
||||
|
||||
# Проверьте статус Gunicorn
|
||||
sudo systemctl status eusrr
|
||||
|
||||
# Проверьте логи на ошибки
|
||||
sudo journalctl -u eusrr --since "1 hour ago" | grep -i "error\|worker\|timeout"
|
||||
|
||||
# Проверьте количество worker'ов
|
||||
ps aux | grep gunicorn | grep -v grep
|
||||
```
|
||||
|
||||
**Решение:**
|
||||
|
||||
1. Проверьте конфигурацию Gunicorn:
|
||||
```bash
|
||||
sudo cat /etc/systemd/system/eusrr.service
|
||||
```
|
||||
|
||||
Должно быть примерно так:
|
||||
```ini
|
||||
ExecStart=/home/igor/EUSRR/backend/venv/bin/gunicorn \
|
||||
--workers 4 \
|
||||
--worker-class uvicorn.workers.UvicornWorker \
|
||||
--bind 0.0.0.0:9000 \
|
||||
--timeout 300 \
|
||||
--access-logfile /var/log/eusrr/access.log \
|
||||
--error-logfile /var/log/eusrr/error.log \
|
||||
eusrr_backend.asgi:application
|
||||
```
|
||||
|
||||
2. Если конфигурация неправильная, исправьте и перезапустите:
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl restart eusrr
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Быстрый чек-лист диагностики
|
||||
|
||||
Выполните эти команды **по порядку**:
|
||||
|
||||
```bash
|
||||
# 1. Подключитесь к серверу
|
||||
ssh igor@172.11.0.11
|
||||
|
||||
# 2. Проверьте все сервисы
|
||||
sudo systemctl status nginx eusrr redis
|
||||
# Все должны быть active (running)
|
||||
|
||||
# 3. Проверьте JWT логи (САМОЕ ВАЖНОЕ!)
|
||||
sudo journalctl -u eusrr -n 200 | grep -i "websocket\|authentication\|jwt"
|
||||
# Ищите ошибки аутентификации
|
||||
|
||||
# 4. Проверьте Redis
|
||||
redis-cli ping
|
||||
# Должно вернуть: PONG
|
||||
|
||||
# 5. Проверьте ошибки Nginx
|
||||
sudo tail -50 /var/log/nginx/error.log
|
||||
# Не должно быть ошибок 502/504
|
||||
|
||||
# 6. Проверьте активные WebSocket соединения
|
||||
sudo netstat -an | grep :9000 | grep ESTABLISHED
|
||||
# Должны быть подключения
|
||||
|
||||
# 7. Тест WebSocket вручную
|
||||
curl -i -N \
|
||||
-H "Connection: Upgrade" \
|
||||
-H "Upgrade: websocket" \
|
||||
-H "Sec-WebSocket-Version: 13" \
|
||||
-H "Sec-WebSocket-Key: test" \
|
||||
http://127.0.0.1:9000/ws/
|
||||
# Должен вернуть 403 (нет токена) или 101 (успех с токеном)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Расширенная диагностика JWT (если проблема в аутентификации)
|
||||
|
||||
### На сервере:
|
||||
|
||||
```bash
|
||||
cd /home/igor/EUSRR/backend
|
||||
source venv/bin/activate
|
||||
|
||||
# Запустите Django shell
|
||||
python manage.py shell
|
||||
```
|
||||
|
||||
```python
|
||||
# В Django shell:
|
||||
from users.models import User
|
||||
from rest_framework_simplejwt.tokens import AccessToken
|
||||
from datetime import datetime
|
||||
|
||||
# Проверьте пользователя, у которого проблема
|
||||
username = "имя_пользователя" # Замените на реального пользователя
|
||||
user = User.objects.get(username=username)
|
||||
|
||||
# Создайте новый токен
|
||||
token = AccessToken.for_user(user)
|
||||
print(f"User: {user.username}")
|
||||
print(f"Token: {token}")
|
||||
print(f"Expires at: {datetime.fromtimestamp(token['exp'])}")
|
||||
|
||||
# Проверьте валидность
|
||||
try:
|
||||
token.check_exp()
|
||||
print("✅ Token is valid")
|
||||
except Exception as e:
|
||||
print(f"❌ Token error: {e}")
|
||||
|
||||
# Выход
|
||||
exit()
|
||||
```
|
||||
|
||||
### В браузере пользователя (F12 → Console):
|
||||
|
||||
```javascript
|
||||
// 1. Проверьте текущий токен
|
||||
const token = localStorage.getItem('access_token');
|
||||
console.log('Token:', token);
|
||||
|
||||
// 2. Декодируйте токен (без проверки подписи)
|
||||
if (token) {
|
||||
const parts = token.split('.');
|
||||
if (parts.length === 3) {
|
||||
const payload = JSON.parse(atob(parts[1]));
|
||||
console.log('Token payload:', payload);
|
||||
console.log('Expires:', new Date(payload.exp * 1000));
|
||||
console.log('Is expired:', new Date() > new Date(payload.exp * 1000));
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Попробуйте переподключиться с токеном
|
||||
if (window.userWebSocket) {
|
||||
window.userWebSocket.reconnect();
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📋 Если проблема только у некоторых пользователей
|
||||
|
||||
### Соберите данные от пользователя:
|
||||
|
||||
1. **Браузер и ОС**
|
||||
- Chrome/Firefox/Edge/Safari?
|
||||
- Windows/Mac/Linux?
|
||||
- Версия браузера?
|
||||
|
||||
2. **Сеть**
|
||||
- Офисная сеть или домашняя?
|
||||
- VPN включен?
|
||||
- Антивирус работает?
|
||||
|
||||
3. **Консоль браузера** (F12 → Console)
|
||||
- Есть ли красные ошибки?
|
||||
- Что показывает WebSocket в Network → WS?
|
||||
|
||||
4. **Воспроизведение**
|
||||
- Постоянная проблема или периодическая?
|
||||
- На других устройствах та же проблема?
|
||||
|
||||
### Тест в режиме инкогнито:
|
||||
|
||||
1. Откройте инкогнито (Ctrl+Shift+N)
|
||||
2. Войдите в систему
|
||||
3. Попробуйте использовать функции с WebSocket
|
||||
4. Если **работает в инкогнито** → проблема в расширениях браузера
|
||||
5. Если **не работает в инкогнито** → проблема в сети/firewall
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Временное решение для срочных случаев
|
||||
|
||||
Если нужно срочно дать пользователю доступ, попробуйте:
|
||||
|
||||
### 1. Увеличить время жизни токена
|
||||
|
||||
```python
|
||||
# backend/eusrr_backend/settings.py
|
||||
SIMPLE_JWT = {
|
||||
'ACCESS_TOKEN_LIFETIME': timedelta(hours=24), # Было 1 час?
|
||||
'REFRESH_TOKEN_LIFETIME': timedelta(days=7),
|
||||
# ...
|
||||
}
|
||||
```
|
||||
|
||||
Перезапустите:
|
||||
```bash
|
||||
sudo systemctl restart eusrr
|
||||
```
|
||||
|
||||
### 2. Добавить больше логирования в consumer
|
||||
|
||||
```python
|
||||
# backend/communications/user_consumer.py
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class UserConsumer(AsyncJsonWebsocketConsumer):
|
||||
async def connect(self):
|
||||
# Добавьте в начало метода:
|
||||
client = self.scope.get('client', ['unknown', 0])
|
||||
logger.info(f"[WS CONNECT] Client: {client[0]}:{client[1]}")
|
||||
logger.info(f"[WS CONNECT] User: {self.scope.get('user')}")
|
||||
logger.info(f"[WS CONNECT] Path: {self.scope.get('path')}")
|
||||
|
||||
self.user = self.scope.get("user")
|
||||
|
||||
if not self.user or isinstance(self.user, AnonymousUser) or not self.user.is_authenticated:
|
||||
logger.warning(f"[WS CONNECT] Authentication failed for {client[0]}")
|
||||
await self.close(code=4401)
|
||||
return
|
||||
|
||||
logger.info(f"[WS CONNECT] Success for user {self.user.username}")
|
||||
# ...остальной код...
|
||||
```
|
||||
|
||||
Перезапустите и проверьте логи:
|
||||
```bash
|
||||
sudo systemctl restart eusrr
|
||||
sudo journalctl -u eusrr -f | grep "WS CONNECT"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ После исправления
|
||||
|
||||
### Проверьте работоспособность:
|
||||
|
||||
1. **В браузере** (F12 → Network → WS):
|
||||
- Соединение должно быть зеленым
|
||||
- Status: 101 Switching Protocols
|
||||
- Должны приходить ping каждые 20 секунд
|
||||
|
||||
2. **На сервере**:
|
||||
```bash
|
||||
# Активные соединения
|
||||
watch -n 2 'sudo netstat -an | grep :9000 | grep ESTABLISHED | wc -l'
|
||||
# Число должно расти при подключении пользователей
|
||||
|
||||
# Логи без ошибок
|
||||
sudo journalctl -u eusrr -f | grep -i websocket
|
||||
# Не должно быть ошибок
|
||||
```
|
||||
|
||||
3. **Функциональность**:
|
||||
- Новые сообщения приходят без обновления страницы
|
||||
- Уведомления появляются в реальном времени
|
||||
- Бейдж чатов обновляется
|
||||
|
||||
---
|
||||
|
||||
## 📞 Если ничего не помогло
|
||||
|
||||
Соберите полный дамп для анализа:
|
||||
|
||||
```bash
|
||||
# На сервере
|
||||
cd /tmp
|
||||
|
||||
# Конфигурация
|
||||
sudo cat /etc/nginx/sites-enabled/eusrr > ws_debug_nginx.conf
|
||||
sudo cat /etc/systemd/system/eusrr.service > ws_debug_systemd.service
|
||||
|
||||
# Логи (последний час)
|
||||
sudo journalctl -u eusrr --since "1 hour ago" > ws_debug_django.log
|
||||
sudo tail -500 /var/log/nginx/error.log > ws_debug_nginx_error.log
|
||||
sudo tail -500 /var/log/nginx/access.log | grep '/ws/' > ws_debug_nginx_ws.log
|
||||
|
||||
# Статус
|
||||
sudo systemctl status nginx eusrr redis > ws_debug_status.txt
|
||||
redis-cli INFO > ws_debug_redis.txt
|
||||
ps aux | grep gunicorn > ws_debug_gunicorn.txt
|
||||
|
||||
# Создайте архив
|
||||
tar -czf ws_debug_$(date +%Y%m%d_%H%M%S).tar.gz ws_debug_*
|
||||
|
||||
# Скачайте архив на локальную машину
|
||||
# scp igor@172.11.0.11:/tmp/ws_debug_*.tar.gz .
|
||||
```
|
||||
|
||||
Отправьте архив для детального анализа.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Итого: Порядок действий
|
||||
|
||||
1. ✅ **Проверьте JWT логи** (60% вероятность проблемы здесь)
|
||||
2. ✅ **Проверьте CORS/Origin заголовки** (25% вероятность)
|
||||
3. ✅ **Попросите пользователя попробовать инкогнито** (10% вероятность)
|
||||
4. ✅ **Проверьте Redis** (3% вероятность)
|
||||
5. ✅ **Проверьте Gunicorn workers** (2% вероятность)
|
||||
|
||||
**Начните с пункта 1 - это самая частая причина!**
|
||||
339
WEBSOCKET_1006_QUICK_GUIDE.md
Normal file
339
WEBSOCKET_1006_QUICK_GUIDE.md
Normal file
@ -0,0 +1,339 @@
|
||||
# WebSocket 1006 - Быстрая шпаргалка
|
||||
|
||||
## 🚨 Экспресс-диагностика (5 минут)
|
||||
|
||||
```bash
|
||||
# Подключитесь к серверу
|
||||
ssh igor@172.11.0.11
|
||||
|
||||
# Скопируйте и выполните все команды сразу:
|
||||
|
||||
echo "=== 1. Статус сервисов ==="
|
||||
sudo systemctl status nginx eusrr redis --no-pager
|
||||
|
||||
echo -e "\n=== 2. JWT/Auth ошибки (САМОЕ ВАЖНОЕ!) ==="
|
||||
sudo journalctl -u eusrr -n 200 --no-pager | grep -i "websocket\|authentication\|jwt\|token\|4401"
|
||||
|
||||
echo -e "\n=== 3. Redis доступен? ==="
|
||||
redis-cli ping
|
||||
|
||||
echo -e "\n=== 4. Ошибки Nginx ==="
|
||||
sudo tail -20 /var/log/nginx/error.log
|
||||
|
||||
echo -e "\n=== 5. Активные WS соединения ==="
|
||||
sudo netstat -an | grep :9000 | grep ESTABLISHED | wc -l
|
||||
|
||||
echo -e "\n=== 6. Тест WS подключения ==="
|
||||
curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" \
|
||||
-H "Sec-WebSocket-Version: 13" -H "Sec-WebSocket-Key: test" \
|
||||
http://127.0.0.1:9000/ws/ 2>&1 | head -20
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Что проверить по результатам
|
||||
|
||||
### Результат 2 (JWT/Auth ошибки):
|
||||
|
||||
**Если видите:**
|
||||
- `Authentication failed` → Проблема с токеном
|
||||
- `code=4401` → Пользователь не аутентифицирован
|
||||
- `Invalid token` → Токен истек или неправильный
|
||||
- `AnonymousUser` → Токен не передается
|
||||
|
||||
**➡️ Действие:** Проверьте JWT (см. раздел JWT ниже)
|
||||
|
||||
### Результат 3 (Redis):
|
||||
|
||||
**Если НЕ вернул `PONG`:**
|
||||
```bash
|
||||
sudo systemctl restart redis
|
||||
redis-cli ping
|
||||
```
|
||||
|
||||
### Результат 4 (Nginx):
|
||||
|
||||
**Если видите ошибки:**
|
||||
- `upstream prematurely closed` → Backend закрыл соединение (проверьте Django логи)
|
||||
- `upstream timed out` → Таймаут (но у вас уже 7 дней, странно)
|
||||
- `502/504` → Backend недоступен (проверьте Gunicorn)
|
||||
|
||||
### Результат 5 (Соединения):
|
||||
|
||||
**Если 0:** Никто не подключен (нормально, если нет пользователей онлайн)
|
||||
**Если >0:** Есть активные соединения → значит у кого-то работает!
|
||||
|
||||
### Результат 6 (Тест):
|
||||
|
||||
**Ожидается:**
|
||||
- `HTTP/1.1 403` (нет токена) или
|
||||
- `HTTP/1.1 101` (успех, если токен не требуется на этом уровне)
|
||||
|
||||
**Если `502` или `504`:** Проблема с Gunicorn
|
||||
|
||||
---
|
||||
|
||||
## 🔑 Проверка JWT (если проблема в auth)
|
||||
|
||||
### На сервере:
|
||||
|
||||
```bash
|
||||
cd /home/igor/EUSRR/backend
|
||||
source venv/bin/activate
|
||||
python manage.py shell
|
||||
```
|
||||
|
||||
```python
|
||||
from users.models import User
|
||||
from rest_framework_simplejwt.tokens import AccessToken
|
||||
from datetime import datetime
|
||||
|
||||
# Замените на проблемного пользователя
|
||||
user = User.objects.get(username="USERNAME")
|
||||
token = AccessToken.for_user(user)
|
||||
print(f"✅ Token: {token}")
|
||||
print(f"📅 Expires: {datetime.fromtimestamp(token['exp'])}")
|
||||
exit()
|
||||
```
|
||||
|
||||
### В браузере пользователя (F12 → Console):
|
||||
|
||||
```javascript
|
||||
// Проверьте токен
|
||||
const token = localStorage.getItem('access_token');
|
||||
console.log('Token:', token ? 'Exists' : 'Missing!');
|
||||
|
||||
// Декодируйте и проверьте срок
|
||||
if (token) {
|
||||
const payload = JSON.parse(atob(token.split('.')[1]));
|
||||
console.log('Expires:', new Date(payload.exp * 1000));
|
||||
console.log('Expired?', new Date() > new Date(payload.exp * 1000));
|
||||
}
|
||||
|
||||
// Переподключите WS
|
||||
window.userWebSocket?.reconnect();
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🌐 Проверка на стороне клиента
|
||||
|
||||
### Пользователь в браузере (F12):
|
||||
|
||||
**1. Network → WS:**
|
||||
- Ищите `/ws/` соединение
|
||||
- Status должен быть `101 Switching Protocols`
|
||||
- Если `(pending)` → не подключается
|
||||
- Если красное → смотрите код ошибки
|
||||
|
||||
**2. Console:**
|
||||
```javascript
|
||||
// Ручное подключение для теста
|
||||
const token = localStorage.getItem('access_token');
|
||||
const ws = new WebSocket(`ws://172.11.0.11/ws/?token=${token}`);
|
||||
|
||||
ws.onopen = () => console.log('✅ OPEN');
|
||||
ws.onerror = (e) => console.error('❌ ERROR:', e);
|
||||
ws.onclose = (e) => console.log('❌ CLOSE:', e.code, e.reason);
|
||||
|
||||
// Подождите 5 секунд...
|
||||
// Если не открылось - проблема!
|
||||
```
|
||||
|
||||
**3. Режим инкогнито:**
|
||||
- Ctrl+Shift+N (Chrome/Edge)
|
||||
- Войдите в систему
|
||||
- Если **работает** → проблема в расширениях браузера
|
||||
- Если **не работает** → проблема на сервере/сети
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Быстрые фиксы
|
||||
|
||||
### Фикс 1: Увеличить время жизни токена
|
||||
|
||||
```bash
|
||||
ssh igor@172.11.0.11
|
||||
cd /home/igor/EUSRR/backend
|
||||
nano eusrr_backend/settings.py
|
||||
```
|
||||
|
||||
Найдите и измените:
|
||||
```python
|
||||
SIMPLE_JWT = {
|
||||
'ACCESS_TOKEN_LIFETIME': timedelta(hours=24), # Было меньше?
|
||||
# ...
|
||||
}
|
||||
```
|
||||
|
||||
```bash
|
||||
sudo systemctl restart eusrr
|
||||
```
|
||||
|
||||
### Фикс 2: Добавить CORS заголовки (если нужно)
|
||||
|
||||
```bash
|
||||
sudo nano /etc/nginx/sites-enabled/eusrr
|
||||
```
|
||||
|
||||
В оба блока `location /ws/` (HTTP и HTTPS) добавьте:
|
||||
```nginx
|
||||
proxy_set_header Origin $http_origin;
|
||||
```
|
||||
|
||||
```bash
|
||||
sudo nginx -t && sudo systemctl reload nginx
|
||||
```
|
||||
|
||||
### Фикс 3: Перезапустить всё
|
||||
|
||||
```bash
|
||||
sudo systemctl restart redis
|
||||
sudo systemctl restart eusrr
|
||||
sudo systemctl reload nginx
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Мониторинг в реальном времени
|
||||
|
||||
### Логи Django (в отдельном терминале):
|
||||
|
||||
```bash
|
||||
ssh igor@172.11.0.11
|
||||
sudo journalctl -u eusrr -f | grep -i "websocket\|connect\|disconnect"
|
||||
```
|
||||
|
||||
**Что смотреть:**
|
||||
- `Consumer connected` → Кто-то подключился ✅
|
||||
- `Consumer disconnected` → Кто-то отключился
|
||||
- `code=4401` → Проблема с auth ❌
|
||||
- Traceback → Ошибка в коде ❌
|
||||
|
||||
### Активные соединения (в отдельном терминале):
|
||||
|
||||
```bash
|
||||
ssh igor@172.11.0.11
|
||||
watch -n 2 'sudo netstat -an | grep :9000 | grep ESTABLISHED | wc -l'
|
||||
```
|
||||
|
||||
Число должно расти/уменьшаться при подключении/отключении пользователей.
|
||||
|
||||
---
|
||||
|
||||
## 🐛 Включить расширенное логирование
|
||||
|
||||
Если не понятно что происходит:
|
||||
|
||||
```bash
|
||||
ssh igor@172.11.0.11
|
||||
cd /home/igor/EUSRR/backend
|
||||
nano communications/user_consumer.py
|
||||
```
|
||||
|
||||
В начало класса `UserConsumer` добавьте:
|
||||
```python
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
```
|
||||
|
||||
В метод `connect()` в самое начало:
|
||||
```python
|
||||
async def connect(self):
|
||||
client = self.scope.get('client', ['unknown', 0])
|
||||
logger.info(f"🔌 WS: {client[0]} trying to connect")
|
||||
logger.info(f"👤 User: {self.scope.get('user')}")
|
||||
|
||||
self.user = self.scope.get("user")
|
||||
|
||||
if not self.user or isinstance(self.user, AnonymousUser):
|
||||
logger.warning(f"❌ WS: {client[0]} - No auth")
|
||||
await self.close(code=4401)
|
||||
return
|
||||
|
||||
logger.info(f"✅ WS: {self.user.username} connected")
|
||||
# ...остальной код...
|
||||
```
|
||||
|
||||
Сохраните и перезапустите:
|
||||
```bash
|
||||
sudo systemctl restart eusrr
|
||||
sudo journalctl -u eusrr -f | grep WS
|
||||
```
|
||||
|
||||
Теперь будете видеть каждую попытку подключения!
|
||||
|
||||
---
|
||||
|
||||
## ❓ FAQ
|
||||
|
||||
### Работает у одних, не работает у других?
|
||||
→ Проблема в JWT токене или сети/браузере клиента
|
||||
|
||||
### Не работает ни у кого?
|
||||
→ Проблема на сервере (Redis, Gunicorn, Nginx)
|
||||
|
||||
### Работало, потом перестало?
|
||||
→ Проверьте что изменилось (обновление кода, конфигурации)
|
||||
|
||||
### Периодически отваливается?
|
||||
→ Может быть нормально (пинги каждые 20 сек должны держать)
|
||||
|
||||
### Ошибка только в определенной сети?
|
||||
→ Firewall/proxy блокирует WebSocket
|
||||
|
||||
### Работает в инкогнито, не работает в обычном режиме?
|
||||
→ Расширения браузера блокируют (AdBlock, Privacy Badger и т.д.)
|
||||
|
||||
---
|
||||
|
||||
## 📞 Экстренная помощь
|
||||
|
||||
Если совсем всё плохо, соберите дамп:
|
||||
|
||||
```bash
|
||||
ssh igor@172.11.0.11
|
||||
cd /tmp
|
||||
|
||||
# Один файл со всей инфой
|
||||
{
|
||||
echo "=== SERVICES ==="
|
||||
sudo systemctl status nginx eusrr redis --no-pager
|
||||
echo -e "\n=== DJANGO LOGS ==="
|
||||
sudo journalctl -u eusrr --since "1 hour ago" --no-pager
|
||||
echo -e "\n=== NGINX ERRORS ==="
|
||||
sudo tail -100 /var/log/nginx/error.log
|
||||
echo -e "\n=== NGINX CONFIG ==="
|
||||
sudo cat /etc/nginx/sites-enabled/eusrr
|
||||
echo -e "\n=== GUNICORN PROCESSES ==="
|
||||
ps aux | grep gunicorn
|
||||
echo -e "\n=== REDIS INFO ==="
|
||||
redis-cli INFO
|
||||
echo -e "\n=== CONNECTIONS ==="
|
||||
sudo netstat -an | grep :9000
|
||||
} > ws_debug_$(date +%Y%m%d_%H%M%S).txt
|
||||
|
||||
# Скачайте файл
|
||||
ls -lh ws_debug_*.txt
|
||||
```
|
||||
|
||||
Скопируйте на локальную машину:
|
||||
```bash
|
||||
scp igor@172.11.0.11:/tmp/ws_debug_*.txt .
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ Контрольный список
|
||||
|
||||
- [ ] Все сервисы running (nginx, eusrr, redis)
|
||||
- [ ] Redis отвечает на PONG
|
||||
- [ ] В логах нет ошибок JWT/auth
|
||||
- [ ] Нет ошибок в Nginx error.log
|
||||
- [ ] Тест curl возвращает 403 или 101 (не 502/504)
|
||||
- [ ] Токен существует в localStorage браузера
|
||||
- [ ] Токен не истек
|
||||
- [ ] Попробовали в режиме инкогнито
|
||||
- [ ] Проверили на другом устройстве/сети
|
||||
|
||||
**Если все пункты ✅ но не работает** → пришлите дамп для детального анализа.
|
||||
254
WEBSOCKET_1006_SUMMARY.md
Normal file
254
WEBSOCKET_1006_SUMMARY.md
Normal file
@ -0,0 +1,254 @@
|
||||
# Диагностика WebSocket 1006 - Сводка
|
||||
|
||||
## 📚 Созданные документы
|
||||
|
||||
### 1. **WEBSOCKET_1006_QUICK_GUIDE.md** ⚡ (НАЧНИТЕ ЗДЕСЬ!)
|
||||
**Для:** Быстрой диагностики (5 минут)
|
||||
**Содержит:**
|
||||
- Экспресс-скрипт для проверки всех компонентов
|
||||
- Расшифровку результатов
|
||||
- Быстрые фиксы
|
||||
- Команды для мониторинга в реальном времени
|
||||
- Краткий FAQ
|
||||
|
||||
### 2. **WEBSOCKET_1006_PRIORITY_CHECK.md**
|
||||
**Для:** Детальной диагностики с приоритетами
|
||||
**Содержит:**
|
||||
- 5 наиболее вероятных причин (с процентами)
|
||||
- Детальные инструкции для каждой причины
|
||||
- Решения и обходные пути
|
||||
- Чек-лист после исправления
|
||||
|
||||
### 3. **WEBSOCKET_1006_DIAGNOSTIC_PLAN.md**
|
||||
**Для:** Полной методологии диагностики
|
||||
**Содержит:**
|
||||
- 8 этапов диагностики от простого к сложному
|
||||
- Все возможные сценарии проблем
|
||||
- Примеры конфигураций
|
||||
- Скрипты для мониторинга
|
||||
- Эталонная конфигурация Nginx
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Быстрый старт
|
||||
|
||||
### Шаг 1: Экспресс-диагностика (5 минут)
|
||||
|
||||
Подключитесь к серверу и выполните:
|
||||
|
||||
```bash
|
||||
ssh igor@172.11.0.11
|
||||
|
||||
# Скопируйте и выполните весь блок:
|
||||
echo "=== 1. Статус сервисов ==="
|
||||
sudo systemctl status nginx eusrr redis --no-pager
|
||||
|
||||
echo -e "\n=== 2. JWT/Auth ошибки (САМОЕ ВАЖНОЕ!) ==="
|
||||
sudo journalctl -u eusrr -n 200 --no-pager | grep -i "websocket\|authentication\|jwt\|token\|4401"
|
||||
|
||||
echo -e "\n=== 3. Redis доступен? ==="
|
||||
redis-cli ping
|
||||
|
||||
echo -e "\n=== 4. Ошибки Nginx ==="
|
||||
sudo tail -20 /var/log/nginx/error.log
|
||||
|
||||
echo -e "\n=== 5. Активные WS соединения ==="
|
||||
sudo netstat -an | grep :9000 | grep ESTABLISHED | wc -l
|
||||
|
||||
echo -e "\n=== 6. Тест WS подключения ==="
|
||||
curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" \
|
||||
-H "Sec-WebSocket-Version: 13" -H "Sec-WebSocket-Key: test" \
|
||||
http://127.0.0.1:9000/ws/ 2>&1 | head -20
|
||||
```
|
||||
|
||||
### Шаг 2: Интерпретация результатов
|
||||
|
||||
**Результат 2 (JWT/Auth):**
|
||||
- Если видите `Authentication failed`, `code=4401`, `Invalid token` → **Проблема в JWT!**
|
||||
- Переходите к разделу "Проверка JWT" в WEBSOCKET_1006_QUICK_GUIDE.md
|
||||
|
||||
**Результат 3 (Redis):**
|
||||
- Если НЕ `PONG` → перезапустите Redis: `sudo systemctl restart redis`
|
||||
|
||||
**Результат 4 (Nginx errors):**
|
||||
- Если видите `502` или `504` → проблема с Gunicorn
|
||||
- Если видите `upstream prematurely closed` → проверьте Django логи
|
||||
|
||||
**Результат 6 (Test):**
|
||||
- `403` - нормально (нет токена)
|
||||
- `502/504` - проблема с backend
|
||||
|
||||
### Шаг 3: Быстрые фиксы (если нужно)
|
||||
|
||||
**Фикс 1: Перезапустить всё**
|
||||
```bash
|
||||
sudo systemctl restart redis
|
||||
sudo systemctl restart eusrr
|
||||
sudo systemctl reload nginx
|
||||
```
|
||||
|
||||
**Фикс 2: Увеличить время жизни токена JWT**
|
||||
```bash
|
||||
cd /home/igor/EUSRR/backend
|
||||
nano eusrr_backend/settings.py
|
||||
# Найдите SIMPLE_JWT и увеличьте ACCESS_TOKEN_LIFETIME
|
||||
sudo systemctl restart eusrr
|
||||
```
|
||||
|
||||
**Фикс 3: Включить расширенное логирование**
|
||||
См. раздел в WEBSOCKET_1006_QUICK_GUIDE.md
|
||||
|
||||
---
|
||||
|
||||
## 📊 Вероятные причины (ваш случай)
|
||||
|
||||
Поскольку ваша конфигурация Nginx **уже правильная** (отдельный блок /ws/, таймауты 7 дней, все заголовки):
|
||||
|
||||
### 1. JWT аутентификация (60% вероятность) 🔥
|
||||
**Проверьте:**
|
||||
- Логи Django на ошибки auth
|
||||
- Срок действия токенов
|
||||
- Передается ли токен в URL правильно
|
||||
|
||||
**Где смотреть:**
|
||||
- `WEBSOCKET_1006_PRIORITY_CHECK.md` → раздел 1
|
||||
- `WEBSOCKET_1006_QUICK_GUIDE.md` → "Проверка JWT"
|
||||
|
||||
### 2. CORS/Origin заголовки (25% вероятность)
|
||||
**Проверьте:**
|
||||
- Работает ли с разных доменов (corp.robotail.local vs 172.11.0.11)
|
||||
- Нужны ли дополнительные CORS заголовки
|
||||
|
||||
**Где смотреть:**
|
||||
- `WEBSOCKET_1006_PRIORITY_CHECK.md` → раздел 2
|
||||
|
||||
### 3. Проблемы на стороне клиента (10% вероятность)
|
||||
**Проверьте:**
|
||||
- Firewall/антивирус
|
||||
- Браузерные расширения
|
||||
- Режим инкогнито
|
||||
|
||||
**Где смотреть:**
|
||||
- `WEBSOCKET_1006_PRIORITY_CHECK.md` → раздел 3
|
||||
- `WEBSOCKET_1006_QUICK_GUIDE.md` → "Проверка на стороне клиента"
|
||||
|
||||
### 4. Redis/Gunicorn (5% вероятность)
|
||||
**Проверьте:**
|
||||
- Redis доступен и работает
|
||||
- Gunicorn workers живы
|
||||
|
||||
**Где смотреть:**
|
||||
- `WEBSOCKET_1006_PRIORITY_CHECK.md` → разделы 4-5
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Инструменты для мониторинга
|
||||
|
||||
### Мониторинг логов Django:
|
||||
```bash
|
||||
ssh igor@172.11.0.11
|
||||
sudo journalctl -u eusrr -f | grep -i "websocket\|connect\|4401"
|
||||
```
|
||||
|
||||
### Мониторинг активных соединений:
|
||||
```bash
|
||||
ssh igor@172.11.0.11
|
||||
watch -n 2 'sudo netstat -an | grep :9000 | grep ESTABLISHED | wc -l'
|
||||
```
|
||||
|
||||
### Проверка в браузере пользователя:
|
||||
1. F12 → Network → WS
|
||||
2. Найти `/ws/` соединение
|
||||
3. Проверить Status (должен быть 101)
|
||||
4. Проверить Messages (должны быть ping каждые 20 секунд)
|
||||
|
||||
---
|
||||
|
||||
## 📞 Если ничего не помогло
|
||||
|
||||
### Соберите полный дамп:
|
||||
|
||||
```bash
|
||||
ssh igor@172.11.0.11
|
||||
cd /tmp
|
||||
|
||||
{
|
||||
echo "=== SERVICES ==="
|
||||
sudo systemctl status nginx eusrr redis --no-pager
|
||||
echo -e "\n=== DJANGO LOGS ==="
|
||||
sudo journalctl -u eusrr --since "1 hour ago" --no-pager
|
||||
echo -e "\n=== NGINX ERRORS ==="
|
||||
sudo tail -100 /var/log/nginx/error.log
|
||||
echo -e "\n=== NGINX CONFIG ==="
|
||||
sudo cat /etc/nginx/sites-enabled/eusrr
|
||||
echo -e "\n=== REDIS INFO ==="
|
||||
redis-cli INFO
|
||||
} > ws_debug_$(date +%Y%m%d_%H%M%S).txt
|
||||
|
||||
ls -lh ws_debug_*.txt
|
||||
```
|
||||
|
||||
Скачайте файл на локальную машину:
|
||||
```bash
|
||||
scp igor@172.11.0.11:/tmp/ws_debug_*.txt .
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ Контрольный список
|
||||
|
||||
Перед тем как просить помощь, убедитесь:
|
||||
|
||||
- [ ] Выполнили экспресс-диагностику из Шага 1
|
||||
- [ ] Проверили JWT логи (это самая частая причина!)
|
||||
- [ ] Redis отвечает `PONG`
|
||||
- [ ] Нет ошибок в Nginx error.log
|
||||
- [ ] Попробовали в режиме инкогнито
|
||||
- [ ] Проверили на другом устройстве/сети
|
||||
- [ ] Перезапустили сервисы (redis, eusrr, nginx)
|
||||
- [ ] Проверили время жизни JWT токена
|
||||
|
||||
---
|
||||
|
||||
## 📖 Какой документ читать?
|
||||
|
||||
### У вас 5 минут?
|
||||
→ **WEBSOCKET_1006_QUICK_GUIDE.md** ⚡
|
||||
|
||||
### Нужно разобраться детально?
|
||||
→ **WEBSOCKET_1006_PRIORITY_CHECK.md**
|
||||
|
||||
### Хотите полную методологию?
|
||||
→ **WEBSOCKET_1006_DIAGNOSTIC_PLAN.md**
|
||||
|
||||
### Проблемы с keepalive/ping?
|
||||
→ **WEBSOCKET_KEEPALIVE_FIX.md**
|
||||
|
||||
---
|
||||
|
||||
## 🎓 Полезная информация
|
||||
|
||||
### Код ошибки 1006 означает:
|
||||
"Abnormal Closure" - соединение закрылось без отправки Close frame.
|
||||
|
||||
### Это НЕ означает:
|
||||
- Проблема в коде JavaScript (код правильный)
|
||||
- Проблема в Nginx конфигурации (конфигурация правильная)
|
||||
|
||||
### Это ОБЫЧНО означает:
|
||||
- Проблема с аутентификацией (JWT токен)
|
||||
- Проблема на уровне сети/firewall
|
||||
- Backend отклонил соединение
|
||||
- Таймауты (но у вас 7 дней, маловероятно)
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Следующие шаги
|
||||
|
||||
1. **Начните с экспресс-диагностики** (Шаг 1 выше)
|
||||
2. **Проверьте JWT логи** (это самое важное!)
|
||||
3. **Если не помогло** - читайте WEBSOCKET_1006_PRIORITY_CHECK.md
|
||||
4. **Включите расширенное логирование** для детального анализа
|
||||
5. **Соберите дамп** если ничего не помогло
|
||||
|
||||
Удачи в диагностике! 🔍
|
||||
Loading…
x
Reference in New Issue
Block a user