init commit
This commit is contained in:
353
backend/README.md
Normal file
353
backend/README.md
Normal file
@@ -0,0 +1,353 @@
|
||||
# GodEye Backend API Documentation
|
||||
|
||||
## Обзор
|
||||
Backend сервер системы сигнального центра "GodEye" предоставляет WebSocket и REST API для управления соединениями между Android устройствами и операторами desktop приложений.
|
||||
|
||||
## Архитектура
|
||||
|
||||
### Основные компоненты
|
||||
- **WebSocket Server** - для real-time коммуникации
|
||||
- **REST API** - для операций CRUD и администрирования
|
||||
- **SessionManager** - управление сессиями подключения к камерам
|
||||
- **DeviceManager** - управление Android устройствами и операторами
|
||||
|
||||
### Потоки данных
|
||||
```
|
||||
Android Device <--WebSocket--> Backend <--WebSocket--> Desktop Operator
|
||||
<--WebRTC Signaling--> <--REST API--> Admin Panel
|
||||
```
|
||||
|
||||
## WebSocket API
|
||||
|
||||
### Регистрация Android клиента
|
||||
```javascript
|
||||
socket.emit('register:android', {
|
||||
deviceId: "unique_device_id",
|
||||
deviceInfo: {
|
||||
model: "Samsung Galaxy S21",
|
||||
manufacturer: "Samsung",
|
||||
androidVersion: "12",
|
||||
availableCameras: "back,front,ultra_wide,telephoto"
|
||||
}
|
||||
});
|
||||
|
||||
// Response
|
||||
socket.on('register:success', (data) => {
|
||||
console.log(data.deviceId); // подтверждение регистрации
|
||||
});
|
||||
```
|
||||
|
||||
### Регистрация оператора
|
||||
```javascript
|
||||
socket.emit('register:operator', {
|
||||
operatorId: "operator_123", // опционально
|
||||
operatorInfo: {
|
||||
name: "Иван Иванов",
|
||||
permissions: ["view_cameras", "request_camera"]
|
||||
}
|
||||
});
|
||||
|
||||
// Response
|
||||
socket.on('register:success', (data) => {
|
||||
console.log(data.operatorId);
|
||||
console.log(data.availableDevices); // список доступных устройств
|
||||
});
|
||||
```
|
||||
|
||||
### Запрос доступа к камере
|
||||
```javascript
|
||||
// Оператор запрашивает камеру
|
||||
socket.emit('camera:request', {
|
||||
deviceId: "device_123",
|
||||
cameraType: "back" // back, front, ultra_wide, telephoto
|
||||
});
|
||||
|
||||
// Android получает запрос
|
||||
socket.on('camera:request', (data) => {
|
||||
console.log(data.sessionId);
|
||||
console.log(data.operatorId);
|
||||
console.log(data.cameraType);
|
||||
});
|
||||
|
||||
// Android отвечает на запрос
|
||||
socket.emit('camera:response', {
|
||||
sessionId: "session_123",
|
||||
accepted: true,
|
||||
streamUrl: "webrtc", // или RTSP URL
|
||||
error: null
|
||||
});
|
||||
```
|
||||
|
||||
### WebRTC сигнализация
|
||||
```javascript
|
||||
// Отправка offer/answer/ice-candidate
|
||||
socket.emit('webrtc:offer', {
|
||||
sessionId: "session_123",
|
||||
offer: "SDP_offer_string"
|
||||
});
|
||||
|
||||
socket.emit('webrtc:answer', {
|
||||
sessionId: "session_123",
|
||||
answer: "SDP_answer_string"
|
||||
});
|
||||
|
||||
socket.emit('webrtc:ice-candidate', {
|
||||
sessionId: "session_123",
|
||||
candidate: "ICE_candidate_string"
|
||||
});
|
||||
```
|
||||
|
||||
### Управление камерой
|
||||
```javascript
|
||||
// Переключение камеры
|
||||
socket.emit('camera:switch', {
|
||||
sessionId: "session_123",
|
||||
cameraType: "front"
|
||||
});
|
||||
|
||||
// Завершение сессии
|
||||
socket.emit('camera:disconnect', {
|
||||
sessionId: "session_123"
|
||||
});
|
||||
```
|
||||
|
||||
## REST API
|
||||
|
||||
### Базовый URL
|
||||
```
|
||||
http://localhost:3000/api
|
||||
```
|
||||
|
||||
### Аутентификация
|
||||
Для всех операторских запросов требуется заголовок:
|
||||
```
|
||||
X-Operator-Id: your_operator_id
|
||||
```
|
||||
|
||||
## Endpoints для операторов
|
||||
|
||||
### GET /api/operators/devices
|
||||
Получение списка доступных устройств
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"devices": [
|
||||
{
|
||||
"deviceId": "device_123",
|
||||
"deviceInfo": {
|
||||
"model": "Samsung Galaxy S21",
|
||||
"manufacturer": "Samsung"
|
||||
},
|
||||
"status": "connected",
|
||||
"isConnected": true,
|
||||
"capabilities": {
|
||||
"cameras": ["back", "front", "ultra_wide"],
|
||||
"hasMultipleCameras": true
|
||||
},
|
||||
"canAcceptSession": true
|
||||
}
|
||||
],
|
||||
"total": 1
|
||||
}
|
||||
```
|
||||
|
||||
### POST /api/operators/camera/request
|
||||
Создание запроса на доступ к камере
|
||||
```json
|
||||
{
|
||||
"deviceId": "device_123",
|
||||
"cameraType": "back"
|
||||
}
|
||||
```
|
||||
|
||||
Response:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"sessionId": "session_456",
|
||||
"message": "Camera request sent to device"
|
||||
}
|
||||
```
|
||||
|
||||
### POST /api/operators/camera/{sessionId}/switch
|
||||
Переключение камеры в активной сессии
|
||||
```json
|
||||
{
|
||||
"cameraType": "front"
|
||||
}
|
||||
```
|
||||
|
||||
### DELETE /api/operators/camera/{sessionId}
|
||||
Завершение сессии камеры
|
||||
|
||||
### GET /api/operators/sessions
|
||||
Получение активных сессий оператора
|
||||
|
||||
### GET /api/operators/profile
|
||||
Получение профиля текущего оператора
|
||||
|
||||
## Admin API
|
||||
|
||||
### GET /api/admin/stats
|
||||
Общая статистика системы
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"stats": {
|
||||
"timestamp": "2025-09-28T10:30:00.000Z",
|
||||
"uptime": 3600,
|
||||
"devices": {
|
||||
"totalDevices": 10,
|
||||
"connectedDevices": 8
|
||||
},
|
||||
"sessions": {
|
||||
"totalSessions": 25,
|
||||
"activeSessions": 3
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### GET /api/admin/devices
|
||||
Список всех устройств (с пагинацией)
|
||||
|
||||
### GET /api/admin/sessions
|
||||
Список всех сессий (с фильтрацией и пагинацией)
|
||||
|
||||
### POST /api/admin/sessions/{sessionId}/terminate
|
||||
Принудительное завершение сессии
|
||||
|
||||
### POST /api/admin/devices/{deviceId}/disconnect
|
||||
Принудительное отключение устройства
|
||||
|
||||
### GET /api/admin/health
|
||||
Проверка состояния системы
|
||||
|
||||
## Коды состояний
|
||||
|
||||
### Статусы устройств
|
||||
- `connected` - устройство подключено и готово
|
||||
- `busy` - устройство занято активной сессией
|
||||
- `disconnected` - устройство отключено
|
||||
|
||||
### Статусы сессий
|
||||
- `pending` - сессия создана, ожидает ответа от устройства
|
||||
- `active` - сессия активна, идет трансляция
|
||||
- `closed` - сессия завершена
|
||||
- `denied` - запрос отклонен устройством
|
||||
- `error` - ошибка в сессии
|
||||
|
||||
### WebRTC состояния
|
||||
- `offer_sent` - offer отправлен
|
||||
- `answer_sent` - answer отправлен
|
||||
- `connected` - WebRTC соединение установлено
|
||||
- `disconnected` - WebRTC соединение разорвано
|
||||
|
||||
## Обработка ошибок
|
||||
|
||||
### HTTP ошибки
|
||||
- `400` - Некорректные параметры запроса
|
||||
- `401` - Не авторизован (отсутствует Operator ID)
|
||||
- `403` - Нет прав доступа
|
||||
- `404` - Ресурс не найден
|
||||
- `409` - Конфликт (устройство занято и т.д.)
|
||||
- `500` - Внутренняя ошибка сервера
|
||||
|
||||
### WebSocket ошибки
|
||||
```javascript
|
||||
socket.on('camera:error', (data) => {
|
||||
console.error(data.error);
|
||||
});
|
||||
```
|
||||
|
||||
## Примеры использования
|
||||
|
||||
### Полный цикл подключения к камере
|
||||
|
||||
1. **Регистрация оператора**
|
||||
```javascript
|
||||
socket.emit('register:operator', { operatorId: 'op1' });
|
||||
```
|
||||
|
||||
2. **Получение списка устройств**
|
||||
```javascript
|
||||
const response = await fetch('/api/operators/devices', {
|
||||
headers: { 'X-Operator-Id': 'op1' }
|
||||
});
|
||||
const { devices } = await response.json();
|
||||
```
|
||||
|
||||
3. **Запрос камеры**
|
||||
```javascript
|
||||
const response = await fetch('/api/operators/camera/request', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-Operator-Id': 'op1',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
deviceId: devices[0].deviceId,
|
||||
cameraType: 'back'
|
||||
})
|
||||
});
|
||||
const { sessionId } = await response.json();
|
||||
```
|
||||
|
||||
4. **WebRTC сигнализация**
|
||||
```javascript
|
||||
socket.on('webrtc:offer', async (data) => {
|
||||
const answer = await createWebRTCAnswer(data.offer);
|
||||
socket.emit('webrtc:answer', {
|
||||
sessionId: data.sessionId,
|
||||
answer
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
5. **Завершение сессии**
|
||||
```javascript
|
||||
await fetch(`/api/operators/camera/${sessionId}`, {
|
||||
method: 'DELETE',
|
||||
headers: { 'X-Operator-Id': 'op1' }
|
||||
});
|
||||
```
|
||||
|
||||
## Развертывание
|
||||
|
||||
### Переменные окружения
|
||||
```env
|
||||
PORT=3000
|
||||
NODE_ENV=production
|
||||
LOG_LEVEL=info
|
||||
```
|
||||
|
||||
### Запуск
|
||||
```bash
|
||||
npm install
|
||||
npm start
|
||||
```
|
||||
|
||||
### Docker
|
||||
```dockerfile
|
||||
FROM node:18-alpine
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm ci --only=production
|
||||
COPY . .
|
||||
EXPOSE 3000
|
||||
CMD ["npm", "start"]
|
||||
```
|
||||
|
||||
## Мониторинг
|
||||
|
||||
### Логи
|
||||
Логи сохраняются в файл `god-eye.log` и выводятся в консоль.
|
||||
|
||||
### Метрики
|
||||
- `/api/status` - базовая статистика
|
||||
- `/api/admin/health` - детальная проверка здоровья
|
||||
- `/api/admin/stats` - полная статистика системы
|
||||
|
||||
### Автоматическая очистка
|
||||
- Старые сессии (>60 мин) очищаются каждые 5 минут
|
||||
- Отключенные устройства удаляются через 5 минут после отключения
|
||||
Reference in New Issue
Block a user