Files
boc/quixzoom-capture-pipeline/websocket/test-client.js
T
Bernt bae705aa97 ARCHITECTURE: NFC roadmap, edge AI, audit logging
- 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
2026-06-29 16:24:48 +00:00

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;