aotrautils-srv 0.0.1476 → 0.0.1478
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-srv/aotrautils-srv.build.js +506 -743
- aotrautils-srv/package.json +1 -1
@@ -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:16:46)»*/
|
4
4
|
/*-----------------------------------------------------------------------------*/
|
5
5
|
|
6
6
|
|
@@ -4894,7 +4894,7 @@ AOTRAUTILS_LIB_IS_LOADED=true;
|
|
4894
4894
|
|
4895
4895
|
|
4896
4896
|
|
4897
|
-
/*utils AI library associated with aotra version : «1_29072022-2359 (26/04/2025-
|
4897
|
+
/*utils AI library associated with aotra version : «1_29072022-2359 (26/04/2025-16:16:46)»*/
|
4898
4898
|
/*-----------------------------------------------------------------------------*/
|
4899
4899
|
|
4900
4900
|
|
@@ -5040,11 +5040,11 @@ getOpenAIAPIClient=(modelName, apiURL, agentRole, defaultPrompt)=>{
|
|
5040
5040
|
|
5041
5041
|
|
5042
5042
|
|
5043
|
-
/*utils
|
5043
|
+
/*utils CONSOLE library associated with aotra version : «1_29072022-2359 (26/04/2025-16:16:46)»*/
|
5044
5044
|
/*-----------------------------------------------------------------------------*/
|
5045
5045
|
|
5046
5046
|
|
5047
|
-
/* ## Utility global methods in a javascript, console (nodejs)
|
5047
|
+
/* ## Utility global methods in a javascript, console (nodejs) or vanilla javascript with no browser environment.
|
5048
5048
|
*
|
5049
5049
|
* This set of methods gathers utility generic-purpose methods usable in any JS project.
|
5050
5050
|
* Several authors of snippets published freely on the Internet contributed to this library.
|
@@ -5378,7 +5378,6 @@ WebsocketImplementation={
|
|
5378
5378
|
throw new Error("ERROR : SERVER : Server launch is not supported in a non-nodejs context for any implementation.");
|
5379
5379
|
}
|
5380
5380
|
|
5381
|
-
|
5382
5381
|
|
5383
5382
|
// TODO : FIXME : Use one single interface !
|
5384
5383
|
// NODE SERVER MODE ONLY :
|
@@ -5404,322 +5403,20 @@ WebsocketImplementation={
|
|
5404
5403
|
}
|
5405
5404
|
|
5406
5405
|
serverSocket.on("error",(error)=>{
|
5407
|
-
|
5408
5406
|
// TRACE
|
5409
5407
|
lognow("ERROR : An error occurred when trying to start the server : ",error);
|
5410
5408
|
|
5411
5409
|
});
|
5412
5410
|
|
5413
5411
|
// NODE SERVER INSTANCE :
|
5414
|
-
const nodeServerInstance=
|
5415
|
-
|
5416
|
-
onClientLostListeners:[],
|
5417
|
-
|
5418
|
-
clientPingIntervalMillis:5000,
|
5419
|
-
setPingPongTimeout:(clientPingIntervalMillis)=>{
|
5420
|
-
nodeServerInstance.clientPingIntervalMillis=clientPingIntervalMillis;
|
5421
|
-
return nodeServerInstance;
|
5422
|
-
},
|
5423
|
-
|
5424
|
-
// clientsSockets:[],
|
5425
|
-
serverSocket:serverSocket,
|
5426
|
-
listenableServer:listenableServer,
|
5427
|
-
|
5428
|
-
receptionEntryPoints:[],
|
5429
|
-
|
5430
|
-
close:(doOnCloseServer)=>{
|
5431
|
-
if(!nodeServerInstance.serverSocket) return;
|
5432
|
-
nodeServerInstance.serverSocket.close(()=>{
|
5433
|
-
if(!nodeServerInstance.listenableServer) return;
|
5434
|
-
nodeServerInstance.listenableServer.close(doOnCloseServer);
|
5435
|
-
});
|
5436
|
-
},
|
5437
|
-
|
5438
|
-
receive:(channelNameParam, doOnIncomingMessage, clientsRoomsTag=null)=>{
|
5439
|
-
|
5440
|
-
// DBG
|
5441
|
-
lognow("(SERVER) Registering receive for «"+channelNameParam+"»...");
|
5442
|
-
|
5443
|
-
|
5444
|
-
|
5445
|
-
const receptionEntryPoint={
|
5446
|
-
channelName:channelNameParam,
|
5447
|
-
clientsRoomsTag:clientsRoomsTag,
|
5448
|
-
execute:(eventOrMessage, clientSocketParam)=>{
|
5449
|
-
|
5450
|
-
// With «ws» library we have no choive than register message events inside a «connection» event !
|
5451
|
-
|
5452
|
-
// // DBG
|
5453
|
-
// lognow("(SERVER) RECEIVED SOMETHING FROM CLIENT...", eventOrMessage.data);
|
5454
|
-
|
5455
|
-
// dataWrapped=parseJSON(dataWrapped);
|
5456
|
-
// dataWrapped=getAt(dataWrapped,0);// We get the root element
|
5457
|
-
|
5458
|
-
|
5459
|
-
const dataWrapped=WebsocketImplementation.getMessageDataBothImplementations(eventOrMessage);
|
5460
|
-
|
5461
|
-
|
5462
|
-
// Channel information is stored in exchanged data :
|
5463
|
-
if(dataWrapped.channelName!==receptionEntryPoint.channelName) return;
|
5464
|
-
|
5465
|
-
|
5466
|
-
// // DBG
|
5467
|
-
// lognow("(SERVER) ENTRY POINT IS OF THE RIGHT CHANNEL:", receptionEntryPoint.channelName);
|
5468
|
-
|
5469
|
-
|
5470
|
-
// TODO : FIXME : Use one single interface !
|
5471
|
-
// Room information is stored in client socket object :
|
5472
|
-
const isClientInRoom=WebsocketImplementation.isInRoom(clientSocketParam, receptionEntryPoint.clientsRoomsTag);
|
5473
|
-
|
5474
|
-
// DBG
|
5475
|
-
lognow("(SERVER) isClientInRoom:",isClientInRoom);
|
5476
|
-
|
5477
|
-
if(!isClientInRoom) return;
|
5478
|
-
|
5479
|
-
if(doOnIncomingMessage){
|
5480
|
-
// DBG
|
5481
|
-
lognow("(SERVER) doOnIncomingMessage:");
|
5482
|
-
doOnIncomingMessage(dataWrapped.data, clientSocketParam);
|
5483
|
-
}
|
5484
|
-
|
5485
|
-
},
|
5486
|
-
};
|
5487
|
-
|
5488
|
-
|
5489
|
-
///!!!
|
5490
|
-
nodeServerInstance.receptionEntryPoints.push(receptionEntryPoint);
|
5491
|
-
|
5492
|
-
// SPECIAL FOR THE SOCKETIO IMPLEMENTATION :
|
5493
|
-
if(WebsocketImplementation.useSocketIOImplementation){
|
5494
|
-
const channelName=receptionEntryPoint.channelName;
|
5495
|
-
clientSocket.on(channelName, (eventOrMessage)=>{
|
5496
|
-
receptionEntryPoint.execute(eventOrMessage, clientSocket);
|
5497
|
-
});
|
5498
|
-
}
|
5499
|
-
|
5500
|
-
|
5501
|
-
// // DBG
|
5502
|
-
// console.log("ADD RECEPTION ENTRY POINT channelName:«"+channelName+"»! nodeServerInstance.receptionEntryPoints.length:",nodeServerInstance.receptionEntryPoints.length);
|
5503
|
-
|
5504
|
-
|
5505
|
-
return nodeServerInstance;
|
5506
|
-
},
|
5507
|
-
|
5508
|
-
|
5509
|
-
send:(channelName, data, clientsRoomsTag=null, clientSocketParam=null)=>{
|
5510
|
-
|
5511
|
-
// DBG
|
5512
|
-
lognow("(SERVER) SERVER TRIES TO SEND !");
|
5513
|
-
|
5514
|
-
|
5515
|
-
if(!clientSocketParam){
|
5516
|
-
|
5517
|
-
// DBG
|
5518
|
-
lognow("(SERVER) (server sends to all clients)");
|
5519
|
-
|
5520
|
-
// TODO : FIXME : Use one single interface !
|
5521
|
-
let serverClients;
|
5522
|
-
if(!WebsocketImplementation.useSocketIOImplementation) serverClients=nodeServerInstance.serverSocket.clients;
|
5523
|
-
// OLD: else serverClients=nodeServerInstance.serverSocket.sockets.clients();
|
5524
|
-
else serverClients=nodeServerInstance.serverSocket.sockets.sockets;
|
5525
|
-
|
5526
|
-
|
5527
|
-
|
5528
|
-
serverClients.forEach((clientSocket)=>{
|
5529
|
-
|
5530
|
-
|
5531
|
-
if(!isConnected(clientSocket)) return;
|
5532
|
-
|
5533
|
-
|
5534
|
-
// Room information is stored in client socket object :
|
5535
|
-
if(!WebsocketImplementation.isInRoom(clientSocket,clientsRoomsTag)) return;
|
5536
|
-
|
5537
|
-
// Channel information is stored in exchanged data :
|
5538
|
-
let dataWrapped={channelName:channelName, data:data};
|
5539
|
-
|
5540
|
-
|
5541
|
-
dataWrapped=stringifyObject(dataWrapped);
|
5542
|
-
|
5543
|
-
// TODO : FIXME : Use one single interface !
|
5544
|
-
if(!WebsocketImplementation.useSocketIOImplementation) clientSocket.send(dataWrapped);
|
5545
|
-
else clientSocket.emit(channelName,dataWrapped);
|
5546
|
-
|
5547
|
-
});
|
5548
|
-
|
5549
|
-
}else{
|
5550
|
-
|
5551
|
-
// DBG
|
5552
|
-
lognow("(SERVER) (server sends to a client)");
|
5553
|
-
|
5554
|
-
|
5555
|
-
// TODO : FIXME : Use one single interface !
|
5556
|
-
let clientSocket=clientSocketParam;
|
5557
|
-
if(!WebsocketImplementation.useSocketIOImplementation) if(clientSocket.readyState!==WebSocket.OPEN) return;
|
5558
|
-
else if(clientSocket.connected) return;
|
5559
|
-
|
5560
|
-
|
5561
|
-
// Room information is stored in client socket object :
|
5562
|
-
if(!WebsocketImplementation.isInRoom(clientSocket,clientsRoomsTag)) return;
|
5563
|
-
|
5564
|
-
// Channel information is stored in exchanged data :
|
5565
|
-
let dataWrapped={channelName:channelName, data:data};
|
5566
|
-
dataWrapped=stringifyObject(dataWrapped);
|
5567
|
-
|
5568
|
-
|
5569
|
-
// DBG
|
5570
|
-
lognow("(SERVER) WebsocketImplementation.useSocketIOImplementation:"+WebsocketImplementation.useSocketIOImplementation);
|
5571
|
-
// lognow("(SERVER) dataWrapped:"+dataWrapped);
|
5572
|
-
|
5573
|
-
|
5574
|
-
// TODO : FIXME : Use one single interface !
|
5575
|
-
if(!WebsocketImplementation.useSocketIOImplementation) clientSocket.send(dataWrapped);
|
5576
|
-
else clientSocket.emit(channelName,dataWrapped);
|
5577
|
-
|
5578
|
-
|
5579
|
-
}
|
5580
|
-
|
5581
|
-
|
5582
|
-
return nodeServerInstance;
|
5583
|
-
},
|
5584
|
-
|
5585
|
-
|
5586
|
-
onConnectionToClient:(doOnConnection)=>{
|
5587
|
-
|
5588
|
-
// «connection» is the only event fired by the serverSocket :
|
5589
|
-
nodeServerInstance.serverSocket.on("connection", (clientSocket)=>{
|
5590
|
-
|
5591
|
-
// DBG
|
5592
|
-
console.log("SERVER : ON CONNECTION !");
|
5593
|
-
|
5594
|
-
|
5595
|
-
// if(contains(nodeServerInstance.clientsSockets, clientSocket)) return;
|
5596
|
-
// nodeServerInstance.clientsSockets.push(clientSocket);
|
5597
|
-
|
5598
|
-
|
5599
|
-
const clientId="autogeneratedid_"+getUUID();
|
5600
|
-
|
5601
|
-
|
5602
|
-
clientSocket.clientId=clientId;
|
5603
|
-
|
5604
|
-
|
5605
|
-
|
5606
|
-
const doOnMessage=(eventOrMessage)=>{
|
5607
|
-
// We execute the events registration listeners entry points:
|
5608
|
-
foreach(nodeServerInstance.receptionEntryPoints,(receptionEntryPoint,i)=>{
|
5609
|
-
receptionEntryPoint.execute(eventOrMessage, clientSocket);
|
5610
|
-
});
|
5611
|
-
};
|
5612
|
-
|
5613
|
-
if(!WebsocketImplementation.useSocketIOImplementation){ clientSocket.addEventListener("message", doOnMessage);
|
5614
|
-
// NO: else clientSocket.on("message", doOnMessage);
|
5615
|
-
}
|
5616
|
-
|
5617
|
-
doOnConnection(nodeServerInstance, clientSocket);
|
5618
|
-
|
5619
|
-
|
5620
|
-
// DBG
|
5621
|
-
lognow("DEBUG : Starting ping-pong with client : clientSocket.clientId:",clientSocket.clientId);
|
5622
|
-
lognow("DEBUG : WebsocketImplementation.useSocketIOImplementation:",WebsocketImplementation.useSocketIOImplementation);
|
5623
|
-
lognow("DEBUG : clientSocket.readyState:",clientSocket.readyState);
|
5624
|
-
|
5625
|
-
|
5626
|
-
// To make the server aware of the clients connections states :
|
5627
|
-
clientSocket.isConnectionAlive=true;
|
5628
|
-
clientSocket.stateCheckInterval=setInterval(()=>{
|
5629
|
-
|
5630
|
-
|
5631
|
-
if (clientSocket.isConnectionAlive===false){
|
5632
|
-
|
5633
|
-
|
5634
|
-
// On today, this method is named as same for the two implementations :
|
5635
|
-
// TRACE
|
5636
|
-
lognow("(SERVER) Removing all listeners for client socket «"+clientSocket.clientId+"».");
|
5637
|
-
|
5638
|
-
clientSocket.removeAllListeners();
|
5639
|
-
|
5640
|
-
|
5641
|
-
// TODO : FIXME : Use one single interface !
|
5642
|
-
if(!WebsocketImplementation.useSocketIOImplementation) clientSocket.terminate();
|
5643
|
-
else clientSocket.emit("endConnection");
|
5644
|
-
|
5645
|
-
if(!empty(nodeServerInstance.onClientLostListeners))
|
5646
|
-
foreach(nodeServerInstance.onClientLostListeners,l=>{l.execute(clientSocket);});
|
5647
|
-
|
5648
|
-
// DBG
|
5649
|
-
lognow("DEBUG : (SERVER) Connection closed for failed ping-pong.");
|
5650
|
-
|
5651
|
-
|
5652
|
-
clearInterval(clientSocket.stateCheckInterval);
|
5653
|
-
return;
|
5654
|
-
}
|
5655
|
-
|
5656
|
-
clientSocket.isConnectionAlive=false;
|
5657
|
-
|
5658
|
-
// // DBG
|
5659
|
-
// lognow("(SERVER) DEBUG : SENDING PING");
|
5660
|
-
|
5661
|
-
if(!WebsocketImplementation.useSocketIOImplementation) clientSocket.ping();
|
5662
|
-
// OLD :
|
5663
|
-
// else clientSocket.emit("ping");
|
5664
|
-
else nodeServerInstance.send("protocol",{type:"ping"}, null, clientSocket);
|
5665
|
-
|
5666
|
-
|
5667
|
-
}, nodeServerInstance.clientPingIntervalMillis);
|
5668
|
-
|
5669
|
-
|
5670
|
-
if(!WebsocketImplementation.useSocketIOImplementation){
|
5671
|
-
clientSocket.on("pong",()=>{
|
5672
|
-
clientSocket.isConnectionAlive=true;
|
5673
|
-
});
|
5674
|
-
}else{
|
5675
|
-
// // OLD :
|
5676
|
-
// clientSocket.on("ping",()=>{
|
5677
|
-
// clientSocket.isConnectionAlive=true;
|
5678
|
-
// });
|
5679
|
-
|
5680
|
-
nodeServerInstance.receive("protocol",(message)=>{
|
5681
|
-
if(message.type!=="pong") return;
|
5682
|
-
clientSocket.isConnectionAlive=true;
|
5683
|
-
});
|
5684
|
-
|
5685
|
-
}
|
5686
|
-
|
5687
|
-
|
5688
|
-
|
5689
|
-
});
|
5690
|
-
|
5691
|
-
|
5692
|
-
return nodeServerInstance;
|
5693
|
-
},
|
5694
|
-
|
5695
|
-
onFinalize:(doOnFinalizeServer)=>{
|
5696
|
-
|
5697
|
-
doOnFinalizeServer(nodeServerInstance);
|
5698
|
-
|
5699
|
-
// TRACE
|
5700
|
-
console.log("INFO : SERVER : Node server setup complete.");
|
5701
|
-
|
5702
|
-
return nodeServerInstance;
|
5703
|
-
},
|
5704
|
-
|
5705
|
-
addToRoom:(clientSocket,clientRoomTag)=>{
|
5706
|
-
clientSocket.clientRoomTag=clientRoomTag;
|
5707
|
-
},
|
5708
|
-
|
5709
|
-
|
5710
|
-
|
5711
|
-
};
|
5412
|
+
const nodeServerInstance=new NodeServerInstance(serverSocket, listenableServer);
|
5712
5413
|
|
5713
5414
|
// Join room server part protocol :
|
5714
5415
|
nodeServerInstance.receive("protocol",(message, clientSocket)=>{
|
5715
|
-
|
5716
5416
|
if(message.type!=="joinRoom" || !clientSocket) return;
|
5717
5417
|
nodeServerInstance.addToRoom(clientSocket, message.clientRoomTag);
|
5718
|
-
|
5719
5418
|
});
|
5720
5419
|
|
5721
|
-
|
5722
|
-
|
5723
5420
|
// To make the server aware of the clients connections states :
|
5724
5421
|
nodeServerInstance.serverSocket.on("close", function close() {
|
5725
5422
|
|
@@ -5732,8 +5429,6 @@ WebsocketImplementation={
|
|
5732
5429
|
clearInterval(clientSocket.stateCheckInterval);
|
5733
5430
|
});
|
5734
5431
|
});
|
5735
|
-
|
5736
|
-
|
5737
5432
|
|
5738
5433
|
return nodeServerInstance;
|
5739
5434
|
},
|
@@ -5751,14 +5446,12 @@ WebsocketImplementation={
|
|
5751
5446
|
return WebsocketImplementation.connectToServerFromBrowser(serverURL, port, isSecure, timeout);
|
5752
5447
|
},
|
5753
5448
|
|
5754
|
-
|
5755
5449
|
|
5756
5450
|
//
|
5757
5451
|
// NODE CLIENT
|
5758
5452
|
//
|
5759
5453
|
/*private*/connectToServerFromNode:(serverURL, port, isSecure, timeout)=>{
|
5760
5454
|
|
5761
|
-
|
5762
5455
|
// NODE CLIENT MODE ONLY :
|
5763
5456
|
let clientSocket;
|
5764
5457
|
if(!WebsocketImplementation.useSocketIOImplementation){
|
@@ -5787,219 +5480,13 @@ WebsocketImplementation={
|
|
5787
5480
|
// DBG
|
5788
5481
|
lognow("DEBUG : CLIENT : clientSocket created:");
|
5789
5482
|
|
5790
|
-
|
5791
|
-
// NODE CLIENT INSTANCE :
|
5792
|
-
const nodeClientInstance={
|
5793
|
-
clientSocket:clientSocket,
|
5794
|
-
|
5795
|
-
receptionEntryPoints:[],
|
5796
|
-
|
5797
|
-
receive:(channelNameParam, doOnIncomingMessage, clientsRoomsTag=null)=>{
|
5798
|
-
|
5799
|
-
const receptionEntryPoint={
|
5800
|
-
channelName:channelNameParam,
|
5801
|
-
clientsRoomsTag:clientsRoomsTag,
|
5802
|
-
execute:(eventOrMessage)=>{
|
5803
|
-
|
5804
|
-
// dataWrapped=parseJSON(dataWrapped);
|
5805
|
-
// dataWrapped=getAt(dataWrapped,0);// We get the root element
|
5806
|
-
// const dataWrapped=(WebsocketImplementation.useFlatStrings?parseJSON(eventOrMessage):eventOrMessage);
|
5807
|
-
|
5808
|
-
const dataWrapped=WebsocketImplementation.getMessageDataBothImplementations(eventOrMessage);
|
5809
|
-
|
5810
|
-
// Channel information is stored in exchanged data :
|
5811
|
-
if(dataWrapped.channelName && dataWrapped.channelName!==channelNameParam) return;
|
5812
|
-
|
5813
|
-
const clientSocket=nodeClientInstance.clientSocket;
|
5814
|
-
|
5815
|
-
// Room information is stored in client socket object :
|
5816
|
-
if(!WebsocketImplementation.isInRoom(clientSocket,clientsRoomsTag)) return;
|
5817
|
-
|
5818
|
-
if(doOnIncomingMessage) doOnIncomingMessage(dataWrapped.data, clientSocket);
|
5819
|
-
|
5820
|
-
|
5821
|
-
}
|
5822
|
-
};
|
5823
|
-
|
5824
|
-
|
5825
|
-
///!!!
|
5826
|
-
nodeClientInstance.receptionEntryPoints.push(receptionEntryPoint);
|
5827
|
-
|
5828
|
-
// SPECIAL FOR THE SOCKETIO IMPLEMENTATION :
|
5829
|
-
if(WebsocketImplementation.useSocketIOImplementation){
|
5830
|
-
const channelName=receptionEntryPoint.channelName;
|
5831
|
-
clientSocket.on(channelName, (eventOrMessage)=>{
|
5832
|
-
receptionEntryPoint.execute(eventOrMessage, clientSocket);
|
5833
|
-
});
|
5834
|
-
}
|
5835
|
-
|
5836
|
-
|
5837
|
-
return nodeClientInstance;
|
5838
|
-
},
|
5839
|
-
|
5840
|
-
|
5841
|
-
|
5842
|
-
// TODO : FIXME : DUPLICATED CODE !
|
5843
|
-
sendChainable:(channelNameParam, data, clientsRoomsTag=null)=>{
|
5844
|
-
|
5845
|
-
// DBG
|
5846
|
-
lognow(">>>>>>sendChainable NODE CLIENT ("+channelNameParam+"):data:",data);
|
5847
|
-
|
5848
|
-
// We add a message id :
|
5849
|
-
const messageId=getUUID();
|
5850
|
-
data.messageId=messageId;
|
5851
|
-
|
5852
|
-
// 1) We prepare the reception :
|
5853
|
-
const resultPromise={
|
5854
|
-
clientsRoomsTag:clientsRoomsTag,
|
5855
|
-
messageId:messageId,
|
5856
|
-
thenWhenReceiveMessageType:(channelNameForResponse, listenerConfig={messageType:"",condition:()=>true}, doOnIncomingMessageForResponse)=>{
|
5857
|
-
|
5858
|
-
listenerConfig=nonull(listenerConfig,{messageType:"",condition:()=>true});
|
5859
|
-
const listenerId=nonull(listenerConfig.messageType,"");
|
5860
|
-
|
5861
|
-
//
|
5862
|
-
nodeClientInstance.receive(channelNameForResponse, (dataLocal, clientSocket)=>{
|
5863
|
-
|
5864
|
-
// We check if the message matches the condition :
|
5865
|
-
if(listenerConfig.condition && !listenerConfig.condition(dataLocal, clientSocket)) return ;
|
5866
|
-
|
5867
|
-
// We check if we have the same message id:
|
5868
|
-
if(resultPromise.messageId!==dataLocal.messageId){
|
5869
|
-
// DBG
|
5870
|
-
lognow("resultPromise.messageId:"+resultPromise.messageId+"|dataLocal.messageId"+dataLocal.messageId);
|
5871
|
-
return;
|
5872
|
-
}
|
5873
|
-
|
5874
|
-
doOnIncomingMessageForResponse(dataLocal, clientSocket);
|
5875
|
-
}, resultPromise.clientsRoomsTag, listenerId, {destroyListenerAfterReceiving:true});
|
5876
|
-
//
|
5877
|
-
|
5878
|
-
return resultPromise;
|
5879
|
-
}
|
5880
|
-
};
|
5881
|
-
|
5882
|
-
// 2) We send the data :
|
5883
|
-
nodeClientInstance.send(channelNameParam, data, clientsRoomsTag);
|
5884
|
-
|
5885
|
-
|
5886
|
-
return resultPromise;
|
5887
|
-
},
|
5888
|
-
|
5889
|
-
|
5890
|
-
send:(channelNameParam, data, clientsRoomsTag=null)=>{
|
5891
|
-
|
5892
|
-
// // DBG
|
5893
|
-
// lognow("(CLIENT) (NODEJS) CLIENT TRIES TO SEND !");
|
5894
|
-
|
5895
|
-
|
5896
|
-
const clientSocket=nodeClientInstance.clientSocket;
|
5897
|
-
|
5898
|
-
|
5899
|
-
// // DBG
|
5900
|
-
// console.log("(NODE CLIENT) TRYING TO SEND : clientSocket.readyState:",clientSocket.readyState);
|
5901
|
-
|
5902
|
-
if(!isConnected(clientSocket)) return;
|
5903
|
-
|
5904
|
-
|
5905
|
-
// Room information is stored in client socket object :
|
5906
|
-
if(!WebsocketImplementation.isInRoom(clientSocket,clientsRoomsTag)) return;
|
5907
|
-
|
5908
|
-
// Channel information is stored in exchanged data :
|
5909
|
-
let dataWrapped={channelName:channelNameParam, data:data};
|
5910
|
-
|
5911
|
-
|
5912
|
-
// // DBG
|
5913
|
-
// console.log("(NODE CLIENT) SENDING DATA ! dataWrapped:",dataWrapped);
|
5914
|
-
|
5915
|
-
|
5916
|
-
dataWrapped=stringifyObject(dataWrapped);
|
5917
|
-
|
5918
|
-
|
5919
|
-
// // DBG
|
5920
|
-
// console.log("(NODE CLIENT) SENDING DATA ! channelNameParam:«"+channelNameParam+"» ; clientsRoomsTag:«"+clientsRoomsTag+"»");
|
5921
|
-
// console.log("(NODE CLIENT) SENDING DATA ! dataWrapped:",dataWrapped);
|
5922
|
-
|
5923
|
-
// TODO : FIXME : Use one single interface !
|
5924
|
-
if(!WebsocketImplementation.useSocketIOImplementation) clientSocket.send(dataWrapped);
|
5925
|
-
else clientSocket.emit(channelNameParam,dataWrapped);
|
5926
|
-
|
5927
|
-
return nodeClientInstance;
|
5928
|
-
},
|
5929
|
-
|
5930
|
-
|
5931
|
-
join:(clientRoomTag)=>{
|
5932
|
-
// Join room client part protocol :
|
5933
|
-
const message={type:"joinRoom",clientRoomTag:clientRoomTag};
|
5934
|
-
nodeClientInstance.send("protocol",message);
|
5935
|
-
},
|
5936
|
-
|
5937
|
-
|
5938
|
-
onConnectionToServer:(doOnConnection)=>{
|
5939
|
-
|
5940
|
-
// DBG
|
5941
|
-
lognow("DEBUG : CLIENT : setting up onConnectionToServer.");
|
5942
|
-
|
5943
|
-
const doAllOnConnection=()=>{
|
5944
|
-
|
5945
|
-
// To avoid triggering this event several times, depending on the implementation :
|
5946
|
-
if(nodeClientInstance.hasConnectEventFired) return;
|
5947
|
-
nodeClientInstance.hasConnectEventFired=true;
|
5948
|
-
|
5949
|
-
// DBG
|
5950
|
-
lognow("DEBUG : CLIENT (NODEJS) : doOnConnection !");
|
5951
|
-
|
5952
|
-
const doOnMessage=(eventOrMessage)=>{
|
5953
|
-
|
5954
|
-
// We execute the listeners entry points registration :
|
5955
|
-
foreach(nodeClientInstance.receptionEntryPoints,(receptionEntryPoint)=>{
|
5956
|
-
receptionEntryPoint.execute(eventOrMessage);
|
5957
|
-
});
|
5958
|
-
|
5959
|
-
};
|
5960
|
-
|
5961
|
-
const clientSocket=nodeClientInstance.clientSocket;
|
5962
|
-
if(!WebsocketImplementation.useSocketIOImplementation){ clientSocket.addEventListener("message", doOnMessage);
|
5963
|
-
// NO: else clientSocket.on("message", doOnMessage);
|
5964
|
-
}
|
5965
|
-
|
5966
|
-
doOnConnection(nodeClientInstance, clientSocket);
|
5967
|
-
|
5968
|
-
};
|
5969
|
-
|
5970
|
-
|
5971
|
-
if(!WebsocketImplementation.useSocketIOImplementation) nodeClientInstance.clientSocket.addEventListener("open",doAllOnConnection);
|
5972
|
-
else nodeClientInstance.clientSocket.on("connect",doAllOnConnection);
|
5973
|
-
|
5974
|
-
|
5975
|
-
// DBG
|
5976
|
-
lognow("DEBUG : CLIENT : nodeClientInstance.clientSocket.on(connect)");
|
5977
|
-
|
5978
|
-
|
5979
|
-
// Node client ping handling : (SocketIO implementation only)
|
5980
|
-
if(WebsocketImplementation.useSocketIOImplementation){
|
5981
|
-
nodeClientInstance.receive("protocol",(message)=>{
|
5982
|
-
if(message.type!=="ping") return;
|
5983
|
-
nodeClientInstance.send("protocol",{type:"pong"});
|
5984
|
-
|
5985
|
-
// DBG
|
5986
|
-
lognow("DEBUG : NODE CLIENT : Pong sent.");
|
5987
|
-
});
|
5988
|
-
}
|
5989
|
-
|
5990
|
-
|
5991
|
-
},
|
5992
|
-
|
5993
|
-
|
5994
|
-
};
|
5995
|
-
|
5996
|
-
|
5483
|
+
const nodeClientInstance=new ClientInstance(clientSocket);
|
5997
5484
|
return nodeClientInstance;
|
5998
5485
|
},
|
5999
5486
|
|
6000
|
-
|
6001
|
-
|
5487
|
+
//
|
6002
5488
|
// BROWSER CLIENT
|
5489
|
+
//
|
6003
5490
|
|
6004
5491
|
/*private*/connectToServerFromBrowser:(serverURL, port, isSecure, timeout)=>{
|
6005
5492
|
|
@@ -6008,230 +5495,22 @@ WebsocketImplementation={
|
|
6008
5495
|
// TRACE
|
6009
5496
|
lognow("ERROR : CLIENT : Could not find websocket client lib, aborting client connection.");
|
6010
5497
|
return null;
|
6011
|
-
}
|
6012
|
-
|
6013
|
-
// TODO : FIXME : Use one single interface !
|
6014
|
-
// BROWSER CLIENT MODE ONLY :
|
6015
|
-
let clientSocket;
|
6016
|
-
if(!WebsocketImplementation.useSocketIOImplementation){
|
6017
|
-
clientSocket=new WebSocket(serverURL+":"+port,["ws","wss"]);
|
6018
|
-
}else if(typeof(io)!=="undefined"){
|
6019
|
-
// OLD SYNTAX :clientSocket=io.connect(serverURL + ":" + port,{timeout: timeout, secure: isSecure});
|
6020
|
-
// ALTERNATIVE :
|
6021
|
-
clientSocket=io(serverURL + ":" + port,{timeout: timeout, secure: isSecure});
|
6022
|
-
}
|
6023
|
-
|
6024
|
-
|
6025
|
-
// BROWSER CLIENT INSTANCE :
|
6026
|
-
const browserInstance={
|
6027
|
-
|
6028
|
-
clientSocket:clientSocket,
|
6029
|
-
receptionEntryPoints:[],
|
6030
|
-
|
6031
|
-
receive:(channelNameParam, doOnIncomingMessage, clientsRoomsTag=null, receptionEntryPointId=null, listenerConfig={destroyListenerAfterReceiving:false})=>{
|
6032
|
-
|
6033
|
-
// DBG
|
6034
|
-
lognow("INFO : (CLIENT-BROWSER) SETTING UP RECEIVE for :",channelNameParam);
|
6035
|
-
|
6036
|
-
|
6037
|
-
const receptionEntryPoint={
|
6038
|
-
channelName:channelNameParam,
|
6039
|
-
clientsRoomsTag:clientsRoomsTag,
|
6040
|
-
// TODO : ADD TO ALL OTHER SUBSYSTEMS !
|
6041
|
-
id:receptionEntryPointId,
|
6042
|
-
listenerConfig:listenerConfig,
|
6043
|
-
doOnIncomingMessage:doOnIncomingMessage,
|
6044
|
-
execute:(eventOrMessage)=>{
|
6045
|
-
|
6046
|
-
const dataWrapped=WebsocketImplementation.getMessageDataBothImplementations(eventOrMessage);
|
6047
|
-
|
6048
|
-
// Channel information is stored in exchanged data :
|
6049
|
-
if(dataWrapped.channelName && dataWrapped.channelName!==receptionEntryPoint.channelName) return;
|
6050
|
-
|
6051
|
-
// Room information is stored in client socket object :
|
6052
|
-
const clientSocket=browserInstance.clientSocket;
|
6053
|
-
if(!WebsocketImplementation.isInRoom(clientSocket, receptionEntryPoint.clientsRoomsTag)) return;
|
6054
|
-
|
6055
|
-
// We remove one-time usage listeners :
|
6056
|
-
// We remove BEFORE executing doOnIncomingMessage(), because in receptionEntryPoint function we can have other listener registration UNDER THE SAME ID !
|
6057
|
-
if(receptionEntryPoint.listenerConfig && receptionEntryPoint.listenerConfig.destroyListenerAfterReceiving)
|
6058
|
-
remove(browserInstance.receptionEntryPoints, receptionEntryPoint);
|
6059
|
-
|
6060
|
-
if(receptionEntryPoint.doOnIncomingMessage)
|
6061
|
-
receptionEntryPoint.doOnIncomingMessage(dataWrapped.data, clientSocket);
|
6062
|
-
|
6063
|
-
}
|
6064
|
-
};
|
6065
|
-
|
6066
|
-
///!!!
|
6067
|
-
// TODO : ADD TO ALL OTHER SUBSYSTEMS !
|
6068
|
-
if(!contains.filter((l)=>(l.id && receptionEntryPoint.id && l.id===receptionEntryPoint.id))(browserInstance.receptionEntryPoints))
|
6069
|
-
browserInstance.receptionEntryPoints.push(receptionEntryPoint);
|
6070
|
-
|
6071
|
-
// SPECIAL FOR THE SOCKETIO IMPLEMENTATION :
|
6072
|
-
if(WebsocketImplementation.useSocketIOImplementation){
|
6073
|
-
const channelName=receptionEntryPoint.channelName;
|
6074
|
-
clientSocket.on(channelName, (eventOrMessage)=>{
|
6075
|
-
receptionEntryPoint.execute(eventOrMessage, clientSocket);
|
6076
|
-
});
|
6077
|
-
}
|
6078
|
-
|
6079
|
-
|
6080
|
-
return browserInstance;
|
6081
|
-
},
|
6082
|
-
|
6083
|
-
|
6084
|
-
|
6085
|
-
// TODO : FIXME : DUPLICATED CODE !
|
6086
|
-
sendChainable:(channelNameParam, data, clientsRoomsTag=null)=>{
|
6087
|
-
|
6088
|
-
// DBG
|
6089
|
-
lognow(">>>>>>sendChainable BROWSER CLIENT ("+channelNameParam+"):data:",data);
|
6090
|
-
|
6091
|
-
// We add a message id :
|
6092
|
-
const messageId=getUUID();
|
6093
|
-
data.messageId=messageId;
|
6094
|
-
|
6095
|
-
// 1) We prepare the reception :
|
6096
|
-
const resultPromise={
|
6097
|
-
clientsRoomsTag:clientsRoomsTag,
|
6098
|
-
messageId:messageId,
|
6099
|
-
thenWhenReceiveMessageType:(channelNameForResponse, listenerConfig={messageType:"",condition:()=>true}, doOnIncomingMessageForResponse)=>{
|
6100
|
-
listenerConfig=nonull(listenerConfig,{messageType:"",condition:()=>true});
|
6101
|
-
const listenerId=nonull(listenerConfig.messageType,"");
|
6102
|
-
|
6103
|
-
browserInstance.receive(channelNameForResponse, (dataLocal, clientSocket)=>{
|
6104
|
-
|
6105
|
-
// We check if the message matches the condition :
|
6106
|
-
if(listenerConfig.condition && !listenerConfig.condition(dataLocal, clientSocket)) return ;
|
6107
|
-
|
6108
|
-
// We check if we have the same message id:
|
6109
|
-
if(resultPromise.messageId!==dataLocal.messageId){
|
6110
|
-
// DBG
|
6111
|
-
lognow("resultPromise.messageId:"+resultPromise.messageId+"|dataLocal.messageId"+dataLocal.messageId);
|
6112
|
-
return;
|
6113
|
-
}
|
6114
|
-
|
6115
|
-
doOnIncomingMessageForResponse(dataLocal, clientSocket);
|
6116
|
-
}, resultPromise.clientsRoomsTag, listenerId, {destroyListenerAfterReceiving:true});
|
6117
|
-
return resultPromise;
|
6118
|
-
}
|
6119
|
-
};
|
6120
|
-
|
6121
|
-
// 2) We send the data :
|
6122
|
-
browserInstance.send(channelNameParam, data, clientsRoomsTag);
|
6123
|
-
|
6124
|
-
|
6125
|
-
return resultPromise;
|
6126
|
-
},
|
6127
|
-
|
6128
|
-
|
6129
|
-
|
6130
|
-
|
6131
|
-
|
6132
|
-
|
6133
|
-
send:(channelNameParam, data, clientsRoomsTag=null)=>{
|
6134
|
-
|
6135
|
-
// // DBG
|
6136
|
-
// lognow("(CLIENT) (BROWSER) CLIENT TRIES TO SEND !");
|
6137
|
-
|
6138
|
-
const clientSocket=browserInstance.clientSocket;
|
6139
|
-
|
6140
|
-
|
6141
|
-
// // DBG
|
6142
|
-
// console.log("(BROWSER) TRYING TO SEND : clientSocket.readyState:",clientSocket.readyState);
|
6143
|
-
|
6144
|
-
if(!isConnected(clientSocket)) return;
|
6145
|
-
|
6146
|
-
|
6147
|
-
// Room information is stored in client socket object :
|
6148
|
-
if(!WebsocketImplementation.isInRoom(clientSocket,clientsRoomsTag)) return;
|
6149
|
-
|
6150
|
-
// Channel information is stored in exchanged data :
|
6151
|
-
let dataWrapped={channelName:channelNameParam, data:data};
|
6152
|
-
|
6153
|
-
|
6154
|
-
// // DBG
|
6155
|
-
// console.log("(BROWSER) SENDING... : dataWrapped :",dataWrapped);
|
6156
|
-
// console.log("(BROWSER) SENDING... : clientSocket :",clientSocket);
|
6157
|
-
|
6158
|
-
|
6159
|
-
dataWrapped=stringifyObject(dataWrapped);
|
6160
|
-
|
6161
|
-
|
6162
|
-
// TODO : FIXME : Use one single interface !
|
6163
|
-
if(!WebsocketImplementation.useSocketIOImplementation) clientSocket.send(dataWrapped);
|
6164
|
-
else clientSocket.emit(channelNameParam,dataWrapped);
|
6165
|
-
|
6166
|
-
|
6167
|
-
return browserInstance;
|
6168
|
-
},
|
6169
|
-
|
6170
|
-
|
6171
|
-
join:(clientRoomTag)=>{
|
6172
|
-
// Join room client part protocol :
|
6173
|
-
const message={type:"joinRoom",clientRoomTag:clientRoomTag};
|
6174
|
-
browserInstance.send("protocol",message);
|
6175
|
-
},
|
6176
|
-
|
6177
|
-
|
6178
|
-
onConnectionToServer:(doOnConnection)=>{
|
6179
|
-
const doAllOnConnection=()=>{
|
6180
|
-
|
6181
|
-
// To avoid triggering this event several times, depending on the implementation :
|
6182
|
-
if(browserInstance.hasConnectEventFired) return;
|
6183
|
-
browserInstance.hasConnectEventFired=true;
|
6184
|
-
|
6185
|
-
|
6186
|
-
|
6187
|
-
// DBG
|
6188
|
-
lognow("DEBUG : CLIENT (BROWSER) : doOnConnection !");
|
6189
|
-
|
6190
|
-
const doOnMessage=(eventOrMessage)=>{
|
6191
|
-
|
6192
|
-
// We execute the listeners entry points registration :
|
6193
|
-
foreach(browserInstance.receptionEntryPoints,(receptionEntryPoint)=>{
|
6194
|
-
receptionEntryPoint.execute(eventOrMessage);
|
6195
|
-
});
|
6196
|
-
|
6197
|
-
};
|
6198
|
-
|
6199
|
-
const clientSocket=browserInstance.clientSocket;
|
6200
|
-
if(!WebsocketImplementation.useSocketIOImplementation){ clientSocket.addEventListener("message", doOnMessage);
|
6201
|
-
// NO: else clientSocket.on("message", doOnMessage);
|
6202
|
-
}
|
6203
|
-
|
6204
|
-
|
6205
|
-
doOnConnection(browserInstance, clientSocket);
|
6206
|
-
|
6207
|
-
};
|
6208
|
-
|
6209
|
-
if(!WebsocketImplementation.useSocketIOImplementation) browserInstance.clientSocket.addEventListener("open",doAllOnConnection);
|
6210
|
-
else browserInstance.clientSocket.on("connect",doAllOnConnection);
|
6211
|
-
|
6212
|
-
|
6213
|
-
|
6214
|
-
// Browser client ping handling : (SocketIO implementation only)
|
6215
|
-
if(WebsocketImplementation.useSocketIOImplementation){
|
6216
|
-
browserInstance.receive("protocol",(message)=>{
|
6217
|
-
if(message.type!=="ping") return;
|
6218
|
-
browserInstance.send("protocol",{type:"pong"});
|
6219
|
-
|
6220
|
-
// DBG
|
6221
|
-
lognow("DEBUG : BROWSER CLIENT : Pong sent.");
|
6222
|
-
});
|
6223
|
-
}
|
6224
|
-
|
6225
|
-
|
6226
|
-
},
|
6227
|
-
|
6228
|
-
|
6229
|
-
};
|
6230
|
-
|
6231
|
-
|
5498
|
+
}
|
6232
5499
|
|
5500
|
+
// TODO : FIXME : Use one single interface !
|
5501
|
+
// BROWSER CLIENT MODE ONLY :
|
5502
|
+
let clientSocket;
|
5503
|
+
if(!WebsocketImplementation.useSocketIOImplementation){
|
5504
|
+
clientSocket=new WebSocket(serverURL+":"+port,["ws","wss"]);
|
5505
|
+
}else if(typeof(io)!=="undefined"){
|
5506
|
+
// OLD SYNTAX :clientSocket=io.connect(serverURL + ":" + port,{timeout: timeout, secure: isSecure});
|
5507
|
+
// ALTERNATIVE :
|
5508
|
+
clientSocket=io(serverURL + ":" + port,{timeout: timeout, secure: isSecure});
|
5509
|
+
}
|
6233
5510
|
|
6234
|
-
|
5511
|
+
// BROWSER CLIENT INSTANCE :
|
5512
|
+
const browserClientInstance=new ClientInstance(clientSocket);
|
5513
|
+
return browserClientInstance;
|
6235
5514
|
},
|
6236
5515
|
|
6237
5516
|
};
|
@@ -7837,9 +7116,493 @@ getAORTACNode=function(nodeId=getUUID(), selfOrigin="ws://127.0.0.1:40000", outc
|
|
7837
7116
|
|
7838
7117
|
|
7839
7118
|
|
7119
|
+
// ==================================================================================================================
|
7120
|
+
|
7121
|
+
class NodeServerInstance{
|
7122
|
+
|
7123
|
+
constructor(serverSocket, listenableServer){
|
7124
|
+
|
7125
|
+
this.onClientLostListeners=[];
|
7126
|
+
|
7127
|
+
this.clientPingIntervalMillis=5000;
|
7128
|
+
this.serverSocket=serverSocket;
|
7129
|
+
this.listenableServer=listenableServer;
|
7130
|
+
this.receptionEntryPoints=[];
|
7131
|
+
|
7132
|
+
}
|
7133
|
+
|
7134
|
+
setPingPongTimeout(clientPingIntervalMillis){
|
7135
|
+
this.clientPingIntervalMillis=clientPingIntervalMillis;
|
7136
|
+
return this;
|
7137
|
+
}
|
7138
|
+
|
7139
|
+
close(doOnCloseServer){
|
7140
|
+
if(!this.serverSocket) return;
|
7141
|
+
this.serverSocket.close(()=>{
|
7142
|
+
if(!this.listenableServer) return;
|
7143
|
+
this.listenableServer.close(doOnCloseServer);
|
7144
|
+
});
|
7145
|
+
}
|
7146
|
+
|
7147
|
+
receive(channelNameParam, doOnIncomingMessage, clientsRoomsTag=null){
|
7148
|
+
const self=this;
|
7149
|
+
|
7150
|
+
// DBG
|
7151
|
+
lognow("(SERVER) Registering receive for «"+channelNameParam+"»...");
|
7152
|
+
|
7153
|
+
|
7154
|
+
const receptionEntryPoint={
|
7155
|
+
channelName:channelNameParam,
|
7156
|
+
clientsRoomsTag:clientsRoomsTag,
|
7157
|
+
execute:(eventOrMessage, clientSocketParam)=>{
|
7158
|
+
|
7159
|
+
// With «ws» library we have no choive than register message events inside a «connection» event !
|
7160
|
+
|
7161
|
+
const dataWrapped=WebsocketImplementation.getMessageDataBothImplementations(eventOrMessage);
|
7162
|
+
|
7163
|
+
// Channel information is stored in exchanged data :
|
7164
|
+
if(dataWrapped.channelName!==receptionEntryPoint.channelName) return;
|
7165
|
+
|
7166
|
+
|
7167
|
+
// TODO : FIXME : Use one single interface !
|
7168
|
+
// Room information is stored in client socket object :
|
7169
|
+
const isClientInRoom=WebsocketImplementation.isInRoom(clientSocketParam, receptionEntryPoint.clientsRoomsTag);
|
7170
|
+
|
7171
|
+
// DBG
|
7172
|
+
lognow("(SERVER) isClientInRoom:",isClientInRoom);
|
7173
|
+
|
7174
|
+
if(!isClientInRoom) return;
|
7175
|
+
|
7176
|
+
if(doOnIncomingMessage){
|
7177
|
+
// DBG
|
7178
|
+
lognow("(SERVER) doOnIncomingMessage:");
|
7179
|
+
doOnIncomingMessage(dataWrapped.data, clientSocketParam);
|
7180
|
+
}
|
7181
|
+
|
7182
|
+
},
|
7183
|
+
};
|
7184
|
+
|
7185
|
+
|
7186
|
+
///!!!
|
7187
|
+
self.receptionEntryPoints.push(receptionEntryPoint);
|
7188
|
+
|
7189
|
+
// SPECIAL FOR THE SOCKETIO IMPLEMENTATION :
|
7190
|
+
if(WebsocketImplementation.useSocketIOImplementation){
|
7191
|
+
const channelName=receptionEntryPoint.channelName;
|
7192
|
+
clientSocket.on(channelName, (eventOrMessage)=>{
|
7193
|
+
receptionEntryPoint.execute(eventOrMessage, clientSocket);
|
7194
|
+
});
|
7195
|
+
}
|
7196
|
+
|
7197
|
+
return this;
|
7198
|
+
}
|
7199
|
+
|
7200
|
+
|
7201
|
+
send(channelName, data, clientsRoomsTag=null, clientSocketParam=null){
|
7202
|
+
|
7203
|
+
// DBG
|
7204
|
+
lognow("(SERVER) SERVER TRIES TO SEND !");
|
7205
|
+
|
7206
|
+
|
7207
|
+
if(!clientSocketParam){
|
7208
|
+
|
7209
|
+
// DBG
|
7210
|
+
lognow("(SERVER) (server sends to all clients)");
|
7211
|
+
|
7212
|
+
// TODO : FIXME : Use one single interface !
|
7213
|
+
let serverClients;
|
7214
|
+
if(!WebsocketImplementation.useSocketIOImplementation) serverClients=this.serverSocket.clients;
|
7215
|
+
else serverClients=this.serverSocket.sockets.sockets;
|
7216
|
+
|
7217
|
+
|
7218
|
+
serverClients.forEach((clientSocket)=>{
|
7219
|
+
|
7220
|
+
|
7221
|
+
if(!isConnected(clientSocket)) return;
|
7222
|
+
|
7223
|
+
|
7224
|
+
// Room information is stored in client socket object :
|
7225
|
+
if(!WebsocketImplementation.isInRoom(clientSocket,clientsRoomsTag)) return;
|
7226
|
+
|
7227
|
+
// Channel information is stored in exchanged data :
|
7228
|
+
let dataWrapped={channelName:channelName, data:data};
|
7229
|
+
|
7230
|
+
|
7231
|
+
dataWrapped=stringifyObject(dataWrapped);
|
7232
|
+
|
7233
|
+
// TODO : FIXME : Use one single interface !
|
7234
|
+
if(!WebsocketImplementation.useSocketIOImplementation) clientSocket.send(dataWrapped);
|
7235
|
+
else clientSocket.emit(channelName,dataWrapped);
|
7236
|
+
|
7237
|
+
});
|
7238
|
+
|
7239
|
+
}else{
|
7240
|
+
|
7241
|
+
// DBG
|
7242
|
+
lognow("(SERVER) (server sends to a client)");
|
7243
|
+
|
7244
|
+
|
7245
|
+
// TODO : FIXME : Use one single interface !
|
7246
|
+
let clientSocket=clientSocketParam;
|
7247
|
+
if(!WebsocketImplementation.useSocketIOImplementation) if(clientSocket.readyState!==WebSocket.OPEN) return;
|
7248
|
+
else if(clientSocket.connected) return;
|
7249
|
+
|
7250
|
+
|
7251
|
+
// Room information is stored in client socket object :
|
7252
|
+
if(!WebsocketImplementation.isInRoom(clientSocket,clientsRoomsTag)) return;
|
7253
|
+
|
7254
|
+
// Channel information is stored in exchanged data :
|
7255
|
+
let dataWrapped={channelName:channelName, data:data};
|
7256
|
+
dataWrapped=stringifyObject(dataWrapped);
|
7257
|
+
|
7258
|
+
|
7259
|
+
// DBG
|
7260
|
+
lognow("(SERVER) WebsocketImplementation.useSocketIOImplementation:"+WebsocketImplementation.useSocketIOImplementation);
|
7261
|
+
|
7262
|
+
|
7263
|
+
// TODO : FIXME : Use one single interface !
|
7264
|
+
if(!WebsocketImplementation.useSocketIOImplementation) clientSocket.send(dataWrapped);
|
7265
|
+
else clientSocket.emit(channelName,dataWrapped);
|
7266
|
+
|
7267
|
+
}
|
7268
|
+
|
7269
|
+
|
7270
|
+
return this;
|
7271
|
+
}
|
7272
|
+
|
7273
|
+
|
7274
|
+
onConnectionToClient(doOnConnection){
|
7275
|
+
const self=this;
|
7276
|
+
|
7277
|
+
|
7278
|
+
// «connection» is the only event fired by the serverSocket :
|
7279
|
+
this.serverSocket.on("connection", (clientSocket)=>{
|
7280
|
+
|
7281
|
+
// DBG
|
7282
|
+
console.log("SERVER : ON CONNECTION !");
|
7283
|
+
|
7284
|
+
|
7285
|
+
const clientId="autogeneratedid_"+getUUID();
|
7286
|
+
|
7287
|
+
clientSocket.clientId=clientId;
|
7288
|
+
|
7289
|
+
|
7290
|
+
const doOnMessage=(eventOrMessage)=>{
|
7291
|
+
// We execute the events registration listeners entry points:
|
7292
|
+
foreach(self.receptionEntryPoints,(receptionEntryPoint,i)=>{
|
7293
|
+
receptionEntryPoint.execute(eventOrMessage, clientSocket);
|
7294
|
+
});
|
7295
|
+
};
|
7296
|
+
|
7297
|
+
if(!WebsocketImplementation.useSocketIOImplementation)
|
7298
|
+
clientSocket.addEventListener("message", doOnMessage);
|
7299
|
+
|
7300
|
+
doOnConnection(this, clientSocket);
|
7301
|
+
|
7302
|
+
|
7303
|
+
// DBG
|
7304
|
+
lognow("DEBUG : Starting ping-pong with client : clientSocket.clientId:",clientSocket.clientId);
|
7305
|
+
lognow("DEBUG : WebsocketImplementation.useSocketIOImplementation:",WebsocketImplementation.useSocketIOImplementation);
|
7306
|
+
lognow("DEBUG : clientSocket.readyState:",clientSocket.readyState);
|
7307
|
+
|
7308
|
+
|
7309
|
+
// To make the server aware of the clients connections states :
|
7310
|
+
clientSocket.isConnectionAlive=true;
|
7311
|
+
clientSocket.stateCheckInterval=setInterval(()=>{
|
7312
|
+
|
7313
|
+
if (clientSocket.isConnectionAlive===false){
|
7314
|
+
|
7315
|
+
// On today, this method is named as same for the two implementations :
|
7316
|
+
// TRACE
|
7317
|
+
lognow("(SERVER) Removing all listeners for client socket «"+clientSocket.clientId+"».");
|
7318
|
+
|
7319
|
+
clientSocket.removeAllListeners();
|
7320
|
+
|
7321
|
+
// TODO : FIXME : Use one single interface !
|
7322
|
+
if(!WebsocketImplementation.useSocketIOImplementation) clientSocket.terminate();
|
7323
|
+
else clientSocket.emit("endConnection");
|
7324
|
+
|
7325
|
+
if(!empty(self.onClientLostListeners))
|
7326
|
+
foreach(self.onClientLostListeners,l=>{l.execute(clientSocket);});
|
7327
|
+
|
7328
|
+
// DBG
|
7329
|
+
lognow("DEBUG : (SERVER) Connection closed for failed ping-pong.");
|
7330
|
+
|
7331
|
+
|
7332
|
+
clearInterval(clientSocket.stateCheckInterval);
|
7333
|
+
return;
|
7334
|
+
}
|
7335
|
+
|
7336
|
+
clientSocket.isConnectionAlive=false;
|
7337
|
+
|
7338
|
+
if(!WebsocketImplementation.useSocketIOImplementation) clientSocket.ping();
|
7339
|
+
else self.send("protocol",{type:"ping"}, null, clientSocket);
|
7340
|
+
|
7341
|
+
|
7342
|
+
}, this.clientPingIntervalMillis);
|
7343
|
+
|
7344
|
+
|
7345
|
+
if(!WebsocketImplementation.useSocketIOImplementation){
|
7346
|
+
clientSocket.on("pong",()=>{
|
7347
|
+
clientSocket.isConnectionAlive=true;
|
7348
|
+
});
|
7349
|
+
}else{
|
7350
|
+
|
7351
|
+
this.receive("protocol",(message)=>{
|
7352
|
+
if(message.type!=="pong") return;
|
7353
|
+
clientSocket.isConnectionAlive=true;
|
7354
|
+
});
|
7355
|
+
|
7356
|
+
}
|
7357
|
+
|
7358
|
+
});
|
7359
|
+
|
7360
|
+
|
7361
|
+
return this;
|
7362
|
+
}
|
7363
|
+
|
7364
|
+
onFinalize(doOnFinalizeServer){
|
7365
|
+
|
7366
|
+
doOnFinalizeServer(this);
|
7367
|
+
|
7368
|
+
// TRACE
|
7369
|
+
console.log("INFO : SERVER : Node server setup complete.");
|
7370
|
+
|
7371
|
+
return this;
|
7372
|
+
}
|
7373
|
+
|
7374
|
+
addToRoom(clientSocket, clientRoomTag){
|
7375
|
+
clientSocket.clientRoomTag=clientRoomTag;
|
7376
|
+
}
|
7377
|
+
|
7378
|
+
}
|
7379
|
+
|
7380
|
+
|
7381
|
+
|
7382
|
+
|
7383
|
+
|
7384
|
+
|
7385
|
+
|
7386
|
+
|
7387
|
+
/* ## Utility network global methods in a javascript, console (nodejs), or vanilla javascript with no browser environment.
|
7388
|
+
*
|
7389
|
+
* This set of methods gathers utility generic-purpose methods usable in any JS project.
|
7390
|
+
* Several authors of snippets published freely on the Internet contributed to this library.
|
7391
|
+
* Feel free to use/modify-enhance/publish them under the terms of its license.
|
7392
|
+
*
|
7393
|
+
* # Library name : «aotrautils»
|
7394
|
+
* # Library license : HGPL(Help Burma) (see aotra README information for details : https://alqemia.com/aotra.js )
|
7395
|
+
* # Author name : Jérémie Ratomposon (massively helped by his native country free education system)
|
7396
|
+
* # Author email : info@alqemia.com
|
7397
|
+
* # Organization name : Alqemia
|
7398
|
+
* # Organization email : admin@alqemia.com
|
7399
|
+
* # Organization website : https://alqemia.com
|
7400
|
+
*
|
7401
|
+
*
|
7402
|
+
*/
|
7403
|
+
|
7404
|
+
|
7405
|
+
|
7406
|
+
// COMPATIBILITY browser javascript / nodejs environment :
|
7407
|
+
if(typeof(window)==="undefined") window=global;
|
7408
|
+
|
7409
|
+
|
7410
|
+
|
7411
|
+
// ==================================================================================================================
|
7412
|
+
|
7413
|
+
//
|
7414
|
+
// CLIENT INSTANCE :
|
7415
|
+
//
|
7416
|
+
class ClientInstance{
|
7417
|
+
|
7418
|
+
constructor(clientSocket){
|
7419
|
+
this.clientSocket=clientSocket;
|
7420
|
+
this.receptionEntryPoints=[];
|
7421
|
+
|
7422
|
+
}
|
7423
|
+
|
7424
|
+
receive(channelNameParam, doOnIncomingMessage, clientsRoomsTag=null, receptionEntryPointId=null, listenerConfig={destroyListenerAfterReceiving:false}){
|
7425
|
+
const self=this;
|
7426
|
+
|
7427
|
+
// DBG
|
7428
|
+
lognow("INFO : (CLIENT-BROWSER) SETTING UP RECEIVE for :",channelNameParam);
|
7429
|
+
|
7430
|
+
const receptionEntryPoint={
|
7431
|
+
channelName:channelNameParam,
|
7432
|
+
clientsRoomsTag:clientsRoomsTag,
|
7433
|
+
// TODO : ADD TO ALL OTHER SUBSYSTEMS !
|
7434
|
+
id:receptionEntryPointId,
|
7435
|
+
listenerConfig:listenerConfig,
|
7436
|
+
doOnIncomingMessage:doOnIncomingMessage,
|
7437
|
+
execute:(eventOrMessage)=>{
|
7438
|
+
|
7439
|
+
const dataWrapped=WebsocketImplementation.getMessageDataBothImplementations(eventOrMessage);
|
7440
|
+
|
7441
|
+
// Channel information is stored in exchanged data :
|
7442
|
+
if(dataWrapped.channelName && dataWrapped.channelName!==receptionEntryPoint.channelName) return;
|
7443
|
+
|
7444
|
+
// Room information is stored in client socket object :
|
7445
|
+
const clientSocket=self.clientSocket;
|
7446
|
+
if(!WebsocketImplementation.isInRoom(clientSocket, receptionEntryPoint.clientsRoomsTag)) return;
|
7447
|
+
|
7448
|
+
// We remove one-time usage listeners :
|
7449
|
+
// We remove BEFORE executing doOnIncomingMessage(), because in receptionEntryPoint function we can have other listener registration UNDER THE SAME ID !
|
7450
|
+
if(receptionEntryPoint.listenerConfig && receptionEntryPoint.listenerConfig.destroyListenerAfterReceiving)
|
7451
|
+
remove(self.receptionEntryPoints, receptionEntryPoint);
|
7452
|
+
|
7453
|
+
if(receptionEntryPoint.doOnIncomingMessage)
|
7454
|
+
receptionEntryPoint.doOnIncomingMessage(dataWrapped.data, clientSocket);
|
7455
|
+
|
7456
|
+
}
|
7457
|
+
};
|
7458
|
+
|
7459
|
+
///!!!
|
7460
|
+
// TODO : ADD TO ALL OTHER SUBSYSTEMS !
|
7461
|
+
if(!contains.filter((l)=>(l.id && receptionEntryPoint.id && l.id===receptionEntryPoint.id))(this.receptionEntryPoints))
|
7462
|
+
this.receptionEntryPoints.push(receptionEntryPoint);
|
7463
|
+
|
7464
|
+
// SPECIAL FOR THE SOCKETIO IMPLEMENTATION :
|
7465
|
+
if(WebsocketImplementation.useSocketIOImplementation){
|
7466
|
+
const channelName=receptionEntryPoint.channelName;
|
7467
|
+
clientSocket.on(channelName, (eventOrMessage)=>{
|
7468
|
+
receptionEntryPoint.execute(eventOrMessage, clientSocket);
|
7469
|
+
});
|
7470
|
+
}
|
7471
|
+
|
7472
|
+
|
7473
|
+
return this;
|
7474
|
+
}
|
7475
|
+
|
7476
|
+
sendChainable(channelNameParam, data, clientsRoomsTag=null){
|
7477
|
+
const self=this;
|
7478
|
+
|
7479
|
+
// DBG
|
7480
|
+
lognow(">>>>>>sendChainable CLIENT ("+channelNameParam+"):data:",data);
|
7481
|
+
|
7482
|
+
// We add a message id :
|
7483
|
+
const messageId=getUUID();
|
7484
|
+
data.messageId=messageId;
|
7485
|
+
|
7486
|
+
// 1) We prepare the reception :
|
7487
|
+
const resultPromise={
|
7488
|
+
clientsRoomsTag:clientsRoomsTag,
|
7489
|
+
messageId:messageId,
|
7490
|
+
thenWhenReceiveMessageType:(channelNameForResponse, listenerConfig={messageType:"",condition:()=>true}, doOnIncomingMessageForResponse)=>{
|
7491
|
+
listenerConfig=nonull(listenerConfig,{messageType:"",condition:()=>true});
|
7492
|
+
const listenerId=nonull(listenerConfig.messageType,"");
|
7493
|
+
|
7494
|
+
//
|
7495
|
+
self.receive(channelNameForResponse, (dataLocal, clientSocket)=>{
|
7496
|
+
|
7497
|
+
// We check if the message matches the condition :
|
7498
|
+
if(listenerConfig.condition && !listenerConfig.condition(dataLocal, clientSocket)) return ;
|
7499
|
+
|
7500
|
+
// We check if we have the same message id:
|
7501
|
+
if(resultPromise.messageId!==dataLocal.messageId){
|
7502
|
+
// DBG
|
7503
|
+
lognow("resultPromise.messageId:"+resultPromise.messageId+"|dataLocal.messageId"+dataLocal.messageId);
|
7504
|
+
return;
|
7505
|
+
}
|
7506
|
+
|
7507
|
+
doOnIncomingMessageForResponse(dataLocal, clientSocket);
|
7508
|
+
}, resultPromise.clientsRoomsTag, listenerId, {destroyListenerAfterReceiving:true});
|
7509
|
+
//
|
7510
|
+
|
7511
|
+
return resultPromise;
|
7512
|
+
}
|
7513
|
+
};
|
7514
|
+
|
7515
|
+
// 2) We send the data :
|
7516
|
+
this.send(channelNameParam, data, clientsRoomsTag);
|
7517
|
+
|
7518
|
+
|
7519
|
+
return resultPromise;
|
7520
|
+
}
|
7521
|
+
|
7522
|
+
|
7523
|
+
send(channelNameParam, data, clientsRoomsTag=null){
|
7524
|
+
|
7525
|
+
// // DBG
|
7526
|
+
// lognow("(CLIENT) CLIENT TRIES TO SEND !");
|
7527
|
+
|
7528
|
+
const clientSocket=this.clientSocket;
|
7529
|
+
|
7530
|
+
if(!isConnected(clientSocket)) return;
|
7531
|
+
|
7532
|
+
// Room information is stored in client socket object :
|
7533
|
+
if(!WebsocketImplementation.isInRoom(clientSocket,clientsRoomsTag)) return;
|
7534
|
+
|
7535
|
+
// Channel information is stored in exchanged data :
|
7536
|
+
let dataWrapped={channelName:channelNameParam, data:data};
|
7537
|
+
|
7538
|
+
dataWrapped=stringifyObject(dataWrapped);
|
7539
|
+
|
7540
|
+
// TODO : FIXME : Use one single interface !
|
7541
|
+
if(!WebsocketImplementation.useSocketIOImplementation) clientSocket.send(dataWrapped);
|
7542
|
+
else clientSocket.emit(channelNameParam,dataWrapped);
|
7543
|
+
|
7544
|
+
return this;
|
7545
|
+
}
|
7546
|
+
|
7547
|
+
|
7548
|
+
join(clientRoomTag){
|
7549
|
+
// Join room client part protocol :
|
7550
|
+
const message={type:"joinRoom",clientRoomTag:clientRoomTag};
|
7551
|
+
this.send("protocol",message);
|
7552
|
+
}
|
7553
|
+
|
7554
|
+
|
7555
|
+
onConnectionToServer(doOnConnection){
|
7556
|
+
const self=this;
|
7557
|
+
|
7558
|
+
// DBG
|
7559
|
+
lognow("DEBUG : CLIENT : setting up onConnectionToServer.");
|
7560
|
+
|
7561
|
+
const doAllOnConnection=()=>{
|
7840
7562
|
|
7563
|
+
// To avoid triggering this event several times, depending on the implementation :
|
7564
|
+
if(self.hasConnectEventFired) return;
|
7565
|
+
self.hasConnectEventFired=true;
|
7566
|
+
|
7567
|
+
// DBG
|
7568
|
+
lognow("DEBUG : CLIENT : doOnConnection !");
|
7569
|
+
|
7570
|
+
const doOnMessage=(eventOrMessage)=>{
|
7571
|
+
|
7572
|
+
// We execute the listeners entry points registration :
|
7573
|
+
foreach(self.receptionEntryPoints,(receptionEntryPoint)=>{
|
7574
|
+
receptionEntryPoint.execute(eventOrMessage);
|
7575
|
+
});
|
7841
7576
|
|
7577
|
+
};
|
7578
|
+
|
7579
|
+
const clientSocket=self.clientSocket;
|
7580
|
+
if(!WebsocketImplementation.useSocketIOImplementation){ clientSocket.addEventListener("message", doOnMessage);
|
7581
|
+
}
|
7842
7582
|
|
7583
|
+
doOnConnection(self, clientSocket);
|
7584
|
+
|
7585
|
+
};
|
7586
|
+
|
7587
|
+
if(!WebsocketImplementation.useSocketIOImplementation) this.clientSocket.addEventListener("open",doAllOnConnection);
|
7588
|
+
else this.clientSocket.on("connect",doAllOnConnection);
|
7589
|
+
|
7590
|
+
|
7591
|
+
// Client ping handling : (SocketIO implementation only)
|
7592
|
+
if(WebsocketImplementation.useSocketIOImplementation){
|
7593
|
+
this.receive("protocol",(message)=>{
|
7594
|
+
if(message.type!=="ping") return;
|
7595
|
+
self.send("protocol",{type:"pong"});
|
7596
|
+
|
7597
|
+
// DBG
|
7598
|
+
lognow("DEBUG : CLIENT : Pong sent.");
|
7599
|
+
});
|
7600
|
+
}
|
7601
|
+
|
7602
|
+
|
7603
|
+
}
|
7604
|
+
|
7605
|
+
}
|
7843
7606
|
|
7844
7607
|
|
7845
7608
|
/* INCLUDED EXTERNAL LIBRAIRIES
|
aotrautils-srv/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "aotrautils-srv",
|
3
|
-
"version": "0.0.
|
3
|
+
"version": "0.0.1478",
|
4
4
|
"main": "aotrautils-srv.build.js",
|
5
5
|
"description": "A library for vanilla javascript utils (server-side) used in aotra javascript CMS",
|
6
6
|
"author": "Jeremie Ratomposon <info@alqemia.com> (https://alqemia.com)",
|