aotrautils 0.0.1475 → 0.0.1477
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aotrautils/aotrautils.build.js +506 -741
- aotrautils/package.json +1 -1
aotrautils/aotrautils.build.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
|
2
2
|
|
3
|
-
/*utils COMMONS library associated with aotra version : «1_29072022-2359 (26/04/2025-
|
3
|
+
/*utils COMMONS library associated with aotra version : «1_29072022-2359 (26/04/2025-16:15:49)»*/
|
4
4
|
/*-----------------------------------------------------------------------------*/
|
5
5
|
|
6
6
|
|
@@ -4894,7 +4894,7 @@ AOTRAUTILS_LIB_IS_LOADED=true;
|
|
4894
4894
|
|
4895
4895
|
|
4896
4896
|
|
4897
|
-
/*utils CLIENT library associated with aotra version : «1_29072022-2359 (26/04/2025-
|
4897
|
+
/*utils CLIENT library associated with aotra version : «1_29072022-2359 (26/04/2025-16:15:49)»*/
|
4898
4898
|
/*-----------------------------------------------------------------------------*/
|
4899
4899
|
/* ## Utility global methods in a browser (htmljs) client environment.
|
4900
4900
|
*
|
@@ -13466,7 +13466,7 @@ getAORTACClient=function(clientId=getUUID(), serverNodeOrigin="ws://127.0.0.1:40
|
|
13466
13466
|
|
13467
13467
|
|
13468
13468
|
|
13469
|
-
/*utils GEOMETRY library associated with aotra version : «1_29072022-2359 (26/04/2025-
|
13469
|
+
/*utils GEOMETRY library associated with aotra version : «1_29072022-2359 (26/04/2025-16:15:49)»*/
|
13470
13470
|
/*-----------------------------------------------------------------------------*/
|
13471
13471
|
|
13472
13472
|
|
@@ -14705,7 +14705,7 @@ function rayVsUnitSphereClosestPoint(p, r) {
|
|
14705
14705
|
// MUST REMAIN AT THE END OF THIS LIBRARY FILE !
|
14706
14706
|
|
14707
14707
|
AOTRAUTILS_GEOMETRY_LIB_IS_LOADED=true;
|
14708
|
-
/*utils AI library associated with aotra version : «1_29072022-2359 (26/04/2025-
|
14708
|
+
/*utils AI library associated with aotra version : «1_29072022-2359 (26/04/2025-16:15:49)»*/
|
14709
14709
|
/*-----------------------------------------------------------------------------*/
|
14710
14710
|
|
14711
14711
|
|
@@ -14851,11 +14851,11 @@ getOpenAIAPIClient=(modelName, apiURL, agentRole, defaultPrompt)=>{
|
|
14851
14851
|
|
14852
14852
|
|
14853
14853
|
|
14854
|
-
/*utils
|
14854
|
+
/*utils CONSOLE library associated with aotra version : «1_29072022-2359 (26/04/2025-16:15:49)»*/
|
14855
14855
|
/*-----------------------------------------------------------------------------*/
|
14856
14856
|
|
14857
14857
|
|
14858
|
-
/* ## Utility global methods in a javascript, console (nodejs)
|
14858
|
+
/* ## Utility global methods in a javascript, console (nodejs) or vanilla javascript with no browser environment.
|
14859
14859
|
*
|
14860
14860
|
* This set of methods gathers utility generic-purpose methods usable in any JS project.
|
14861
14861
|
* Several authors of snippets published freely on the Internet contributed to this library.
|
@@ -15189,7 +15189,6 @@ WebsocketImplementation={
|
|
15189
15189
|
throw new Error("ERROR : SERVER : Server launch is not supported in a non-nodejs context for any implementation.");
|
15190
15190
|
}
|
15191
15191
|
|
15192
|
-
|
15193
15192
|
|
15194
15193
|
// TODO : FIXME : Use one single interface !
|
15195
15194
|
// NODE SERVER MODE ONLY :
|
@@ -15215,322 +15214,20 @@ WebsocketImplementation={
|
|
15215
15214
|
}
|
15216
15215
|
|
15217
15216
|
serverSocket.on("error",(error)=>{
|
15218
|
-
|
15219
15217
|
// TRACE
|
15220
15218
|
lognow("ERROR : An error occurred when trying to start the server : ",error);
|
15221
15219
|
|
15222
15220
|
});
|
15223
15221
|
|
15224
15222
|
// NODE SERVER INSTANCE :
|
15225
|
-
const nodeServerInstance=
|
15226
|
-
|
15227
|
-
onClientLostListeners:[],
|
15228
|
-
|
15229
|
-
clientPingIntervalMillis:5000,
|
15230
|
-
setPingPongTimeout:(clientPingIntervalMillis)=>{
|
15231
|
-
nodeServerInstance.clientPingIntervalMillis=clientPingIntervalMillis;
|
15232
|
-
return nodeServerInstance;
|
15233
|
-
},
|
15234
|
-
|
15235
|
-
// clientsSockets:[],
|
15236
|
-
serverSocket:serverSocket,
|
15237
|
-
listenableServer:listenableServer,
|
15238
|
-
|
15239
|
-
receptionEntryPoints:[],
|
15240
|
-
|
15241
|
-
close:(doOnCloseServer)=>{
|
15242
|
-
if(!nodeServerInstance.serverSocket) return;
|
15243
|
-
nodeServerInstance.serverSocket.close(()=>{
|
15244
|
-
if(!nodeServerInstance.listenableServer) return;
|
15245
|
-
nodeServerInstance.listenableServer.close(doOnCloseServer);
|
15246
|
-
});
|
15247
|
-
},
|
15248
|
-
|
15249
|
-
receive:(channelNameParam, doOnIncomingMessage, clientsRoomsTag=null)=>{
|
15250
|
-
|
15251
|
-
// DBG
|
15252
|
-
lognow("(SERVER) Registering receive for «"+channelNameParam+"»...");
|
15253
|
-
|
15254
|
-
|
15255
|
-
|
15256
|
-
const receptionEntryPoint={
|
15257
|
-
channelName:channelNameParam,
|
15258
|
-
clientsRoomsTag:clientsRoomsTag,
|
15259
|
-
execute:(eventOrMessage, clientSocketParam)=>{
|
15260
|
-
|
15261
|
-
// With «ws» library we have no choive than register message events inside a «connection» event !
|
15262
|
-
|
15263
|
-
// // DBG
|
15264
|
-
// lognow("(SERVER) RECEIVED SOMETHING FROM CLIENT...", eventOrMessage.data);
|
15265
|
-
|
15266
|
-
// dataWrapped=parseJSON(dataWrapped);
|
15267
|
-
// dataWrapped=getAt(dataWrapped,0);// We get the root element
|
15268
|
-
|
15269
|
-
|
15270
|
-
const dataWrapped=WebsocketImplementation.getMessageDataBothImplementations(eventOrMessage);
|
15271
|
-
|
15272
|
-
|
15273
|
-
// Channel information is stored in exchanged data :
|
15274
|
-
if(dataWrapped.channelName!==receptionEntryPoint.channelName) return;
|
15275
|
-
|
15276
|
-
|
15277
|
-
// // DBG
|
15278
|
-
// lognow("(SERVER) ENTRY POINT IS OF THE RIGHT CHANNEL:", receptionEntryPoint.channelName);
|
15279
|
-
|
15280
|
-
|
15281
|
-
// TODO : FIXME : Use one single interface !
|
15282
|
-
// Room information is stored in client socket object :
|
15283
|
-
const isClientInRoom=WebsocketImplementation.isInRoom(clientSocketParam, receptionEntryPoint.clientsRoomsTag);
|
15284
|
-
|
15285
|
-
// DBG
|
15286
|
-
lognow("(SERVER) isClientInRoom:",isClientInRoom);
|
15287
|
-
|
15288
|
-
if(!isClientInRoom) return;
|
15289
|
-
|
15290
|
-
if(doOnIncomingMessage){
|
15291
|
-
// DBG
|
15292
|
-
lognow("(SERVER) doOnIncomingMessage:");
|
15293
|
-
doOnIncomingMessage(dataWrapped.data, clientSocketParam);
|
15294
|
-
}
|
15295
|
-
|
15296
|
-
},
|
15297
|
-
};
|
15298
|
-
|
15299
|
-
|
15300
|
-
///!!!
|
15301
|
-
nodeServerInstance.receptionEntryPoints.push(receptionEntryPoint);
|
15302
|
-
|
15303
|
-
// SPECIAL FOR THE SOCKETIO IMPLEMENTATION :
|
15304
|
-
if(WebsocketImplementation.useSocketIOImplementation){
|
15305
|
-
const channelName=receptionEntryPoint.channelName;
|
15306
|
-
clientSocket.on(channelName, (eventOrMessage)=>{
|
15307
|
-
receptionEntryPoint.execute(eventOrMessage, clientSocket);
|
15308
|
-
});
|
15309
|
-
}
|
15310
|
-
|
15311
|
-
|
15312
|
-
// // DBG
|
15313
|
-
// console.log("ADD RECEPTION ENTRY POINT channelName:«"+channelName+"»! nodeServerInstance.receptionEntryPoints.length:",nodeServerInstance.receptionEntryPoints.length);
|
15314
|
-
|
15315
|
-
|
15316
|
-
return nodeServerInstance;
|
15317
|
-
},
|
15318
|
-
|
15319
|
-
|
15320
|
-
send:(channelName, data, clientsRoomsTag=null, clientSocketParam=null)=>{
|
15321
|
-
|
15322
|
-
// DBG
|
15323
|
-
lognow("(SERVER) SERVER TRIES TO SEND !");
|
15324
|
-
|
15325
|
-
|
15326
|
-
if(!clientSocketParam){
|
15327
|
-
|
15328
|
-
// DBG
|
15329
|
-
lognow("(SERVER) (server sends to all clients)");
|
15330
|
-
|
15331
|
-
// TODO : FIXME : Use one single interface !
|
15332
|
-
let serverClients;
|
15333
|
-
if(!WebsocketImplementation.useSocketIOImplementation) serverClients=nodeServerInstance.serverSocket.clients;
|
15334
|
-
// OLD: else serverClients=nodeServerInstance.serverSocket.sockets.clients();
|
15335
|
-
else serverClients=nodeServerInstance.serverSocket.sockets.sockets;
|
15336
|
-
|
15337
|
-
|
15338
|
-
|
15339
|
-
serverClients.forEach((clientSocket)=>{
|
15340
|
-
|
15341
|
-
|
15342
|
-
if(!isConnected(clientSocket)) return;
|
15343
|
-
|
15344
|
-
|
15345
|
-
// Room information is stored in client socket object :
|
15346
|
-
if(!WebsocketImplementation.isInRoom(clientSocket,clientsRoomsTag)) return;
|
15347
|
-
|
15348
|
-
// Channel information is stored in exchanged data :
|
15349
|
-
let dataWrapped={channelName:channelName, data:data};
|
15350
|
-
|
15351
|
-
|
15352
|
-
dataWrapped=stringifyObject(dataWrapped);
|
15353
|
-
|
15354
|
-
// TODO : FIXME : Use one single interface !
|
15355
|
-
if(!WebsocketImplementation.useSocketIOImplementation) clientSocket.send(dataWrapped);
|
15356
|
-
else clientSocket.emit(channelName,dataWrapped);
|
15357
|
-
|
15358
|
-
});
|
15359
|
-
|
15360
|
-
}else{
|
15361
|
-
|
15362
|
-
// DBG
|
15363
|
-
lognow("(SERVER) (server sends to a client)");
|
15364
|
-
|
15365
|
-
|
15366
|
-
// TODO : FIXME : Use one single interface !
|
15367
|
-
let clientSocket=clientSocketParam;
|
15368
|
-
if(!WebsocketImplementation.useSocketIOImplementation) if(clientSocket.readyState!==WebSocket.OPEN) return;
|
15369
|
-
else if(clientSocket.connected) return;
|
15370
|
-
|
15371
|
-
|
15372
|
-
// Room information is stored in client socket object :
|
15373
|
-
if(!WebsocketImplementation.isInRoom(clientSocket,clientsRoomsTag)) return;
|
15374
|
-
|
15375
|
-
// Channel information is stored in exchanged data :
|
15376
|
-
let dataWrapped={channelName:channelName, data:data};
|
15377
|
-
dataWrapped=stringifyObject(dataWrapped);
|
15378
|
-
|
15379
|
-
|
15380
|
-
// DBG
|
15381
|
-
lognow("(SERVER) WebsocketImplementation.useSocketIOImplementation:"+WebsocketImplementation.useSocketIOImplementation);
|
15382
|
-
// lognow("(SERVER) dataWrapped:"+dataWrapped);
|
15383
|
-
|
15384
|
-
|
15385
|
-
// TODO : FIXME : Use one single interface !
|
15386
|
-
if(!WebsocketImplementation.useSocketIOImplementation) clientSocket.send(dataWrapped);
|
15387
|
-
else clientSocket.emit(channelName,dataWrapped);
|
15388
|
-
|
15389
|
-
|
15390
|
-
}
|
15391
|
-
|
15392
|
-
|
15393
|
-
return nodeServerInstance;
|
15394
|
-
},
|
15395
|
-
|
15396
|
-
|
15397
|
-
onConnectionToClient:(doOnConnection)=>{
|
15398
|
-
|
15399
|
-
// «connection» is the only event fired by the serverSocket :
|
15400
|
-
nodeServerInstance.serverSocket.on("connection", (clientSocket)=>{
|
15401
|
-
|
15402
|
-
// DBG
|
15403
|
-
console.log("SERVER : ON CONNECTION !");
|
15404
|
-
|
15405
|
-
|
15406
|
-
// if(contains(nodeServerInstance.clientsSockets, clientSocket)) return;
|
15407
|
-
// nodeServerInstance.clientsSockets.push(clientSocket);
|
15408
|
-
|
15409
|
-
|
15410
|
-
const clientId="autogeneratedid_"+getUUID();
|
15411
|
-
|
15412
|
-
|
15413
|
-
clientSocket.clientId=clientId;
|
15414
|
-
|
15415
|
-
|
15416
|
-
|
15417
|
-
const doOnMessage=(eventOrMessage)=>{
|
15418
|
-
// We execute the events registration listeners entry points:
|
15419
|
-
foreach(nodeServerInstance.receptionEntryPoints,(receptionEntryPoint,i)=>{
|
15420
|
-
receptionEntryPoint.execute(eventOrMessage, clientSocket);
|
15421
|
-
});
|
15422
|
-
};
|
15423
|
-
|
15424
|
-
if(!WebsocketImplementation.useSocketIOImplementation){ clientSocket.addEventListener("message", doOnMessage);
|
15425
|
-
// NO: else clientSocket.on("message", doOnMessage);
|
15426
|
-
}
|
15427
|
-
|
15428
|
-
doOnConnection(nodeServerInstance, clientSocket);
|
15429
|
-
|
15430
|
-
|
15431
|
-
// DBG
|
15432
|
-
lognow("DEBUG : Starting ping-pong with client : clientSocket.clientId:",clientSocket.clientId);
|
15433
|
-
lognow("DEBUG : WebsocketImplementation.useSocketIOImplementation:",WebsocketImplementation.useSocketIOImplementation);
|
15434
|
-
lognow("DEBUG : clientSocket.readyState:",clientSocket.readyState);
|
15435
|
-
|
15436
|
-
|
15437
|
-
// To make the server aware of the clients connections states :
|
15438
|
-
clientSocket.isConnectionAlive=true;
|
15439
|
-
clientSocket.stateCheckInterval=setInterval(()=>{
|
15440
|
-
|
15441
|
-
|
15442
|
-
if (clientSocket.isConnectionAlive===false){
|
15443
|
-
|
15444
|
-
|
15445
|
-
// On today, this method is named as same for the two implementations :
|
15446
|
-
// TRACE
|
15447
|
-
lognow("(SERVER) Removing all listeners for client socket «"+clientSocket.clientId+"».");
|
15448
|
-
|
15449
|
-
clientSocket.removeAllListeners();
|
15450
|
-
|
15451
|
-
|
15452
|
-
// TODO : FIXME : Use one single interface !
|
15453
|
-
if(!WebsocketImplementation.useSocketIOImplementation) clientSocket.terminate();
|
15454
|
-
else clientSocket.emit("endConnection");
|
15455
|
-
|
15456
|
-
if(!empty(nodeServerInstance.onClientLostListeners))
|
15457
|
-
foreach(nodeServerInstance.onClientLostListeners,l=>{l.execute(clientSocket);});
|
15458
|
-
|
15459
|
-
// DBG
|
15460
|
-
lognow("DEBUG : (SERVER) Connection closed for failed ping-pong.");
|
15461
|
-
|
15462
|
-
|
15463
|
-
clearInterval(clientSocket.stateCheckInterval);
|
15464
|
-
return;
|
15465
|
-
}
|
15466
|
-
|
15467
|
-
clientSocket.isConnectionAlive=false;
|
15468
|
-
|
15469
|
-
// // DBG
|
15470
|
-
// lognow("(SERVER) DEBUG : SENDING PING");
|
15471
|
-
|
15472
|
-
if(!WebsocketImplementation.useSocketIOImplementation) clientSocket.ping();
|
15473
|
-
// OLD :
|
15474
|
-
// else clientSocket.emit("ping");
|
15475
|
-
else nodeServerInstance.send("protocol",{type:"ping"}, null, clientSocket);
|
15476
|
-
|
15477
|
-
|
15478
|
-
}, nodeServerInstance.clientPingIntervalMillis);
|
15479
|
-
|
15480
|
-
|
15481
|
-
if(!WebsocketImplementation.useSocketIOImplementation){
|
15482
|
-
clientSocket.on("pong",()=>{
|
15483
|
-
clientSocket.isConnectionAlive=true;
|
15484
|
-
});
|
15485
|
-
}else{
|
15486
|
-
// // OLD :
|
15487
|
-
// clientSocket.on("ping",()=>{
|
15488
|
-
// clientSocket.isConnectionAlive=true;
|
15489
|
-
// });
|
15490
|
-
|
15491
|
-
nodeServerInstance.receive("protocol",(message)=>{
|
15492
|
-
if(message.type!=="pong") return;
|
15493
|
-
clientSocket.isConnectionAlive=true;
|
15494
|
-
});
|
15495
|
-
|
15496
|
-
}
|
15497
|
-
|
15498
|
-
|
15499
|
-
|
15500
|
-
});
|
15501
|
-
|
15502
|
-
|
15503
|
-
return nodeServerInstance;
|
15504
|
-
},
|
15505
|
-
|
15506
|
-
onFinalize:(doOnFinalizeServer)=>{
|
15507
|
-
|
15508
|
-
doOnFinalizeServer(nodeServerInstance);
|
15509
|
-
|
15510
|
-
// TRACE
|
15511
|
-
console.log("INFO : SERVER : Node server setup complete.");
|
15512
|
-
|
15513
|
-
return nodeServerInstance;
|
15514
|
-
},
|
15515
|
-
|
15516
|
-
addToRoom:(clientSocket,clientRoomTag)=>{
|
15517
|
-
clientSocket.clientRoomTag=clientRoomTag;
|
15518
|
-
},
|
15519
|
-
|
15520
|
-
|
15521
|
-
|
15522
|
-
};
|
15223
|
+
const nodeServerInstance=new NodeServerInstance(serverSocket, listenableServer);
|
15523
15224
|
|
15524
15225
|
// Join room server part protocol :
|
15525
15226
|
nodeServerInstance.receive("protocol",(message, clientSocket)=>{
|
15526
|
-
|
15527
15227
|
if(message.type!=="joinRoom" || !clientSocket) return;
|
15528
15228
|
nodeServerInstance.addToRoom(clientSocket, message.clientRoomTag);
|
15529
|
-
|
15530
15229
|
});
|
15531
15230
|
|
15532
|
-
|
15533
|
-
|
15534
15231
|
// To make the server aware of the clients connections states :
|
15535
15232
|
nodeServerInstance.serverSocket.on("close", function close() {
|
15536
15233
|
|
@@ -15543,8 +15240,6 @@ WebsocketImplementation={
|
|
15543
15240
|
clearInterval(clientSocket.stateCheckInterval);
|
15544
15241
|
});
|
15545
15242
|
});
|
15546
|
-
|
15547
|
-
|
15548
15243
|
|
15549
15244
|
return nodeServerInstance;
|
15550
15245
|
},
|
@@ -15562,14 +15257,12 @@ WebsocketImplementation={
|
|
15562
15257
|
return WebsocketImplementation.connectToServerFromBrowser(serverURL, port, isSecure, timeout);
|
15563
15258
|
},
|
15564
15259
|
|
15565
|
-
|
15566
15260
|
|
15567
15261
|
//
|
15568
15262
|
// NODE CLIENT
|
15569
15263
|
//
|
15570
15264
|
/*private*/connectToServerFromNode:(serverURL, port, isSecure, timeout)=>{
|
15571
15265
|
|
15572
|
-
|
15573
15266
|
// NODE CLIENT MODE ONLY :
|
15574
15267
|
let clientSocket;
|
15575
15268
|
if(!WebsocketImplementation.useSocketIOImplementation){
|
@@ -15598,219 +15291,13 @@ WebsocketImplementation={
|
|
15598
15291
|
// DBG
|
15599
15292
|
lognow("DEBUG : CLIENT : clientSocket created:");
|
15600
15293
|
|
15601
|
-
|
15602
|
-
// NODE CLIENT INSTANCE :
|
15603
|
-
const nodeClientInstance={
|
15604
|
-
clientSocket:clientSocket,
|
15605
|
-
|
15606
|
-
receptionEntryPoints:[],
|
15607
|
-
|
15608
|
-
receive:(channelNameParam, doOnIncomingMessage, clientsRoomsTag=null)=>{
|
15609
|
-
|
15610
|
-
const receptionEntryPoint={
|
15611
|
-
channelName:channelNameParam,
|
15612
|
-
clientsRoomsTag:clientsRoomsTag,
|
15613
|
-
execute:(eventOrMessage)=>{
|
15614
|
-
|
15615
|
-
// dataWrapped=parseJSON(dataWrapped);
|
15616
|
-
// dataWrapped=getAt(dataWrapped,0);// We get the root element
|
15617
|
-
// const dataWrapped=(WebsocketImplementation.useFlatStrings?parseJSON(eventOrMessage):eventOrMessage);
|
15618
|
-
|
15619
|
-
const dataWrapped=WebsocketImplementation.getMessageDataBothImplementations(eventOrMessage);
|
15620
|
-
|
15621
|
-
// Channel information is stored in exchanged data :
|
15622
|
-
if(dataWrapped.channelName && dataWrapped.channelName!==channelNameParam) return;
|
15623
|
-
|
15624
|
-
const clientSocket=nodeClientInstance.clientSocket;
|
15625
|
-
|
15626
|
-
// Room information is stored in client socket object :
|
15627
|
-
if(!WebsocketImplementation.isInRoom(clientSocket,clientsRoomsTag)) return;
|
15628
|
-
|
15629
|
-
if(doOnIncomingMessage) doOnIncomingMessage(dataWrapped.data, clientSocket);
|
15630
|
-
|
15631
|
-
|
15632
|
-
}
|
15633
|
-
};
|
15634
|
-
|
15635
|
-
|
15636
|
-
///!!!
|
15637
|
-
nodeClientInstance.receptionEntryPoints.push(receptionEntryPoint);
|
15638
|
-
|
15639
|
-
// SPECIAL FOR THE SOCKETIO IMPLEMENTATION :
|
15640
|
-
if(WebsocketImplementation.useSocketIOImplementation){
|
15641
|
-
const channelName=receptionEntryPoint.channelName;
|
15642
|
-
clientSocket.on(channelName, (eventOrMessage)=>{
|
15643
|
-
receptionEntryPoint.execute(eventOrMessage, clientSocket);
|
15644
|
-
});
|
15645
|
-
}
|
15646
|
-
|
15647
|
-
|
15648
|
-
return nodeClientInstance;
|
15649
|
-
},
|
15650
|
-
|
15651
|
-
|
15652
|
-
|
15653
|
-
// TODO : FIXME : DUPLICATED CODE !
|
15654
|
-
sendChainable:(channelNameParam, data, clientsRoomsTag=null)=>{
|
15655
|
-
|
15656
|
-
// DBG
|
15657
|
-
lognow(">>>>>>sendChainable NODE CLIENT ("+channelNameParam+"):data:",data);
|
15658
|
-
|
15659
|
-
// We add a message id :
|
15660
|
-
const messageId=getUUID();
|
15661
|
-
data.messageId=messageId;
|
15662
|
-
|
15663
|
-
// 1) We prepare the reception :
|
15664
|
-
const resultPromise={
|
15665
|
-
clientsRoomsTag:clientsRoomsTag,
|
15666
|
-
messageId:messageId,
|
15667
|
-
thenWhenReceiveMessageType:(channelNameForResponse, listenerConfig={messageType:"",condition:()=>true}, doOnIncomingMessageForResponse)=>{
|
15668
|
-
|
15669
|
-
listenerConfig=nonull(listenerConfig,{messageType:"",condition:()=>true});
|
15670
|
-
const listenerId=nonull(listenerConfig.messageType,"");
|
15671
|
-
|
15672
|
-
//
|
15673
|
-
nodeClientInstance.receive(channelNameForResponse, (dataLocal, clientSocket)=>{
|
15674
|
-
|
15675
|
-
// We check if the message matches the condition :
|
15676
|
-
if(listenerConfig.condition && !listenerConfig.condition(dataLocal, clientSocket)) return ;
|
15677
|
-
|
15678
|
-
// We check if we have the same message id:
|
15679
|
-
if(resultPromise.messageId!==dataLocal.messageId){
|
15680
|
-
// DBG
|
15681
|
-
lognow("resultPromise.messageId:"+resultPromise.messageId+"|dataLocal.messageId"+dataLocal.messageId);
|
15682
|
-
return;
|
15683
|
-
}
|
15684
|
-
|
15685
|
-
doOnIncomingMessageForResponse(dataLocal, clientSocket);
|
15686
|
-
}, resultPromise.clientsRoomsTag, listenerId, {destroyListenerAfterReceiving:true});
|
15687
|
-
//
|
15688
|
-
|
15689
|
-
return resultPromise;
|
15690
|
-
}
|
15691
|
-
};
|
15692
|
-
|
15693
|
-
// 2) We send the data :
|
15694
|
-
nodeClientInstance.send(channelNameParam, data, clientsRoomsTag);
|
15695
|
-
|
15696
|
-
|
15697
|
-
return resultPromise;
|
15698
|
-
},
|
15699
|
-
|
15700
|
-
|
15701
|
-
send:(channelNameParam, data, clientsRoomsTag=null)=>{
|
15702
|
-
|
15703
|
-
// // DBG
|
15704
|
-
// lognow("(CLIENT) (NODEJS) CLIENT TRIES TO SEND !");
|
15705
|
-
|
15706
|
-
|
15707
|
-
const clientSocket=nodeClientInstance.clientSocket;
|
15708
|
-
|
15709
|
-
|
15710
|
-
// // DBG
|
15711
|
-
// console.log("(NODE CLIENT) TRYING TO SEND : clientSocket.readyState:",clientSocket.readyState);
|
15712
|
-
|
15713
|
-
if(!isConnected(clientSocket)) return;
|
15714
|
-
|
15715
|
-
|
15716
|
-
// Room information is stored in client socket object :
|
15717
|
-
if(!WebsocketImplementation.isInRoom(clientSocket,clientsRoomsTag)) return;
|
15718
|
-
|
15719
|
-
// Channel information is stored in exchanged data :
|
15720
|
-
let dataWrapped={channelName:channelNameParam, data:data};
|
15721
|
-
|
15722
|
-
|
15723
|
-
// // DBG
|
15724
|
-
// console.log("(NODE CLIENT) SENDING DATA ! dataWrapped:",dataWrapped);
|
15725
|
-
|
15726
|
-
|
15727
|
-
dataWrapped=stringifyObject(dataWrapped);
|
15728
|
-
|
15729
|
-
|
15730
|
-
// // DBG
|
15731
|
-
// console.log("(NODE CLIENT) SENDING DATA ! channelNameParam:«"+channelNameParam+"» ; clientsRoomsTag:«"+clientsRoomsTag+"»");
|
15732
|
-
// console.log("(NODE CLIENT) SENDING DATA ! dataWrapped:",dataWrapped);
|
15733
|
-
|
15734
|
-
// TODO : FIXME : Use one single interface !
|
15735
|
-
if(!WebsocketImplementation.useSocketIOImplementation) clientSocket.send(dataWrapped);
|
15736
|
-
else clientSocket.emit(channelNameParam,dataWrapped);
|
15737
|
-
|
15738
|
-
return nodeClientInstance;
|
15739
|
-
},
|
15740
|
-
|
15741
|
-
|
15742
|
-
join:(clientRoomTag)=>{
|
15743
|
-
// Join room client part protocol :
|
15744
|
-
const message={type:"joinRoom",clientRoomTag:clientRoomTag};
|
15745
|
-
nodeClientInstance.send("protocol",message);
|
15746
|
-
},
|
15747
|
-
|
15748
|
-
|
15749
|
-
onConnectionToServer:(doOnConnection)=>{
|
15750
|
-
|
15751
|
-
// DBG
|
15752
|
-
lognow("DEBUG : CLIENT : setting up onConnectionToServer.");
|
15753
|
-
|
15754
|
-
const doAllOnConnection=()=>{
|
15755
|
-
|
15756
|
-
// To avoid triggering this event several times, depending on the implementation :
|
15757
|
-
if(nodeClientInstance.hasConnectEventFired) return;
|
15758
|
-
nodeClientInstance.hasConnectEventFired=true;
|
15759
|
-
|
15760
|
-
// DBG
|
15761
|
-
lognow("DEBUG : CLIENT (NODEJS) : doOnConnection !");
|
15762
|
-
|
15763
|
-
const doOnMessage=(eventOrMessage)=>{
|
15764
|
-
|
15765
|
-
// We execute the listeners entry points registration :
|
15766
|
-
foreach(nodeClientInstance.receptionEntryPoints,(receptionEntryPoint)=>{
|
15767
|
-
receptionEntryPoint.execute(eventOrMessage);
|
15768
|
-
});
|
15769
|
-
|
15770
|
-
};
|
15771
|
-
|
15772
|
-
const clientSocket=nodeClientInstance.clientSocket;
|
15773
|
-
if(!WebsocketImplementation.useSocketIOImplementation){ clientSocket.addEventListener("message", doOnMessage);
|
15774
|
-
// NO: else clientSocket.on("message", doOnMessage);
|
15775
|
-
}
|
15776
|
-
|
15777
|
-
doOnConnection(nodeClientInstance, clientSocket);
|
15778
|
-
|
15779
|
-
};
|
15780
|
-
|
15781
|
-
|
15782
|
-
if(!WebsocketImplementation.useSocketIOImplementation) nodeClientInstance.clientSocket.addEventListener("open",doAllOnConnection);
|
15783
|
-
else nodeClientInstance.clientSocket.on("connect",doAllOnConnection);
|
15784
|
-
|
15785
|
-
|
15786
|
-
// DBG
|
15787
|
-
lognow("DEBUG : CLIENT : nodeClientInstance.clientSocket.on(connect)");
|
15788
|
-
|
15789
|
-
|
15790
|
-
// Node client ping handling : (SocketIO implementation only)
|
15791
|
-
if(WebsocketImplementation.useSocketIOImplementation){
|
15792
|
-
nodeClientInstance.receive("protocol",(message)=>{
|
15793
|
-
if(message.type!=="ping") return;
|
15794
|
-
nodeClientInstance.send("protocol",{type:"pong"});
|
15795
|
-
|
15796
|
-
// DBG
|
15797
|
-
lognow("DEBUG : NODE CLIENT : Pong sent.");
|
15798
|
-
});
|
15799
|
-
}
|
15800
|
-
|
15801
|
-
|
15802
|
-
},
|
15803
|
-
|
15804
|
-
|
15805
|
-
};
|
15806
|
-
|
15807
|
-
|
15294
|
+
const nodeClientInstance=new ClientInstance(clientSocket);
|
15808
15295
|
return nodeClientInstance;
|
15809
15296
|
},
|
15810
15297
|
|
15811
|
-
|
15812
|
-
|
15298
|
+
//
|
15813
15299
|
// BROWSER CLIENT
|
15300
|
+
//
|
15814
15301
|
|
15815
15302
|
/*private*/connectToServerFromBrowser:(serverURL, port, isSecure, timeout)=>{
|
15816
15303
|
|
@@ -15824,225 +15311,17 @@ WebsocketImplementation={
|
|
15824
15311
|
// TODO : FIXME : Use one single interface !
|
15825
15312
|
// BROWSER CLIENT MODE ONLY :
|
15826
15313
|
let clientSocket;
|
15827
|
-
if(!WebsocketImplementation.useSocketIOImplementation){
|
15828
|
-
clientSocket=new WebSocket(serverURL+":"+port,["ws","wss"]);
|
15829
|
-
}else if(typeof(io)!=="undefined"){
|
15830
|
-
// OLD SYNTAX :clientSocket=io.connect(serverURL + ":" + port,{timeout: timeout, secure: isSecure});
|
15831
|
-
// ALTERNATIVE :
|
15832
|
-
clientSocket=io(serverURL + ":" + port,{timeout: timeout, secure: isSecure});
|
15833
|
-
}
|
15834
|
-
|
15835
|
-
|
15836
|
-
// BROWSER CLIENT INSTANCE :
|
15837
|
-
const browserInstance={
|
15838
|
-
|
15839
|
-
clientSocket:clientSocket,
|
15840
|
-
receptionEntryPoints:[],
|
15841
|
-
|
15842
|
-
receive:(channelNameParam, doOnIncomingMessage, clientsRoomsTag=null, receptionEntryPointId=null, listenerConfig={destroyListenerAfterReceiving:false})=>{
|
15843
|
-
|
15844
|
-
// DBG
|
15845
|
-
lognow("INFO : (CLIENT-BROWSER) SETTING UP RECEIVE for :",channelNameParam);
|
15846
|
-
|
15847
|
-
|
15848
|
-
const receptionEntryPoint={
|
15849
|
-
channelName:channelNameParam,
|
15850
|
-
clientsRoomsTag:clientsRoomsTag,
|
15851
|
-
// TODO : ADD TO ALL OTHER SUBSYSTEMS !
|
15852
|
-
id:receptionEntryPointId,
|
15853
|
-
listenerConfig:listenerConfig,
|
15854
|
-
doOnIncomingMessage:doOnIncomingMessage,
|
15855
|
-
execute:(eventOrMessage)=>{
|
15856
|
-
|
15857
|
-
const dataWrapped=WebsocketImplementation.getMessageDataBothImplementations(eventOrMessage);
|
15858
|
-
|
15859
|
-
// Channel information is stored in exchanged data :
|
15860
|
-
if(dataWrapped.channelName && dataWrapped.channelName!==this.channelName) return;
|
15861
|
-
|
15862
|
-
// Room information is stored in client socket object :
|
15863
|
-
const clientSocket=browserInstance.clientSocket;
|
15864
|
-
if(!WebsocketImplementation.isInRoom(clientSocket, this.clientsRoomsTag)) return;
|
15865
|
-
|
15866
|
-
// We remove one-time usage listeners :
|
15867
|
-
// We remove BEFORE executing doOnIncomingMessage(), because in this function we can have other listener registration UNDER THE SAME ID !
|
15868
|
-
if(this.listenerConfig && this.listenerConfig.destroyListenerAfterReceiving)
|
15869
|
-
remove(browserInstance.receptionEntryPoints, receptionEntryPoint);
|
15870
|
-
|
15871
|
-
if(this.doOnIncomingMessage)
|
15872
|
-
this.doOnIncomingMessage(dataWrapped.data, clientSocket);
|
15873
|
-
|
15874
|
-
}
|
15875
|
-
};
|
15876
|
-
|
15877
|
-
///!!!
|
15878
|
-
// TODO : ADD TO ALL OTHER SUBSYSTEMS !
|
15879
|
-
if(!contains.filter((l)=>(l.id && receptionEntryPoint.id && l.id===receptionEntryPoint.id))(browserInstance.receptionEntryPoints))
|
15880
|
-
browserInstance.receptionEntryPoints.push(receptionEntryPoint);
|
15881
|
-
|
15882
|
-
// SPECIAL FOR THE SOCKETIO IMPLEMENTATION :
|
15883
|
-
if(WebsocketImplementation.useSocketIOImplementation){
|
15884
|
-
const channelName=receptionEntryPoint.channelName;
|
15885
|
-
clientSocket.on(channelName, (eventOrMessage)=>{
|
15886
|
-
receptionEntryPoint.execute(eventOrMessage, clientSocket);
|
15887
|
-
});
|
15888
|
-
}
|
15889
|
-
|
15890
|
-
|
15891
|
-
return browserInstance;
|
15892
|
-
},
|
15893
|
-
|
15894
|
-
|
15895
|
-
|
15896
|
-
// TODO : FIXME : DUPLICATED CODE !
|
15897
|
-
sendChainable:(channelNameParam, data, clientsRoomsTag=null)=>{
|
15898
|
-
|
15899
|
-
// DBG
|
15900
|
-
lognow(">>>>>>sendChainable BROWSER CLIENT ("+channelNameParam+"):data:",data);
|
15901
|
-
|
15902
|
-
// We add a message id :
|
15903
|
-
const messageId=getUUID();
|
15904
|
-
data.messageId=messageId;
|
15905
|
-
|
15906
|
-
// 1) We prepare the reception :
|
15907
|
-
const resultPromise={
|
15908
|
-
clientsRoomsTag:clientsRoomsTag,
|
15909
|
-
messageId:messageId,
|
15910
|
-
thenWhenReceiveMessageType:(channelNameForResponse, listenerConfig={messageType:"",condition:()=>true}, doOnIncomingMessageForResponse)=>{
|
15911
|
-
listenerConfig=nonull(listenerConfig,{messageType:"",condition:()=>true});
|
15912
|
-
const listenerId=nonull(listenerConfig.messageType,"");
|
15913
|
-
|
15914
|
-
browserInstance.receive(channelNameForResponse, (dataLocal, clientSocket)=>{
|
15915
|
-
|
15916
|
-
// We check if the message matches the condition :
|
15917
|
-
if(listenerConfig.condition && !listenerConfig.condition(dataLocal, clientSocket)) return ;
|
15918
|
-
|
15919
|
-
// We check if we have the same message id:
|
15920
|
-
if(resultPromise.messageId!==dataLocal.messageId){
|
15921
|
-
// DBG
|
15922
|
-
lognow("resultPromise.messageId:"+resultPromise.messageId+"|dataLocal.messageId"+dataLocal.messageId);
|
15923
|
-
return;
|
15924
|
-
}
|
15925
|
-
|
15926
|
-
doOnIncomingMessageForResponse(dataLocal, clientSocket);
|
15927
|
-
}, resultPromise.clientsRoomsTag, listenerId, {destroyListenerAfterReceiving:true});
|
15928
|
-
return resultPromise;
|
15929
|
-
}
|
15930
|
-
};
|
15931
|
-
|
15932
|
-
// 2) We send the data :
|
15933
|
-
browserInstance.send(channelNameParam, data, clientsRoomsTag);
|
15934
|
-
|
15935
|
-
|
15936
|
-
return resultPromise;
|
15937
|
-
},
|
15938
|
-
|
15939
|
-
|
15940
|
-
|
15941
|
-
|
15942
|
-
|
15943
|
-
|
15944
|
-
send:(channelNameParam, data, clientsRoomsTag=null)=>{
|
15945
|
-
|
15946
|
-
// // DBG
|
15947
|
-
// lognow("(CLIENT) (BROWSER) CLIENT TRIES TO SEND !");
|
15948
|
-
|
15949
|
-
const clientSocket=browserInstance.clientSocket;
|
15950
|
-
|
15951
|
-
|
15952
|
-
// // DBG
|
15953
|
-
// console.log("(BROWSER) TRYING TO SEND : clientSocket.readyState:",clientSocket.readyState);
|
15954
|
-
|
15955
|
-
if(!isConnected(clientSocket)) return;
|
15956
|
-
|
15957
|
-
|
15958
|
-
// Room information is stored in client socket object :
|
15959
|
-
if(!WebsocketImplementation.isInRoom(clientSocket,clientsRoomsTag)) return;
|
15960
|
-
|
15961
|
-
// Channel information is stored in exchanged data :
|
15962
|
-
let dataWrapped={channelName:channelNameParam, data:data};
|
15963
|
-
|
15964
|
-
|
15965
|
-
// // DBG
|
15966
|
-
// console.log("(BROWSER) SENDING... : dataWrapped :",dataWrapped);
|
15967
|
-
// console.log("(BROWSER) SENDING... : clientSocket :",clientSocket);
|
15968
|
-
|
15969
|
-
|
15970
|
-
dataWrapped=stringifyObject(dataWrapped);
|
15971
|
-
|
15972
|
-
|
15973
|
-
// TODO : FIXME : Use one single interface !
|
15974
|
-
if(!WebsocketImplementation.useSocketIOImplementation) clientSocket.send(dataWrapped);
|
15975
|
-
else clientSocket.emit(channelNameParam,dataWrapped);
|
15976
|
-
|
15977
|
-
|
15978
|
-
return browserInstance;
|
15979
|
-
},
|
15980
|
-
|
15981
|
-
|
15982
|
-
join:(clientRoomTag)=>{
|
15983
|
-
// Join room client part protocol :
|
15984
|
-
const message={type:"joinRoom",clientRoomTag:clientRoomTag};
|
15985
|
-
browserInstance.send("protocol",message);
|
15986
|
-
},
|
15987
|
-
|
15988
|
-
|
15989
|
-
onConnectionToServer:(doOnConnection)=>{
|
15990
|
-
const doAllOnConnection=()=>{
|
15991
|
-
|
15992
|
-
// To avoid triggering this event several times, depending on the implementation :
|
15993
|
-
if(browserInstance.hasConnectEventFired) return;
|
15994
|
-
browserInstance.hasConnectEventFired=true;
|
15995
|
-
|
15996
|
-
|
15997
|
-
|
15998
|
-
// DBG
|
15999
|
-
lognow("DEBUG : CLIENT (BROWSER) : doOnConnection !");
|
16000
|
-
|
16001
|
-
const doOnMessage=(eventOrMessage)=>{
|
16002
|
-
|
16003
|
-
// We execute the listeners entry points registration :
|
16004
|
-
foreach(browserInstance.receptionEntryPoints,(receptionEntryPoint)=>{
|
16005
|
-
receptionEntryPoint.execute(eventOrMessage);
|
16006
|
-
});
|
16007
|
-
|
16008
|
-
};
|
16009
|
-
|
16010
|
-
const clientSocket=browserInstance.clientSocket;
|
16011
|
-
if(!WebsocketImplementation.useSocketIOImplementation){ clientSocket.addEventListener("message", doOnMessage);
|
16012
|
-
// NO: else clientSocket.on("message", doOnMessage);
|
16013
|
-
}
|
16014
|
-
|
16015
|
-
|
16016
|
-
doOnConnection(browserInstance, clientSocket);
|
16017
|
-
|
16018
|
-
};
|
16019
|
-
|
16020
|
-
if(!WebsocketImplementation.useSocketIOImplementation) browserInstance.clientSocket.addEventListener("open",doAllOnConnection);
|
16021
|
-
else browserInstance.clientSocket.on("connect",doAllOnConnection);
|
16022
|
-
|
16023
|
-
|
16024
|
-
|
16025
|
-
// Browser client ping handling : (SocketIO implementation only)
|
16026
|
-
if(WebsocketImplementation.useSocketIOImplementation){
|
16027
|
-
browserInstance.receive("protocol",(message)=>{
|
16028
|
-
if(message.type!=="ping") return;
|
16029
|
-
browserInstance.send("protocol",{type:"pong"});
|
16030
|
-
|
16031
|
-
// DBG
|
16032
|
-
lognow("DEBUG : BROWSER CLIENT : Pong sent.");
|
16033
|
-
});
|
16034
|
-
}
|
16035
|
-
|
16036
|
-
|
16037
|
-
},
|
16038
|
-
|
16039
|
-
|
16040
|
-
};
|
16041
|
-
|
16042
|
-
|
16043
|
-
|
15314
|
+
if(!WebsocketImplementation.useSocketIOImplementation){
|
15315
|
+
clientSocket=new WebSocket(serverURL+":"+port,["ws","wss"]);
|
15316
|
+
}else if(typeof(io)!=="undefined"){
|
15317
|
+
// OLD SYNTAX :clientSocket=io.connect(serverURL + ":" + port,{timeout: timeout, secure: isSecure});
|
15318
|
+
// ALTERNATIVE :
|
15319
|
+
clientSocket=io(serverURL + ":" + port,{timeout: timeout, secure: isSecure});
|
15320
|
+
}
|
16044
15321
|
|
16045
|
-
|
15322
|
+
// BROWSER CLIENT INSTANCE :
|
15323
|
+
const browserClientInstance=new ClientInstance(clientSocket);
|
15324
|
+
return browserClientInstance;
|
16046
15325
|
},
|
16047
15326
|
|
16048
15327
|
};
|
@@ -17648,9 +16927,495 @@ getAORTACNode=function(nodeId=getUUID(), selfOrigin="ws://127.0.0.1:40000", outc
|
|
17648
16927
|
|
17649
16928
|
|
17650
16929
|
|
16930
|
+
// ==================================================================================================================
|
16931
|
+
|
16932
|
+
class NodeServerInstance{
|
16933
|
+
|
16934
|
+
constructor(serverSocket, listenableServer){
|
16935
|
+
|
16936
|
+
this.onClientLostListeners=[];
|
16937
|
+
|
16938
|
+
this.clientPingIntervalMillis=5000;
|
16939
|
+
this.serverSocket=serverSocket;
|
16940
|
+
this.listenableServer=listenableServer;
|
16941
|
+
this.receptionEntryPoints=[];
|
16942
|
+
|
16943
|
+
}
|
16944
|
+
|
16945
|
+
setPingPongTimeout(clientPingIntervalMillis){
|
16946
|
+
this.clientPingIntervalMillis=clientPingIntervalMillis;
|
16947
|
+
return this;
|
16948
|
+
}
|
16949
|
+
|
16950
|
+
close(doOnCloseServer){
|
16951
|
+
if(!this.serverSocket) return;
|
16952
|
+
this.serverSocket.close(()=>{
|
16953
|
+
if(!this.listenableServer) return;
|
16954
|
+
this.listenableServer.close(doOnCloseServer);
|
16955
|
+
});
|
16956
|
+
}
|
16957
|
+
|
16958
|
+
receive(channelNameParam, doOnIncomingMessage, clientsRoomsTag=null){
|
16959
|
+
const self=this;
|
16960
|
+
|
16961
|
+
// DBG
|
16962
|
+
lognow("(SERVER) Registering receive for «"+channelNameParam+"»...");
|
16963
|
+
|
16964
|
+
|
16965
|
+
const receptionEntryPoint={
|
16966
|
+
channelName:channelNameParam,
|
16967
|
+
clientsRoomsTag:clientsRoomsTag,
|
16968
|
+
execute:(eventOrMessage, clientSocketParam)=>{
|
16969
|
+
|
16970
|
+
// With «ws» library we have no choive than register message events inside a «connection» event !
|
16971
|
+
|
16972
|
+
const dataWrapped=WebsocketImplementation.getMessageDataBothImplementations(eventOrMessage);
|
16973
|
+
|
16974
|
+
// Channel information is stored in exchanged data :
|
16975
|
+
if(dataWrapped.channelName!==receptionEntryPoint.channelName) return;
|
16976
|
+
|
16977
|
+
|
16978
|
+
// TODO : FIXME : Use one single interface !
|
16979
|
+
// Room information is stored in client socket object :
|
16980
|
+
const isClientInRoom=WebsocketImplementation.isInRoom(clientSocketParam, receptionEntryPoint.clientsRoomsTag);
|
16981
|
+
|
16982
|
+
// DBG
|
16983
|
+
lognow("(SERVER) isClientInRoom:",isClientInRoom);
|
16984
|
+
|
16985
|
+
if(!isClientInRoom) return;
|
16986
|
+
|
16987
|
+
if(doOnIncomingMessage){
|
16988
|
+
// DBG
|
16989
|
+
lognow("(SERVER) doOnIncomingMessage:");
|
16990
|
+
doOnIncomingMessage(dataWrapped.data, clientSocketParam);
|
16991
|
+
}
|
16992
|
+
|
16993
|
+
},
|
16994
|
+
};
|
16995
|
+
|
16996
|
+
|
16997
|
+
///!!!
|
16998
|
+
self.receptionEntryPoints.push(receptionEntryPoint);
|
16999
|
+
|
17000
|
+
// SPECIAL FOR THE SOCKETIO IMPLEMENTATION :
|
17001
|
+
if(WebsocketImplementation.useSocketIOImplementation){
|
17002
|
+
const channelName=receptionEntryPoint.channelName;
|
17003
|
+
clientSocket.on(channelName, (eventOrMessage)=>{
|
17004
|
+
receptionEntryPoint.execute(eventOrMessage, clientSocket);
|
17005
|
+
});
|
17006
|
+
}
|
17007
|
+
|
17008
|
+
return this;
|
17009
|
+
}
|
17010
|
+
|
17011
|
+
|
17012
|
+
send(channelName, data, clientsRoomsTag=null, clientSocketParam=null){
|
17013
|
+
|
17014
|
+
// DBG
|
17015
|
+
lognow("(SERVER) SERVER TRIES TO SEND !");
|
17016
|
+
|
17017
|
+
|
17018
|
+
if(!clientSocketParam){
|
17019
|
+
|
17020
|
+
// DBG
|
17021
|
+
lognow("(SERVER) (server sends to all clients)");
|
17022
|
+
|
17023
|
+
// TODO : FIXME : Use one single interface !
|
17024
|
+
let serverClients;
|
17025
|
+
if(!WebsocketImplementation.useSocketIOImplementation) serverClients=this.serverSocket.clients;
|
17026
|
+
else serverClients=this.serverSocket.sockets.sockets;
|
17027
|
+
|
17028
|
+
|
17029
|
+
serverClients.forEach((clientSocket)=>{
|
17030
|
+
|
17031
|
+
|
17032
|
+
if(!isConnected(clientSocket)) return;
|
17033
|
+
|
17034
|
+
|
17035
|
+
// Room information is stored in client socket object :
|
17036
|
+
if(!WebsocketImplementation.isInRoom(clientSocket,clientsRoomsTag)) return;
|
17037
|
+
|
17038
|
+
// Channel information is stored in exchanged data :
|
17039
|
+
let dataWrapped={channelName:channelName, data:data};
|
17040
|
+
|
17041
|
+
|
17042
|
+
dataWrapped=stringifyObject(dataWrapped);
|
17043
|
+
|
17044
|
+
// TODO : FIXME : Use one single interface !
|
17045
|
+
if(!WebsocketImplementation.useSocketIOImplementation) clientSocket.send(dataWrapped);
|
17046
|
+
else clientSocket.emit(channelName,dataWrapped);
|
17047
|
+
|
17048
|
+
});
|
17049
|
+
|
17050
|
+
}else{
|
17051
|
+
|
17052
|
+
// DBG
|
17053
|
+
lognow("(SERVER) (server sends to a client)");
|
17054
|
+
|
17055
|
+
|
17056
|
+
// TODO : FIXME : Use one single interface !
|
17057
|
+
let clientSocket=clientSocketParam;
|
17058
|
+
if(!WebsocketImplementation.useSocketIOImplementation) if(clientSocket.readyState!==WebSocket.OPEN) return;
|
17059
|
+
else if(clientSocket.connected) return;
|
17060
|
+
|
17061
|
+
|
17062
|
+
// Room information is stored in client socket object :
|
17063
|
+
if(!WebsocketImplementation.isInRoom(clientSocket,clientsRoomsTag)) return;
|
17064
|
+
|
17065
|
+
// Channel information is stored in exchanged data :
|
17066
|
+
let dataWrapped={channelName:channelName, data:data};
|
17067
|
+
dataWrapped=stringifyObject(dataWrapped);
|
17068
|
+
|
17069
|
+
|
17070
|
+
// DBG
|
17071
|
+
lognow("(SERVER) WebsocketImplementation.useSocketIOImplementation:"+WebsocketImplementation.useSocketIOImplementation);
|
17072
|
+
|
17073
|
+
|
17074
|
+
// TODO : FIXME : Use one single interface !
|
17075
|
+
if(!WebsocketImplementation.useSocketIOImplementation) clientSocket.send(dataWrapped);
|
17076
|
+
else clientSocket.emit(channelName,dataWrapped);
|
17077
|
+
|
17078
|
+
}
|
17079
|
+
|
17080
|
+
|
17081
|
+
return this;
|
17082
|
+
}
|
17083
|
+
|
17084
|
+
|
17085
|
+
onConnectionToClient(doOnConnection){
|
17086
|
+
const self=this;
|
17087
|
+
|
17088
|
+
|
17089
|
+
// «connection» is the only event fired by the serverSocket :
|
17090
|
+
this.serverSocket.on("connection", (clientSocket)=>{
|
17091
|
+
|
17092
|
+
// DBG
|
17093
|
+
console.log("SERVER : ON CONNECTION !");
|
17094
|
+
|
17095
|
+
|
17096
|
+
const clientId="autogeneratedid_"+getUUID();
|
17097
|
+
|
17098
|
+
clientSocket.clientId=clientId;
|
17099
|
+
|
17100
|
+
|
17101
|
+
const doOnMessage=(eventOrMessage)=>{
|
17102
|
+
// We execute the events registration listeners entry points:
|
17103
|
+
foreach(self.receptionEntryPoints,(receptionEntryPoint,i)=>{
|
17104
|
+
receptionEntryPoint.execute(eventOrMessage, clientSocket);
|
17105
|
+
});
|
17106
|
+
};
|
17107
|
+
|
17108
|
+
if(!WebsocketImplementation.useSocketIOImplementation)
|
17109
|
+
clientSocket.addEventListener("message", doOnMessage);
|
17110
|
+
|
17111
|
+
doOnConnection(this, clientSocket);
|
17112
|
+
|
17113
|
+
|
17114
|
+
// DBG
|
17115
|
+
lognow("DEBUG : Starting ping-pong with client : clientSocket.clientId:",clientSocket.clientId);
|
17116
|
+
lognow("DEBUG : WebsocketImplementation.useSocketIOImplementation:",WebsocketImplementation.useSocketIOImplementation);
|
17117
|
+
lognow("DEBUG : clientSocket.readyState:",clientSocket.readyState);
|
17118
|
+
|
17119
|
+
|
17120
|
+
// To make the server aware of the clients connections states :
|
17121
|
+
clientSocket.isConnectionAlive=true;
|
17122
|
+
clientSocket.stateCheckInterval=setInterval(()=>{
|
17123
|
+
|
17124
|
+
if (clientSocket.isConnectionAlive===false){
|
17125
|
+
|
17126
|
+
// On today, this method is named as same for the two implementations :
|
17127
|
+
// TRACE
|
17128
|
+
lognow("(SERVER) Removing all listeners for client socket «"+clientSocket.clientId+"».");
|
17129
|
+
|
17130
|
+
clientSocket.removeAllListeners();
|
17131
|
+
|
17132
|
+
// TODO : FIXME : Use one single interface !
|
17133
|
+
if(!WebsocketImplementation.useSocketIOImplementation) clientSocket.terminate();
|
17134
|
+
else clientSocket.emit("endConnection");
|
17135
|
+
|
17136
|
+
if(!empty(self.onClientLostListeners))
|
17137
|
+
foreach(self.onClientLostListeners,l=>{l.execute(clientSocket);});
|
17138
|
+
|
17139
|
+
// DBG
|
17140
|
+
lognow("DEBUG : (SERVER) Connection closed for failed ping-pong.");
|
17141
|
+
|
17142
|
+
|
17143
|
+
clearInterval(clientSocket.stateCheckInterval);
|
17144
|
+
return;
|
17145
|
+
}
|
17146
|
+
|
17147
|
+
clientSocket.isConnectionAlive=false;
|
17148
|
+
|
17149
|
+
if(!WebsocketImplementation.useSocketIOImplementation) clientSocket.ping();
|
17150
|
+
else self.send("protocol",{type:"ping"}, null, clientSocket);
|
17151
|
+
|
17152
|
+
|
17153
|
+
}, this.clientPingIntervalMillis);
|
17154
|
+
|
17155
|
+
|
17156
|
+
if(!WebsocketImplementation.useSocketIOImplementation){
|
17157
|
+
clientSocket.on("pong",()=>{
|
17158
|
+
clientSocket.isConnectionAlive=true;
|
17159
|
+
});
|
17160
|
+
}else{
|
17161
|
+
|
17162
|
+
this.receive("protocol",(message)=>{
|
17163
|
+
if(message.type!=="pong") return;
|
17164
|
+
clientSocket.isConnectionAlive=true;
|
17165
|
+
});
|
17166
|
+
|
17167
|
+
}
|
17168
|
+
|
17169
|
+
});
|
17170
|
+
|
17171
|
+
|
17172
|
+
return this;
|
17173
|
+
}
|
17174
|
+
|
17175
|
+
onFinalize(doOnFinalizeServer){
|
17176
|
+
|
17177
|
+
doOnFinalizeServer(this);
|
17178
|
+
|
17179
|
+
// TRACE
|
17180
|
+
console.log("INFO : SERVER : Node server setup complete.");
|
17181
|
+
|
17182
|
+
return this;
|
17183
|
+
}
|
17184
|
+
|
17185
|
+
addToRoom(clientSocket, clientRoomTag){
|
17186
|
+
clientSocket.clientRoomTag=clientRoomTag;
|
17187
|
+
}
|
17188
|
+
|
17189
|
+
}
|
17190
|
+
|
17191
|
+
|
17192
|
+
|
17193
|
+
|
17194
|
+
|
17195
|
+
|
17196
|
+
|
17197
|
+
|
17198
|
+
/* ## Utility network global methods in a javascript, console (nodejs), or vanilla javascript with no browser environment.
|
17199
|
+
*
|
17200
|
+
* This set of methods gathers utility generic-purpose methods usable in any JS project.
|
17201
|
+
* Several authors of snippets published freely on the Internet contributed to this library.
|
17202
|
+
* Feel free to use/modify-enhance/publish them under the terms of its license.
|
17203
|
+
*
|
17204
|
+
* # Library name : «aotrautils»
|
17205
|
+
* # Library license : HGPL(Help Burma) (see aotra README information for details : https://alqemia.com/aotra.js )
|
17206
|
+
* # Author name : Jérémie Ratomposon (massively helped by his native country free education system)
|
17207
|
+
* # Author email : info@alqemia.com
|
17208
|
+
* # Organization name : Alqemia
|
17209
|
+
* # Organization email : admin@alqemia.com
|
17210
|
+
* # Organization website : https://alqemia.com
|
17211
|
+
*
|
17212
|
+
*
|
17213
|
+
*/
|
17214
|
+
|
17215
|
+
|
17216
|
+
|
17217
|
+
// COMPATIBILITY browser javascript / nodejs environment :
|
17218
|
+
if(typeof(window)==="undefined") window=global;
|
17219
|
+
|
17220
|
+
|
17221
|
+
|
17222
|
+
// ==================================================================================================================
|
17223
|
+
|
17224
|
+
//
|
17225
|
+
// CLIENT INSTANCE :
|
17226
|
+
//
|
17227
|
+
class ClientInstance{
|
17228
|
+
|
17229
|
+
constructor(clientSocket){
|
17230
|
+
this.clientSocket=clientSocket;
|
17231
|
+
this.receptionEntryPoints=[];
|
17232
|
+
|
17233
|
+
}
|
17234
|
+
|
17235
|
+
receive(channelNameParam, doOnIncomingMessage, clientsRoomsTag=null, receptionEntryPointId=null, listenerConfig={destroyListenerAfterReceiving:false}){
|
17236
|
+
const self=this;
|
17237
|
+
|
17238
|
+
// DBG
|
17239
|
+
lognow("INFO : (CLIENT-BROWSER) SETTING UP RECEIVE for :",channelNameParam);
|
17240
|
+
|
17241
|
+
const receptionEntryPoint={
|
17242
|
+
channelName:channelNameParam,
|
17243
|
+
clientsRoomsTag:clientsRoomsTag,
|
17244
|
+
// TODO : ADD TO ALL OTHER SUBSYSTEMS !
|
17245
|
+
id:receptionEntryPointId,
|
17246
|
+
listenerConfig:listenerConfig,
|
17247
|
+
doOnIncomingMessage:doOnIncomingMessage,
|
17248
|
+
execute:(eventOrMessage)=>{
|
17249
|
+
|
17250
|
+
const dataWrapped=WebsocketImplementation.getMessageDataBothImplementations(eventOrMessage);
|
17251
|
+
|
17252
|
+
// Channel information is stored in exchanged data :
|
17253
|
+
if(dataWrapped.channelName && dataWrapped.channelName!==receptionEntryPoint.channelName) return;
|
17254
|
+
|
17255
|
+
// Room information is stored in client socket object :
|
17256
|
+
const clientSocket=self.clientSocket;
|
17257
|
+
if(!WebsocketImplementation.isInRoom(clientSocket, receptionEntryPoint.clientsRoomsTag)) return;
|
17258
|
+
|
17259
|
+
// We remove one-time usage listeners :
|
17260
|
+
// We remove BEFORE executing doOnIncomingMessage(), because in receptionEntryPoint function we can have other listener registration UNDER THE SAME ID !
|
17261
|
+
if(receptionEntryPoint.listenerConfig && receptionEntryPoint.listenerConfig.destroyListenerAfterReceiving)
|
17262
|
+
remove(self.receptionEntryPoints, receptionEntryPoint);
|
17263
|
+
|
17264
|
+
if(receptionEntryPoint.doOnIncomingMessage)
|
17265
|
+
receptionEntryPoint.doOnIncomingMessage(dataWrapped.data, clientSocket);
|
17266
|
+
|
17267
|
+
}
|
17268
|
+
};
|
17269
|
+
|
17270
|
+
///!!!
|
17271
|
+
// TODO : ADD TO ALL OTHER SUBSYSTEMS !
|
17272
|
+
if(!contains.filter((l)=>(l.id && receptionEntryPoint.id && l.id===receptionEntryPoint.id))(this.receptionEntryPoints))
|
17273
|
+
this.receptionEntryPoints.push(receptionEntryPoint);
|
17274
|
+
|
17275
|
+
// SPECIAL FOR THE SOCKETIO IMPLEMENTATION :
|
17276
|
+
if(WebsocketImplementation.useSocketIOImplementation){
|
17277
|
+
const channelName=receptionEntryPoint.channelName;
|
17278
|
+
clientSocket.on(channelName, (eventOrMessage)=>{
|
17279
|
+
receptionEntryPoint.execute(eventOrMessage, clientSocket);
|
17280
|
+
});
|
17281
|
+
}
|
17282
|
+
|
17283
|
+
|
17284
|
+
return this;
|
17285
|
+
}
|
17286
|
+
|
17287
|
+
|
17288
|
+
// TODO : FIXME : DUPLICATED CODE !
|
17289
|
+
sendChainable(channelNameParam, data, clientsRoomsTag=null){
|
17290
|
+
const self=this;
|
17291
|
+
|
17292
|
+
// DBG
|
17293
|
+
lognow(">>>>>>sendChainable CLIENT ("+channelNameParam+"):data:",data);
|
17294
|
+
|
17295
|
+
// We add a message id :
|
17296
|
+
const messageId=getUUID();
|
17297
|
+
data.messageId=messageId;
|
17298
|
+
|
17299
|
+
// 1) We prepare the reception :
|
17300
|
+
const resultPromise={
|
17301
|
+
clientsRoomsTag:clientsRoomsTag,
|
17302
|
+
messageId:messageId,
|
17303
|
+
thenWhenReceiveMessageType:(channelNameForResponse, listenerConfig={messageType:"",condition:()=>true}, doOnIncomingMessageForResponse)=>{
|
17304
|
+
listenerConfig=nonull(listenerConfig,{messageType:"",condition:()=>true});
|
17305
|
+
const listenerId=nonull(listenerConfig.messageType,"");
|
17306
|
+
|
17307
|
+
//
|
17308
|
+
self.receive(channelNameForResponse, (dataLocal, clientSocket)=>{
|
17309
|
+
|
17310
|
+
// We check if the message matches the condition :
|
17311
|
+
if(listenerConfig.condition && !listenerConfig.condition(dataLocal, clientSocket)) return ;
|
17312
|
+
|
17313
|
+
// We check if we have the same message id:
|
17314
|
+
if(resultPromise.messageId!==dataLocal.messageId){
|
17315
|
+
// DBG
|
17316
|
+
lognow("resultPromise.messageId:"+resultPromise.messageId+"|dataLocal.messageId"+dataLocal.messageId);
|
17317
|
+
return;
|
17318
|
+
}
|
17319
|
+
|
17320
|
+
doOnIncomingMessageForResponse(dataLocal, clientSocket);
|
17321
|
+
}, resultPromise.clientsRoomsTag, listenerId, {destroyListenerAfterReceiving:true});
|
17322
|
+
//
|
17323
|
+
|
17324
|
+
return resultPromise;
|
17325
|
+
}
|
17326
|
+
};
|
17327
|
+
|
17328
|
+
// 2) We send the data :
|
17329
|
+
this.send(channelNameParam, data, clientsRoomsTag);
|
17330
|
+
|
17331
|
+
|
17332
|
+
return resultPromise;
|
17333
|
+
}
|
17334
|
+
|
17335
|
+
|
17336
|
+
send(channelNameParam, data, clientsRoomsTag=null){
|
17337
|
+
|
17338
|
+
// // DBG
|
17339
|
+
// lognow("(CLIENT) CLIENT TRIES TO SEND !");
|
17340
|
+
|
17341
|
+
const clientSocket=this.clientSocket;
|
17342
|
+
|
17343
|
+
if(!isConnected(clientSocket)) return;
|
17344
|
+
|
17345
|
+
// Room information is stored in client socket object :
|
17346
|
+
if(!WebsocketImplementation.isInRoom(clientSocket,clientsRoomsTag)) return;
|
17347
|
+
|
17348
|
+
// Channel information is stored in exchanged data :
|
17349
|
+
let dataWrapped={channelName:channelNameParam, data:data};
|
17350
|
+
|
17351
|
+
dataWrapped=stringifyObject(dataWrapped);
|
17352
|
+
|
17353
|
+
// TODO : FIXME : Use one single interface !
|
17354
|
+
if(!WebsocketImplementation.useSocketIOImplementation) clientSocket.send(dataWrapped);
|
17355
|
+
else clientSocket.emit(channelNameParam,dataWrapped);
|
17356
|
+
|
17357
|
+
return this;
|
17358
|
+
}
|
17359
|
+
|
17360
|
+
|
17361
|
+
join(clientRoomTag){
|
17362
|
+
// Join room client part protocol :
|
17363
|
+
const message={type:"joinRoom",clientRoomTag:clientRoomTag};
|
17364
|
+
this.send("protocol",message);
|
17365
|
+
}
|
17366
|
+
|
17367
|
+
|
17368
|
+
onConnectionToServer(doOnConnection){
|
17369
|
+
const self=this;
|
17370
|
+
|
17371
|
+
// DBG
|
17372
|
+
lognow("DEBUG : CLIENT : setting up onConnectionToServer.");
|
17373
|
+
|
17374
|
+
const doAllOnConnection=()=>{
|
17651
17375
|
|
17376
|
+
// To avoid triggering this event several times, depending on the implementation :
|
17377
|
+
if(self.hasConnectEventFired) return;
|
17378
|
+
self.hasConnectEventFired=true;
|
17379
|
+
|
17380
|
+
// DBG
|
17381
|
+
lognow("DEBUG : CLIENT : doOnConnection !");
|
17382
|
+
|
17383
|
+
const doOnMessage=(eventOrMessage)=>{
|
17384
|
+
|
17385
|
+
// We execute the listeners entry points registration :
|
17386
|
+
foreach(self.receptionEntryPoints,(receptionEntryPoint)=>{
|
17387
|
+
receptionEntryPoint.execute(eventOrMessage);
|
17388
|
+
});
|
17652
17389
|
|
17390
|
+
};
|
17391
|
+
|
17392
|
+
const clientSocket=self.clientSocket;
|
17393
|
+
if(!WebsocketImplementation.useSocketIOImplementation){ clientSocket.addEventListener("message", doOnMessage);
|
17394
|
+
}
|
17653
17395
|
|
17396
|
+
doOnConnection(self, clientSocket);
|
17397
|
+
|
17398
|
+
};
|
17399
|
+
|
17400
|
+
if(!WebsocketImplementation.useSocketIOImplementation) this.clientSocket.addEventListener("open",doAllOnConnection);
|
17401
|
+
else this.clientSocket.on("connect",doAllOnConnection);
|
17402
|
+
|
17403
|
+
|
17404
|
+
// Client ping handling : (SocketIO implementation only)
|
17405
|
+
if(WebsocketImplementation.useSocketIOImplementation){
|
17406
|
+
this.receive("protocol",(message)=>{
|
17407
|
+
if(message.type!=="ping") return;
|
17408
|
+
self.send("protocol",{type:"pong"});
|
17409
|
+
|
17410
|
+
// DBG
|
17411
|
+
lognow("DEBUG : CLIENT : Pong sent.");
|
17412
|
+
});
|
17413
|
+
}
|
17414
|
+
|
17415
|
+
|
17416
|
+
}
|
17417
|
+
|
17418
|
+
}
|
17654
17419
|
|
17655
17420
|
|
17656
17421
|
/* INCLUDED EXTERNAL LIBRAIRIES
|
aotrautils/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "aotrautils",
|
3
|
-
"version": "0.0.
|
3
|
+
"version": "0.0.1477",
|
4
4
|
"main": "aotrautils.build.js",
|
5
5
|
"description": "A library for vanilla javascript utils (client-side) used in aotra javascript CMS",
|
6
6
|
"author": "Jeremie Ratomposon <info@alqemia.com> (https://alqemia.com)",
|