Tafita1206 commited on
Commit
0cb68f2
Β·
verified Β·
1 Parent(s): d5ea5e4

Update server.js

Browse files
Files changed (1) hide show
  1. server.js +117 -8
server.js CHANGED
@@ -112,6 +112,7 @@ function genId(prefix) {
112
  // ─────────────────────────────────────────────────
113
  const connectedClients = new Map();
114
  const adminSessions = new Map();
 
115
  const wsRegistry = new Map();
116
 
117
  // ─────────────────────────────────────────────────
@@ -226,6 +227,83 @@ async function handleMessage(ws, msg, ip) {
226
  break;
227
  }
228
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
229
  // ════════════════════════════════════════
230
  // HEARTBEAT CLIENT
231
  // ════════════════════════════════════════
@@ -280,20 +358,30 @@ async function handleMessage(ws, msg, ip) {
280
  }
281
 
282
  // ════════════════════════════════════════
283
- // WEBRTC ANSWER (client β†’ admin)
284
  // ════════════════════════════════════════
285
  case 'webrtc_answer': {
286
  const { targetAdminSID, answer } = msg;
287
 
 
288
  const adminWs = adminSessions.get(targetAdminSID);
289
  if (adminWs && adminWs.readyState === WebSocket.OPEN) {
290
  send(adminWs, { type: 'webrtc_answer', answer });
291
  console.log(`[RTC] Answer: client β†’ admin(${targetAdminSID})`);
292
- } else {
293
- // Fallback: diffuser Γ  tous les admins connectΓ©s
294
- console.warn(`[RTC] Admin(${targetAdminSID}) introuvable, broadcast fallback`);
295
- broadcastAdmins({ type: 'webrtc_answer', answer });
296
  }
 
 
 
 
 
 
 
 
 
 
 
 
297
  break;
298
  }
299
 
@@ -310,11 +398,18 @@ async function handleMessage(ws, msg, ip) {
310
  send(dest, { type: 'webrtc_ice', candidate });
311
  }
312
  } else if (direction === 'to_admin') {
 
313
  const dest = adminSessions.get(targetId);
314
  if (dest && dest.readyState === WebSocket.OPEN) {
315
  send(dest, { type: 'webrtc_ice', candidate });
316
  } else {
317
- broadcastAdmins({ type: 'webrtc_ice', candidate });
 
 
 
 
 
 
318
  }
319
  }
320
  break;
@@ -329,12 +424,23 @@ async function handleMessage(ws, msg, ip) {
329
  const dest = connectedClients.get(targetId);
330
  if (dest) send(dest, { type: 'webrtc_end' });
331
  } else {
332
- const dest = adminSessions.get(targetId);
333
- if (dest) send(dest, { type: 'webrtc_end' });
 
 
334
  }
335
  break;
336
  }
337
 
 
 
 
 
 
 
 
 
 
338
  default:
339
  console.log('[WS] Message inconnu:', type);
340
  }
@@ -359,6 +465,9 @@ function handleDisconnect(ws) {
359
  dbAddHistory(id, 'disconnect');
360
  notifyAdmins({ type: 'client_disconnected', clientId: id });
361
  console.log(`[WS] Client dΓ©connectΓ©: ${id}`);
 
 
 
362
  } else if (info.type === 'admin') {
363
  adminSessions.delete(info.id);
364
  console.log(`[WS] Admin dΓ©connectΓ©: ${info.id}`);
 
112
  // ─────────────────────────────────────────────────
113
  const connectedClients = new Map();
114
  const adminSessions = new Map();
115
+ const ownerSessions = new Map(); // Map<ownerSID, {ws, clientId}>
116
  const wsRegistry = new Map();
117
 
118
  // ─────────────────────────────────────────────────
 
227
  break;
228
  }
229
 
230
+ // ════════════════════════════════════════
231
+ // ENREGISTREMENT OWNER (propriΓ©taire)
232
+ // Le propriΓ©taire se connecte avec son clientId
233
+ // Il reΓ§oit le flux WebRTC de son propre appareil
234
+ // ════════════════════════════════════════
235
+ case 'register_owner': {
236
+ const { clientId } = msg;
237
+ if (!clientId || !db.clients[clientId]) {
238
+ send(ws, { type: 'error', code: 'NOT_FOUND', message: 'Client ID inconnu' });
239
+ return;
240
+ }
241
+ const ownerSID = genId('OSID');
242
+ ownerSessions.set(ownerSID, { ws, clientId });
243
+ wsRegistry.set(ws, { type: 'owner', id: ownerSID, clientId });
244
+
245
+ send(ws, {
246
+ type: 'owner_registered',
247
+ ownerSID,
248
+ clientId,
249
+ client: buildClientInfo(clientId),
250
+ });
251
+ console.log(`[WS] Owner connectΓ©: ${ownerSID} pour client(${clientId}) depuis ${ip}`);
252
+ break;
253
+ }
254
+
255
+ // ════════════════════════════════════════
256
+ // CALL FROM OWNER β†’ son propre client APK
257
+ // ════════════════════════════════════════
258
+ case 'owner_call_client': {
259
+ const info = wsRegistry.get(ws);
260
+ if (info?.type !== 'owner') return;
261
+ const { mode } = msg;
262
+ const { clientId } = info;
263
+ const clientWs = connectedClients.get(clientId);
264
+ if (!clientWs || clientWs.readyState !== WebSocket.OPEN) {
265
+ send(ws, { type: 'call_error', clientId, message: 'Appareil hors ligne' });
266
+ return;
267
+ }
268
+ send(clientWs, { type: 'incoming_call', mode: mode || 'manual', adminSID: info.id });
269
+ send(ws, { type: 'call_initiated', clientId });
270
+ console.log(`[CALL] Owner(${info.id}) β†’ Client(${clientId}) mode=${mode}`);
271
+ break;
272
+ }
273
+
274
+ // ════════════════════════════════════════
275
+ // WEBRTC OFFER (owner β†’ son client APK)
276
+ // ════════════════════════════════════════
277
+ case 'owner_webrtc_offer': {
278
+ const info = wsRegistry.get(ws);
279
+ if (info?.type !== 'owner') return;
280
+ const { offer } = msg;
281
+ const { clientId, id: ownerSID } = info;
282
+ const clientWs = connectedClients.get(clientId);
283
+ if (!clientWs || clientWs.readyState !== WebSocket.OPEN) {
284
+ send(ws, { type: 'rtc_error', message: `Appareil ${clientId} non connectΓ©` });
285
+ return;
286
+ }
287
+ send(clientWs, { type: 'webrtc_offer', offer, adminSID: ownerSID });
288
+ console.log(`[RTC] Offer: owner(${ownerSID}) β†’ client(${clientId})`);
289
+ break;
290
+ }
291
+
292
+ // ════════════════════════════════════════
293
+ // ICE depuis owner β†’ son client APK
294
+ // ════════════════════════════════════════
295
+ case 'owner_webrtc_ice': {
296
+ const info = wsRegistry.get(ws);
297
+ if (info?.type !== 'owner') return;
298
+ const { candidate } = msg;
299
+ const { clientId } = info;
300
+ const clientWs = connectedClients.get(clientId);
301
+ if (clientWs && clientWs.readyState === WebSocket.OPEN) {
302
+ send(clientWs, { type: 'webrtc_ice', candidate });
303
+ }
304
+ break;
305
+ }
306
+
307
  // ════════════════════════════════════════
