aotrautils-srv 0.0.1476 → 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.
@@ -1,6 +1,6 @@
1
1
 
2
2
 
3
- /*utils COMMONS library associated with aotra version : «1_29072022-2359 (26/04/2025-13:41:01)»*/
3
+ /*utils COMMONS library associated with aotra version : «1_29072022-2359 (26/04/2025-16:15:53)»*/
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-13:41:01)»*/
4897
+ /*utils AI library associated with aotra version : «1_29072022-2359 (26/04/2025-16:15:53)»*/
4898
4898
  /*-----------------------------------------------------------------------------*/
4899
4899
 
4900
4900
 
@@ -5040,11 +5040,11 @@ getOpenAIAPIClient=(modelName, apiURL, agentRole, defaultPrompt)=>{
5040
5040
 
5041
5041
 
5042
5042
 
5043
- /*utils SERVER library associated with aotra version : «1_29072022-2359 (26/04/2025-13:41:01)»*/
5043
+ /*utils CONSOLE library associated with aotra version : «1_29072022-2359 (26/04/2025-16:15:53)»*/
5044
5044
  /*-----------------------------------------------------------------------------*/
5045
5045
 
5046
5046
 
5047
- /* ## Utility global methods in a javascript, console (nodejs) server, or vanilla javascript with no browser environment.
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
 
@@ -6010,228 +5497,20 @@ WebsocketImplementation={
6010
5497
  return null;
6011
5498
  }
6012
5499
 
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
-
6232
-
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
- return browserInstance;
5511
+ // BROWSER CLIENT INSTANCE :
5512
+ const browserClientInstance=new ClientInstance(clientSocket);
5513
+ return browserClientInstance;
6235
5514
  },
6236
5515
 
6237
5516
  };
@@ -7837,9 +7116,495 @@ 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
+
7477
+ // TODO : FIXME : DUPLICATED CODE !
7478
+ sendChainable(channelNameParam, data, clientsRoomsTag=null){
7479
+ const self=this;
7480
+
7481
+ // DBG
7482
+ lognow(">>>>>>sendChainable CLIENT ("+channelNameParam+"):data:",data);
7483
+
7484
+ // We add a message id :
7485
+ const messageId=getUUID();
7486
+ data.messageId=messageId;
7487
+
7488
+ // 1) We prepare the reception :
7489
+ const resultPromise={
7490
+ clientsRoomsTag:clientsRoomsTag,
7491
+ messageId:messageId,
7492
+ thenWhenReceiveMessageType:(channelNameForResponse, listenerConfig={messageType:"",condition:()=>true}, doOnIncomingMessageForResponse)=>{
7493
+ listenerConfig=nonull(listenerConfig,{messageType:"",condition:()=>true});
7494
+ const listenerId=nonull(listenerConfig.messageType,"");
7495
+
7496
+ //
7497
+ self.receive(channelNameForResponse, (dataLocal, clientSocket)=>{
7498
+
7499
+ // We check if the message matches the condition :
7500
+ if(listenerConfig.condition && !listenerConfig.condition(dataLocal, clientSocket)) return ;
7501
+
7502
+ // We check if we have the same message id:
7503
+ if(resultPromise.messageId!==dataLocal.messageId){
7504
+ // DBG
7505
+ lognow("resultPromise.messageId:"+resultPromise.messageId+"|dataLocal.messageId"+dataLocal.messageId);
7506
+ return;
7507
+ }
7508
+
7509
+ doOnIncomingMessageForResponse(dataLocal, clientSocket);
7510
+ }, resultPromise.clientsRoomsTag, listenerId, {destroyListenerAfterReceiving:true});
7511
+ //
7512
+
7513
+ return resultPromise;
7514
+ }
7515
+ };
7516
+
7517
+ // 2) We send the data :
7518
+ this.send(channelNameParam, data, clientsRoomsTag);
7519
+
7520
+
7521
+ return resultPromise;
7522
+ }
7523
+
7524
+
7525
+ send(channelNameParam, data, clientsRoomsTag=null){
7526
+
7527
+ // // DBG
7528
+ // lognow("(CLIENT) CLIENT TRIES TO SEND !");
7529
+
7530
+ const clientSocket=this.clientSocket;
7531
+
7532
+ if(!isConnected(clientSocket)) return;
7533
+
7534
+ // Room information is stored in client socket object :
7535
+ if(!WebsocketImplementation.isInRoom(clientSocket,clientsRoomsTag)) return;
7536
+
7537
+ // Channel information is stored in exchanged data :
7538
+ let dataWrapped={channelName:channelNameParam, data:data};
7539
+
7540
+ dataWrapped=stringifyObject(dataWrapped);
7541
+
7542
+ // TODO : FIXME : Use one single interface !
7543
+ if(!WebsocketImplementation.useSocketIOImplementation) clientSocket.send(dataWrapped);
7544
+ else clientSocket.emit(channelNameParam,dataWrapped);
7545
+
7546
+ return this;
7547
+ }
7548
+
7549
+
7550
+ join(clientRoomTag){
7551
+ // Join room client part protocol :
7552
+ const message={type:"joinRoom",clientRoomTag:clientRoomTag};
7553
+ this.send("protocol",message);
7554
+ }
7555
+
7556
+
7557
+ onConnectionToServer(doOnConnection){
7558
+ const self=this;
7559
+
7560
+ // DBG
7561
+ lognow("DEBUG : CLIENT : setting up onConnectionToServer.");
7562
+
7563
+ const doAllOnConnection=()=>{
7840
7564
 
7565
+ // To avoid triggering this event several times, depending on the implementation :
7566
+ if(self.hasConnectEventFired) return;
7567
+ self.hasConnectEventFired=true;
7568
+
7569
+ // DBG
7570
+ lognow("DEBUG : CLIENT : doOnConnection !");
7571
+
7572
+ const doOnMessage=(eventOrMessage)=>{
7573
+
7574
+ // We execute the listeners entry points registration :
7575
+ foreach(self.receptionEntryPoints,(receptionEntryPoint)=>{
7576
+ receptionEntryPoint.execute(eventOrMessage);
7577
+ });
7841
7578
 
7579
+ };
7580
+
7581
+ const clientSocket=self.clientSocket;
7582
+ if(!WebsocketImplementation.useSocketIOImplementation){ clientSocket.addEventListener("message", doOnMessage);
7583
+ }
7842
7584
 
7585
+ doOnConnection(self, clientSocket);
7586
+
7587
+ };
7588
+
7589
+ if(!WebsocketImplementation.useSocketIOImplementation) this.clientSocket.addEventListener("open",doAllOnConnection);
7590
+ else this.clientSocket.on("connect",doAllOnConnection);
7591
+
7592
+
7593
+ // Client ping handling : (SocketIO implementation only)
7594
+ if(WebsocketImplementation.useSocketIOImplementation){
7595
+ this.receive("protocol",(message)=>{
7596
+ if(message.type!=="ping") return;
7597
+ self.send("protocol",{type:"pong"});
7598
+
7599
+ // DBG
7600
+ lognow("DEBUG : CLIENT : Pong sent.");
7601
+ });
7602
+ }
7603
+
7604
+
7605
+ }
7606
+
7607
+ }
7843
7608
 
7844
7609
 
7845
7610
  /* INCLUDED EXTERNAL LIBRAIRIES
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aotrautils-srv",
3
- "version": "0.0.1476",
3
+ "version": "0.0.1477",
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)",