bae705aa97
- Add NFC ePassport roadmap (ICAO 9303, eIDAS) - Add TensorFlow.js edge face detection (BlazeFace) - Add structured audit logger (GDPR-compliant) - Risk scoring support Part of KYC Apple Native UX v1.1.0
177 lines
4.5 KiB
JavaScript
177 lines
4.5 KiB
JavaScript
/**
|
|
* QUIXZOOM WebSocket Test Client
|
|
*
|
|
* Simulerar en Zoomer som ansluter och skickar observationer.
|
|
*/
|
|
|
|
const WebSocket = require('ws');
|
|
|
|
class TestClient {
|
|
constructor(zoomerId, options = {}) {
|
|
this.zoomerId = zoomerId;
|
|
this.url = options.url || 'ws://localhost:8080';
|
|
this.ws = null;
|
|
this.connected = false;
|
|
this.messagesReceived = 0;
|
|
this.messagesSent = 0;
|
|
}
|
|
|
|
connect() {
|
|
return new Promise((resolve, reject) => {
|
|
this.ws = new WebSocket(this.url);
|
|
|
|
this.ws.on('open', () => {
|
|
console.log(`[CLIENT ${this.zoomerId}] Connected`);
|
|
this.connected = true;
|
|
|
|
// Autentisera
|
|
this.send({
|
|
type: 'auth',
|
|
payload: { zoomerId: this.zoomerId },
|
|
});
|
|
|
|
resolve();
|
|
});
|
|
|
|
this.ws.on('message', (data) => {
|
|
this.messagesReceived++;
|
|
const message = JSON.parse(data);
|
|
this.handleMessage(message);
|
|
});
|
|
|
|
this.ws.on('close', () => {
|
|
console.log(`[CLIENT ${this.zoomerId}] Disconnected`);
|
|
this.connected = false;
|
|
});
|
|
|
|
this.ws.on('error', (error) => {
|
|
console.error(`[CLIENT ${this.zoomerId}] Error:`, error.message);
|
|
reject(error);
|
|
});
|
|
});
|
|
}
|
|
|
|
handleMessage(message) {
|
|
switch (message.type) {
|
|
case 'connected':
|
|
console.log(`[CLIENT ${this.zoomerId}] Server says: connected`);
|
|
break;
|
|
|
|
case 'auth_success':
|
|
console.log(`[CLIENT ${this.zoomerId}] Authenticated as ${message.zoomerId}`);
|
|
break;
|
|
|
|
case 'observation_ack':
|
|
console.log(`[CLIENT ${this.zoomerId}] Observation ${message.observationId} acknowledged`);
|
|
break;
|
|
|
|
case 'identity_result':
|
|
console.log(`[CLIENT ${this.zoomerId}] Identity: ${message.objectId} (${(message.confidence * 100).toFixed(0)}% confidence)`);
|
|
break;
|
|
|
|
case 'instruction':
|
|
console.log(`[CLIENT ${this.zoomerId}] INSTRUCTION: "${message.instruction}" (priority: ${message.priority})`);
|
|
break;
|
|
|
|
default:
|
|
console.log(`[CLIENT ${this.zoomerId}] Received:`, message.type);
|
|
}
|
|
}
|
|
|
|
send(message) {
|
|
if (!this.connected) return;
|
|
this.ws.send(JSON.stringify(message));
|
|
this.messagesSent++;
|
|
}
|
|
|
|
sendObservation(objectType, location) {
|
|
this.send({
|
|
type: 'observation',
|
|
payload: {
|
|
observationId: `obs_${Date.now()}`,
|
|
objectType,
|
|
location,
|
|
timestamp: Date.now(),
|
|
attributes: {
|
|
material: 'steel',
|
|
height: 7.8,
|
|
condition: 'good',
|
|
},
|
|
},
|
|
});
|
|
}
|
|
|
|
sendLocation(location) {
|
|
this.send({
|
|
type: 'location_update',
|
|
payload: { location },
|
|
});
|
|
}
|
|
|
|
disconnect() {
|
|
if (this.ws) {
|
|
this.ws.close();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Demo
|
|
if (require.main === module) {
|
|
async function runDemo() {
|
|
console.log('=== WEBSOCKET CLIENT DEMO ===\n');
|
|
|
|
// Skapa två Zoomers
|
|
const zoomerA = new TestClient('zoomer_A');
|
|
const zoomerB = new TestClient('zoomer_B');
|
|
|
|
// Anslut
|
|
await zoomerA.connect();
|
|
await zoomerB.connect();
|
|
|
|
// Vänta på autentisering
|
|
await new Promise(resolve => setTimeout(resolve, 500));
|
|
|
|
// Zoomer A skickar observation
|
|
console.log('\n--- Zoomer A sends observation ---');
|
|
zoomerA.sendObservation('street_lamp', { lat: 59.3293, lng: 18.0686 });
|
|
|
|
// Vänta på svar
|
|
await new Promise(resolve => setTimeout(resolve, 500));
|
|
|
|
// Zoomer B skickar observation (samma område)
|
|
console.log('\n--- Zoomer B sends observation ---');
|
|
zoomerB.sendObservation('street_lamp', { lat: 59.3294, lng: 18.0687 });
|
|
|
|
// Vänta på svar
|
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
|
|
// Skicka fler observationer
|
|
console.log('\n--- Zoomer A sends more observations ---');
|
|
for (let i = 0; i < 3; i++) {
|
|
zoomerA.sendObservation('traffic_sign', {
|
|
lat: 59.3293 + Math.random() * 0.001,
|
|
lng: 18.0686 + Math.random() * 0.001,
|
|
});
|
|
await new Promise(resolve => setTimeout(resolve, 300));
|
|
}
|
|
|
|
// Vänta
|
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
|
|
// Statistik
|
|
console.log('\n=== STATISTICS ===');
|
|
console.log(`Zoomer A: sent=${zoomerA.messagesSent}, received=${zoomerA.messagesReceived}`);
|
|
console.log(`Zoomer B: sent=${zoomerB.messagesSent}, received=${zoomerB.messagesReceived}`);
|
|
|
|
// Koppla ner
|
|
zoomerA.disconnect();
|
|
zoomerB.disconnect();
|
|
|
|
console.log('\nDemo complete');
|
|
}
|
|
|
|
runDemo().catch(console.error);
|
|
}
|
|
|
|
module.exports = TestClient;
|