353 lines
9.0 KiB
Markdown
353 lines
9.0 KiB
Markdown
# 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 минут после отключения |