288 lines
9.2 KiB
Markdown
288 lines
9.2 KiB
Markdown
# Руководство: Подключение Desktop Operator к Android телефону
|
||
|
||
## 🔗 Как работает подключение оператора к телефону
|
||
|
||
### Архитектура подключения
|
||
|
||
```
|
||
Desktop Operator ←→ WebSocket ←→ Сервер ←→ WebSocket ←→ Android телефон
|
||
↓
|
||
ConnectionManager
|
||
(управляет соединениями)
|
||
↓
|
||
WebRTC P2P соединение
|
||
(прямая передача видео)
|
||
```
|
||
|
||
### 1. 📱 Регистрация Android устройства
|
||
|
||
**Android телефон подключается к серверу:**
|
||
```kotlin
|
||
// Android код
|
||
val socket = IO.socket("ws://192.168.1.100:3001")
|
||
socket.emit("register:android", JSONObject().apply {
|
||
put("deviceId", "android_unique_id")
|
||
put("deviceInfo", JSONObject().apply {
|
||
put("manufacturer", "Samsung")
|
||
put("model", "Galaxy S21")
|
||
put("androidVersion", "11")
|
||
put("availableCameras", JSONArray(listOf("back", "front", "ultra_wide")))
|
||
put("appVersion", "1.0.0")
|
||
})
|
||
})
|
||
```
|
||
|
||
**Сервер подтверждает регистрацию:**
|
||
```javascript
|
||
// Лог сервера
|
||
{"level":"info","message":"Android client registered: android_unique_id","timestamp":"..."}
|
||
```
|
||
|
||
### 2. 💻 Подключение Desktop Operator
|
||
|
||
**Operator приложение подключается:**
|
||
```javascript
|
||
// Desktop Operator код
|
||
const socket = io('ws://192.168.1.100:3001');
|
||
socket.emit('register:operator', {
|
||
operatorId: 'operator-uuid',
|
||
operatorInfo: {
|
||
name: 'Иван Петров',
|
||
organization: 'Служба безопасности',
|
||
permissions: ['view_cameras', 'request_camera', 'initiate_connection']
|
||
}
|
||
});
|
||
```
|
||
|
||
### 3. 🔍 Проверка доступных устройств
|
||
|
||
**REST API запрос списка устройств:**
|
||
```bash
|
||
curl -H "x-operator-id: operator-uuid" \
|
||
http://localhost:3001/api/operators/devices
|
||
```
|
||
|
||
**Ответ сервера:**
|
||
```json
|
||
{
|
||
"success": true,
|
||
"devices": [
|
||
{
|
||
"deviceId": "android_unique_id",
|
||
"model": "Galaxy S21",
|
||
"manufacturer": "Samsung",
|
||
"isConnected": true,
|
||
"availableCameras": ["back", "front", "ultra_wide"],
|
||
"canAcceptNewSession": true,
|
||
"activeSessions": 0
|
||
}
|
||
],
|
||
"total": 1
|
||
}
|
||
```
|
||
|
||
### 4. 📞 Инициация подключения к телефону
|
||
|
||
**Оператор запрашивает доступ к камере:**
|
||
```bash
|
||
curl -X POST http://localhost:3001/api/operators/connections/request \
|
||
-H "Content-Type: application/json" \
|
||
-H "x-operator-id: operator-uuid" \
|
||
-d '{
|
||
"deviceId": "android_unique_id",
|
||
"cameraType": "back"
|
||
}'
|
||
```
|
||
|
||
**Сервер создает подключение:**
|
||
```json
|
||
{
|
||
"success": true,
|
||
"connectionId": "conn-uuid",
|
||
"sessionId": "session-uuid",
|
||
"message": "Connection request initiated"
|
||
}
|
||
```
|
||
|
||
### 5. 📲 Android получает запрос подтверждения
|
||
|
||
**WebSocket событие на Android:**
|
||
```javascript
|
||
// Сервер → Android
|
||
socket.emit('connection:request', {
|
||
connectionId: 'conn-uuid',
|
||
sessionId: 'session-uuid',
|
||
operatorId: 'operator-uuid',
|
||
operatorInfo: {
|
||
name: 'Иван Петров',
|
||
organization: 'Служба безопасности',
|
||
reason: 'Проверка безопасности'
|
||
},
|
||
cameraType: 'back',
|
||
timestamp: '2025-10-04T12:00:00.000Z',
|
||
expiresAt: '2025-10-04T12:05:00.000Z' // 5 минут на ответ
|
||
});
|
||
```
|
||
|
||
**Android показывает диалог пользователю:**
|
||
```
|
||
┌─────────────────────────────────┐
|
||
│ Запрос доступа к камере │
|
||
├─────────────────────────────────┤
|
||
│ Оператор: Иван Петров │
|
||
│ Организация: Служба безопасности│
|
||
│ Причина: Проверка безопасности │
|
||
│ Камера: Задняя │
|
||
│ │
|
||
│ Разрешить доступ к камере? │
|
||
│ │
|
||
│ [Разрешить] [Отклонить] │
|
||
└─────────────────────────────────┘
|
||
```
|
||
|
||
### 6. ✅ Пользователь принимает/отклоняет запрос
|
||
|
||
**Если пользователь принимает:**
|
||
```kotlin
|
||
// Android → Сервер
|
||
socket.emit("connection:accept", JSONObject().apply {
|
||
put("connectionId", connectionId)
|
||
put("sessionId", sessionId)
|
||
put("cameraType", "back")
|
||
put("webrtcInfo", JSONObject().apply {
|
||
put("supported", true)
|
||
put("codecs", JSONArray(listOf("H264", "VP8")))
|
||
put("resolutions", JSONArray(listOf("720p", "1080p")))
|
||
})
|
||
})
|
||
```
|
||
|
||
**Сервер уведомляет оператора:**
|
||
```javascript
|
||
// Сервер → Desktop Operator
|
||
socket.emit('connection:accepted', {
|
||
connectionId: 'conn-uuid',
|
||
sessionId: 'session-uuid',
|
||
webrtcInfo: {
|
||
supported: true,
|
||
codecs: ['H264', 'VP8'],
|
||
resolutions: ['720p', '1080p']
|
||
}
|
||
});
|
||
```
|
||
|
||
### 7. 🎥 Установка WebRTC соединения
|
||
|
||
**Обмен WebRTC сигналами:**
|
||
```
|
||
Desktop Operator → Сервер → Android: webrtc:offer
|
||
Android → Сервер → Desktop Operator: webrtc:answer
|
||
Desktop Operator ↔ Сервер ↔ Android: webrtc:ice-candidate
|
||
```
|
||
|
||
**После успешного установления WebRTC:**
|
||
```
|
||
Desktop Operator ←-----WebRTC P2P-----→ Android
|
||
(прямое видео)
|
||
```
|
||
|
||
## 🧪 Тестирование подключения
|
||
|
||
### Проверка 1: Статус системы
|
||
```bash
|
||
curl http://localhost:3001/api/status | jq
|
||
```
|
||
|
||
### Проверка 2: Список устройств
|
||
```bash
|
||
curl -H "x-operator-id: YOUR_OPERATOR_ID" \
|
||
http://localhost:3001/api/operators/devices | jq
|
||
```
|
||
|
||
### Проверка 3: Инициация подключения
|
||
```bash
|
||
curl -X POST http://localhost:3001/api/operators/connections/request \
|
||
-H "Content-Type: application/json" \
|
||
-H "x-operator-id: YOUR_OPERATOR_ID" \
|
||
-d '{
|
||
"deviceId": "android_device_id",
|
||
"cameraType": "back"
|
||
}' | jq
|
||
```
|
||
|
||
### Проверка 4: Статус подключений
|
||
```bash
|
||
curl -H "x-operator-id: YOUR_OPERATOR_ID" \
|
||
http://localhost:3001/api/operators/connections | jq
|
||
```
|
||
|
||
## 🐞 Диагностика проблем
|
||
|
||
### Проблема: "Invalid or disconnected operator"
|
||
**Причина:** Оператор не подключен к WebSocket
|
||
**Решение:**
|
||
1. Откройте веб-демо: http://localhost:3001
|
||
2. Проверьте WebSocket подключение в консоли браузера
|
||
3. Используйте Operator ID из консоли
|
||
|
||
### Проблема: "Device not found"
|
||
**Причина:** Android устройство не подключено
|
||
**Решение:**
|
||
1. Перезапустите Android приложение
|
||
2. Проверьте сетевое соединение
|
||
3. Убедитесь что устройство регистрируется
|
||
|
||
### Проблема: "Device busy or unavailable"
|
||
**Причина:** Устройство занято другой сессией
|
||
**Решение:**
|
||
1. Завершите активные сессии
|
||
2. Подождите таймаут (30 секунд)
|
||
3. Попробуйте снова
|
||
|
||
## 📊 Мониторинг соединений
|
||
|
||
### Логи сервера
|
||
```bash
|
||
tail -f /home/data/god_eye/backend/god-eye.log
|
||
```
|
||
|
||
### Административная статистика
|
||
```bash
|
||
curl http://localhost:3001/api/admin/stats | jq
|
||
```
|
||
|
||
### Real-time статус через WebSocket
|
||
```javascript
|
||
socket.on('device:connected', (data) => {
|
||
console.log('Устройство подключено:', data.deviceId);
|
||
});
|
||
|
||
socket.on('connection:accepted', (data) => {
|
||
console.log('Подключение принято:', data.connectionId);
|
||
});
|
||
```
|
||
|
||
## 🔒 Безопасность
|
||
|
||
1. **Разрешения пользователя:** Android требует подтверждения каждого запроса
|
||
2. **Таймауты:** Запросы автоматически истекают через 5 минут
|
||
3. **Аутентификация:** Проверка Operator ID для всех API запросов
|
||
4. **Логирование:** Все операции записываются в логи
|
||
|
||
## 🚀 Быстрый старт
|
||
|
||
1. **Запустите сервер:**
|
||
```bash
|
||
cd /home/data/god_eye/backend && npm start
|
||
```
|
||
|
||
2. **Откройте веб-демо:**
|
||
http://localhost:3001
|
||
|
||
3. **Запустите Android приложение** и подключите к серверу
|
||
|
||
4. **Инициируйте подключение** через веб-интерфейс или API
|
||
|
||
5. **Примите запрос** на Android устройстве
|
||
|
||
6. **Наслаждайтесь** прямым WebRTC видеопотоком! |