308
  // HEARTBEAT CLIENT
309
  // ════════════════════════════════════════
 
358
  }
359
 
360
  // ════════════════════════════════════════
361
+ // WEBRTC ANSWER (client β†’ admin ou owner)
362
  // ════════════════════════════════════════
363
  case 'webrtc_answer': {
364
  const { targetAdminSID, answer } = msg;
365
 
366
+ // Chercher d'abord dans adminSessions
367
  const adminWs = adminSessions.get(targetAdminSID);
368
  if (adminWs && adminWs.readyState === WebSocket.OPEN) {
369
  send(adminWs, { type: 'webrtc_answer', answer });
370
  console.log(`[RTC] Answer: client β†’ admin(${targetAdminSID})`);
371
+ break;
 
 
 
372
  }
373
+
374
+ // Sinon chercher dans ownerSessions
375
+ const ownerEntry = ownerSessions.get(targetAdminSID);
376
+ if (ownerEntry && ownerEntry.ws.readyState === WebSocket.OPEN) {
377
+ send(ownerEntry.ws, { type: 'webrtc_answer', answer });
378
+ console.log(`[RTC] Answer: client β†’ owner(${targetAdminSID})`);
379
+ break;
380
+ }
381
+
382
+ // Fallback: diffuser Γ  tous les admins connectΓ©s
383
+ console.warn(`[RTC] Dest(${targetAdminSID}) introuvable, broadcast fallback`);
384
+ broadcastAdmins({ type: 'webrtc_answer', answer });
385
  break;
386
  }
387
 
 
398
  send(dest, { type: 'webrtc_ice', candidate });
399
  }
400
  } else if (direction === 'to_admin') {
401
+ // Chercher admin d'abord
402
  const dest = adminSessions.get(targetId);
403
  if (dest && dest.readyState === WebSocket.OPEN) {
404
  send(dest, { type: 'webrtc_ice', candidate });
405
  } else {
406
+ // Chercher owner ensuite
407
+ const ownerEntry = ownerSessions.get(targetId);
408
+ if (ownerEntry && ownerEntry.ws.readyState === WebSocket.OPEN) {
409
+ send(ownerEntry.ws, { type: 'webrtc_ice', candidate });
410
+ } else {
411
+ broadcastAdmins({ type: 'webrtc_ice', candidate });
412
+ }
413
  }
414
  }
415
  break;
 
424
  const dest = connectedClients.get(targetId);
425
  if (dest) send(dest, { type: 'webrtc_end' });
426
  } else {
427
+ const destAdmin = adminSessions.get(targetId);
428
+ if (destAdmin) { send(destAdmin, { type: 'webrtc_end' }); return; }
429
+ const destOwner = ownerSessions.get(targetId);
430
+ if (destOwner) send(destOwner.ws, { type: 'webrtc_end' });
431
  }
432
  break;
433
  }
434
 
435
+ // FIN SESSION OWNER β†’ client
436
+ case 'owner_webrtc_end': {
437
+ const info = wsRegistry.get(ws);
438
+ if (info?.type !== 'owner') return;
439
+ const clientWs = connectedClients.get(info.clientId);
440
+ if (clientWs) send(clientWs, { type: 'webrtc_end' });
441
+ break;
442
+ }
443
+
444
  default:
445
  console.log('[WS] Message inconnu:', type);
446
  }
 
465
  dbAddHistory(id, 'disconnect');
466
  notifyAdmins({ type: 'client_disconnected', clientId: id });
467
  console.log(`[WS] Client dΓ©connectΓ©: ${id}`);
468
+ } else if (info.type === 'owner') {
469
+ ownerSessions.delete(info.id);
470
+ console.log(`[WS] Owner dΓ©connectΓ©: ${info.id} (client: ${info.clientId})`);
471
  } else if (info.type === 'admin') {
472
  adminSessions.delete(info.id);
473
  console.log(`[WS] Admin dΓ©connectΓ©: ${info.id}`);