Files
god_eye/test-connection.js
2025-10-04 11:55:55 +09:00

324 lines
9.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env node
/**
* Тестовый скрипт для симуляции подключения Android устройства
* и тестирования подключения Desktop Operator к телефону
*/
const io = require('socket.io-client');
const axios = require('axios');
const SERVER_URL = 'http://localhost:3001';
const WS_URL = 'ws://localhost:3001';
// Симулируем Android устройство
class AndroidSimulator {
constructor(deviceId) {
this.deviceId = deviceId;
this.socket = null;
this.isRegistered = false;
}
async connect() {
console.log('📱 Подключение Android устройства...');
this.socket = io(WS_URL, {
transports: ['websocket']
});
return new Promise((resolve, reject) => {
this.socket.on('connect', () => {
console.log(`✅ Android подключен: ${this.socket.id}`);
this.register();
resolve();
});
this.socket.on('connect_error', (error) => {
console.error('❌ Ошибка подключения Android:', error);
reject(error);
});
// Обработка запросов подключения
this.socket.on('connection:request', (data) => {
console.log('📞 Получен запрос подключения:', data);
this.handleConnectionRequest(data);
});
// Legacy обработка
this.socket.on('camera:request', (data) => {
console.log('📷 Получен запрос камеры (legacy):', data);
this.handleCameraRequest(data);
});
});
}
register() {
console.log('📝 Регистрация Android устройства...');
this.socket.emit('register:android', {
deviceId: this.deviceId,
deviceInfo: {
manufacturer: 'Samsung',
model: 'Galaxy S21 Test',
androidVersion: '11',
availableCameras: ['back', 'front', 'ultra_wide', 'telephoto'],
appVersion: '1.0.0-test'
}
});
this.socket.on('register:success', (data) => {
console.log('✅ Android зарегистрирован:', data);
this.isRegistered = true;
});
}
handleConnectionRequest(data) {
console.log(`
🔔 ЗАПРОС ПОДКЛЮЧЕНИЯ:
Connection ID: ${data.connectionId}
Operator: ${data.operatorInfo?.name || 'Unknown'}
Camera: ${data.cameraType}
Expires: ${data.expiresAt}
`);
// Симулируем принятие запроса через 2 секунды
setTimeout(() => {
console.log('✅ Принимаем запрос подключения...');
this.socket.emit('connection:accept', {
connectionId: data.connectionId,
sessionId: data.sessionId,
cameraType: data.cameraType,
webrtcInfo: {
supported: true,
codecs: ['H264', 'VP8'],
resolutions: ['720p', '1080p', '4K']
},
timestamp: new Date().toISOString()
});
}, 2000);
}
handleCameraRequest(data) {
console.log(`
📷 LEGACY ЗАПРОС КАМЕРЫ:
Session ID: ${data.sessionId}
Operator: ${data.operatorId}
Camera: ${data.cameraType}
`);
// Симулируем принятие запроса
setTimeout(() => {
console.log('✅ Принимаем запрос камеры (legacy)...');
this.socket.emit('camera:response', {
sessionId: data.sessionId,
accepted: true,
reason: 'camera_granted',
cameraType: data.cameraType,
timestamp: new Date().toISOString()
});
}, 1500);
}
disconnect() {
if (this.socket) {
this.socket.disconnect();
console.log('📱 Android отключен');
}
}
}
// Симулируем Desktop Operator
class OperatorSimulator {
constructor(operatorId) {
this.operatorId = operatorId;
this.socket = null;
this.isRegistered = false;
}
async connect() {
console.log('💻 Подключение Desktop Operator...');
this.socket = io(WS_URL, {
transports: ['websocket']
});
return new Promise((resolve, reject) => {
this.socket.on('connect', () => {
console.log(`✅ Operator подключен: ${this.socket.id}`);
this.register();
resolve();
});
this.socket.on('connect_error', (error) => {
console.error('❌ Ошибка подключения Operator:', error);
reject(error);
});
// Обработка ответов на подключения
this.socket.on('connection:accepted', (data) => {
console.log('🎉 Подключение принято Android:', data);
});
this.socket.on('connection:rejected', (data) => {
console.log('❌ Подключение отклонено Android:', data);
});
this.socket.on('connection:timeout', (data) => {
console.log('⏰ Таймаут подключения:', data);
});
// Legacy события
this.socket.on('camera:accepted', (data) => {
console.log('📹 Камера принята (legacy):', data);
});
});
}
register() {
console.log('📝 Регистрация Desktop Operator...');
this.socket.emit('register:operator', {
operatorId: this.operatorId,
operatorInfo: {
name: 'Тестовый Оператор',
organization: 'QA Отдел',
permissions: ['view_cameras', 'request_camera', 'initiate_connection']
}
});
this.socket.on('register:success', (data) => {
console.log('✅ Operator зарегистрирован:', data);
this.isRegistered = true;
});
}
async getAvailableDevices() {
try {
const response = await axios.get(`${SERVER_URL}/api/operators/devices`, {
headers: {
'x-operator-id': this.operatorId
}
});
console.log('📱 Доступные устройства:', response.data);
return response.data.devices;
} catch (error) {
console.error('❌ Ошибка получения устройств:', error.response?.data || error.message);
return [];
}
}
async requestConnection(deviceId, cameraType = 'back') {
try {
console.log(`🔗 Запрос подключения к ${deviceId} (${cameraType})...`);
const response = await axios.post(`${SERVER_URL}/api/operators/connections/request`, {
deviceId,
cameraType
}, {
headers: {
'Content-Type': 'application/json',
'x-operator-id': this.operatorId
}
});
console.log('✅ Запрос подключения отправлен:', response.data);
return response.data;
} catch (error) {
console.error('❌ Ошибка запроса подключения:', error.response?.data || error.message);
return null;
}
}
async getConnections() {
try {
const response = await axios.get(`${SERVER_URL}/api/operators/connections`, {
headers: {
'x-operator-id': this.operatorId
}
});
console.log('🔗 Активные подключения:', response.data);
return response.data.connections;
} catch (error) {
console.error('❌ Ошибка получения подключений:', error.response?.data || error.message);
return [];
}
}
disconnect() {
if (this.socket) {
this.socket.disconnect();
console.log('💻 Operator отключен');
}
}
}
// Основная функция тестирования
async function runTest() {
console.log('🚀 Запуск тестирования подключения Operator → Android');
console.log('=' .repeat(60));
const deviceId = 'test_android_' + Math.random().toString(36).substr(2, 9);
const operatorId = 'test_operator_' + Math.random().toString(36).substr(2, 9);
const android = new AndroidSimulator(deviceId);
const operator = new OperatorSimulator(operatorId);
try {
// 1. Подключаем Android
await android.connect();
await new Promise(resolve => setTimeout(resolve, 1000));
// 2. Подключаем Operator
await operator.connect();
await new Promise(resolve => setTimeout(resolve, 1000));
// 3. Проверяем доступные устройства
console.log('\n📋 Шаг 1: Проверка доступных устройств');
const devices = await operator.getAvailableDevices();
if (devices.length === 0) {
console.log('❌ Нет доступных устройств');
return;
}
// 4. Инициируем подключение
console.log('\n🔗 Шаг 2: Инициация подключения');
const connectionResult = await operator.requestConnection(deviceId, 'back');
if (!connectionResult) {
console.log('❌ Не удалось создать подключение');
return;
}
// 5. Ждем обработки подключения
console.log('\n⏳ Шаг 3: Ожидание ответа Android...');
await new Promise(resolve => setTimeout(resolve, 5000));
// 6. Проверяем статус подключений
console.log('\n📊 Шаг 4: Проверка статуса подключений');
await operator.getConnections();
console.log('\n✅ Тестирование завершено!');
} catch (error) {
console.error('❌ Ошибка тестирования:', error);
} finally {
// Отключаем всех
setTimeout(() => {
android.disconnect();
operator.disconnect();
process.exit(0);
}, 2000);
}
}
// Запуск
if (require.main === module) {
runTest();
}
module.exports = { AndroidSimulator, OperatorSimulator };