webpeerjs 0.0.7 → 0.0.9
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.
- package/README.md +42 -22
- package/dist/esm/webpeerjs.d.ts +4 -3
- package/dist/esm/webpeerjs.js +356 -131
- package/dist/umd/webpeerjs.js +15381 -15160
- package/package.json +11 -14
- package/src/config.js +8 -7
- package/src/utils.js +19 -8
- package/src/webpeerjs.js +348 -122
package/dist/esm/webpeerjs.js
CHANGED
|
@@ -2,6 +2,11 @@ import { message, encodeMessage, decodeMessage } from 'protons-runtime';
|
|
|
2
2
|
import { alloc } from 'uint8arrays/alloc';
|
|
3
3
|
import { Key } from 'interface-datastore';
|
|
4
4
|
import { sha256 } from 'multiformats/hashes/sha2';
|
|
5
|
+
import { multiaddr } from '@multiformats/multiaddr';
|
|
6
|
+
import { pipe } from 'it-pipe';
|
|
7
|
+
import 'it-length-prefixed-stream';
|
|
8
|
+
import * as lp from 'it-length-prefixed';
|
|
9
|
+
import map from 'it-map';
|
|
5
10
|
import { createDelegatedRoutingV1HttpApiClient } from '@helia/delegated-routing-v1-http-api-client';
|
|
6
11
|
import { createLibp2p } from 'libp2p';
|
|
7
12
|
import { IDBDatastore } from 'datastore-idb';
|
|
@@ -12,14 +17,13 @@ import { pubsubPeerDiscovery } from '@libp2p/pubsub-peer-discovery';
|
|
|
12
17
|
import { circuitRelayTransport } from '@libp2p/circuit-relay-v2';
|
|
13
18
|
import { gossipsub } from '@chainsafe/libp2p-gossipsub';
|
|
14
19
|
import { identify, identifyPush } from '@libp2p/identify';
|
|
15
|
-
import { multiaddr } from '@multiformats/multiaddr';
|
|
16
20
|
import { peerIdFromString } from '@libp2p/peer-id';
|
|
17
21
|
import { kadDHT, removePrivateAddressesMapper } from '@libp2p/kad-dht';
|
|
18
22
|
import { simpleMetrics } from '@libp2p/simple-metrics';
|
|
19
23
|
|
|
20
24
|
const prefix$1 = 'webpeerjs';
|
|
21
25
|
const CONFIG_PREFIX = prefix$1;
|
|
22
|
-
const CONFIG_PROTOCOL = '/'+prefix$1+'/0.0
|
|
26
|
+
const CONFIG_PROTOCOL = '/'+prefix$1+'/1.0.0';
|
|
23
27
|
const CONFIG_DBSTORE_PATH = prefix$1+'-dbstore';
|
|
24
28
|
const CONFIG_MAX_CONNECTIONS = 100;
|
|
25
29
|
const CONFIG_MIN_CONNECTIONS = 0;
|
|
@@ -30,10 +34,7 @@ const CONFIG_PEER_DISCOVERY_WEBPEERJS= prefix$1+'-peer-discovery';
|
|
|
30
34
|
const CONFIG_PUBSUB_PEER_DISCOVERY = [CONFIG_PEER_DISCOVERY_GLOBAL, CONFIG_PEER_DISCOVERY_UNIVERSAL_CONNECTIVITY, CONFIG_PEER_DISCOVERY_WEBPEERJS];
|
|
31
35
|
const CONFIG_DELEGATED_API = 'https://delegated-ipfs.dev';
|
|
32
36
|
|
|
33
|
-
const
|
|
34
|
-
];
|
|
35
|
-
|
|
36
|
-
const CONFIG_KNOWN_BOOTSTRAP_PEERS_IDS = [
|
|
37
|
+
const CONFIG_KNOWN_BOOTSTRAP_PUBLIC_IDS = [
|
|
37
38
|
'QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN',
|
|
38
39
|
'QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb',
|
|
39
40
|
'QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt',
|
|
@@ -45,12 +46,16 @@ const CONFIG_KNOWN_BOOTSTRAP_PEERS_IDS = [
|
|
|
45
46
|
'12D3KooWS79EhkPU7ESUwgG4vyHHzW9FDNZLoWVth9b5N5NSrvaj',
|
|
46
47
|
'12D3KooWBbkCD5MpJhMc1mfPAVGEyVkQnyxPKGS7AHwDqQM2JUsk',
|
|
47
48
|
'12D3KooWKLdecs31Zmo2pLBjR9HY2vWo3VwM4eBm21Czeucbe6FL',
|
|
48
|
-
'12D3KooWBdF3g6vSJFRPoZQo7BNnkNzaWb59gpyaVzsgtNTVeu8H'
|
|
49
|
-
'12D3KooWFhXabKDwALpzqMbto94sB7rvmZ6M28hs9Y9xSopDKwQr'
|
|
49
|
+
'12D3KooWBdF3g6vSJFRPoZQo7BNnkNzaWb59gpyaVzsgtNTVeu8H'
|
|
50
50
|
];
|
|
51
51
|
|
|
52
52
|
const CONFIG_KNOWN_BOOTSTRAP_HYBRID_IDS = [
|
|
53
53
|
'12D3KooWFhXabKDwALpzqMbto94sB7rvmZ6M28hs9Y9xSopDKwQr'
|
|
54
|
+
];
|
|
55
|
+
|
|
56
|
+
const CONFIG_KNOWN_BOOTSTRAP_PEERS_IDS = CONFIG_KNOWN_BOOTSTRAP_PUBLIC_IDS.concat(CONFIG_KNOWN_BOOTSTRAP_HYBRID_IDS);
|
|
57
|
+
|
|
58
|
+
const CONFIG_KNOWN_BOOTSTRAP_PEERS_ADDRS = [
|
|
54
59
|
];
|
|
55
60
|
|
|
56
61
|
/* eslint-disable import/export */
|
|
@@ -242,16 +247,16 @@ function metrics(data){
|
|
|
242
247
|
fail = errors+timeouts;
|
|
243
248
|
const treshold = errors+timeouts+stats.open+stats.pending;
|
|
244
249
|
|
|
245
|
-
if(treshold>
|
|
250
|
+
if(treshold>30){
|
|
246
251
|
//console.log(`Treeshold hit : ${treshold}`)
|
|
247
252
|
}
|
|
248
253
|
|
|
249
|
-
if(fail>
|
|
254
|
+
if(fail>30){
|
|
250
255
|
//console.log(`Open : ${stats.open} , Pending : ${stats.pending} , Succes : ${totals.success} , Fail : ${fail} `)
|
|
251
256
|
|
|
252
257
|
}
|
|
253
258
|
|
|
254
|
-
if ((fail-lastfailtreshold)>
|
|
259
|
+
if ((fail-lastfailtreshold)>30){
|
|
255
260
|
if(isDialEnabled){
|
|
256
261
|
isDialEnabled = false;
|
|
257
262
|
const str = JSON.stringify({isDialEnabled,fail,lastfailtreshold});
|
|
@@ -332,6 +337,9 @@ class webpeerjs{
|
|
|
332
337
|
//message tracker avoid double
|
|
333
338
|
#msgIdtracker
|
|
334
339
|
|
|
340
|
+
//map of peer exchange data
|
|
341
|
+
#peerexchangedata
|
|
342
|
+
|
|
335
343
|
id
|
|
336
344
|
status
|
|
337
345
|
IPFS
|
|
@@ -360,6 +368,7 @@ class webpeerjs{
|
|
|
360
368
|
this.#dialQueue = [];
|
|
361
369
|
this.#isDialEnabled = true;
|
|
362
370
|
this.#msgIdtracker = [];
|
|
371
|
+
this.#peerexchangedata = new Map();
|
|
363
372
|
|
|
364
373
|
this.peers = (function(f) {
|
|
365
374
|
return f
|
|
@@ -368,6 +377,8 @@ class webpeerjs{
|
|
|
368
377
|
this.status = (function(libp2p) {
|
|
369
378
|
return libp2p.status
|
|
370
379
|
})(this.#libp2p);
|
|
380
|
+
|
|
381
|
+
this.status = 'unconnected';
|
|
371
382
|
|
|
372
383
|
this.IPFS = (function(libp2p,discoveredPeers) {
|
|
373
384
|
const obj = {libp2p,discoveredPeers};
|
|
@@ -389,7 +400,7 @@ class webpeerjs{
|
|
|
389
400
|
const connect = connections.find((con)=>con.id == id);
|
|
390
401
|
const addr = connect.addr;
|
|
391
402
|
|
|
392
|
-
if(CONFIG_KNOWN_BOOTSTRAP_PEERS_IDS.includes(id)
|
|
403
|
+
if(CONFIG_KNOWN_BOOTSTRAP_PEERS_IDS.includes(id)){
|
|
393
404
|
if(!this.#connections.has(id)&&addr.includes('webtransport')){
|
|
394
405
|
await this.#dbstore.put(new Key(id), new TextEncoder().encode(addr));
|
|
395
406
|
}
|
|
@@ -423,11 +434,7 @@ class webpeerjs{
|
|
|
423
434
|
const now = new Date().getTime();
|
|
424
435
|
const metadata = {addrs:address,last:now};
|
|
425
436
|
this.#connectedPeers.set(id,metadata);
|
|
426
|
-
this.#
|
|
427
|
-
for(const peer of this.#connectedPeers){
|
|
428
|
-
const item = {id:peer[0],address:peer[1].addrs};
|
|
429
|
-
this.#connectedPeersArr.push(item);
|
|
430
|
-
}
|
|
437
|
+
this.#updatePeers();
|
|
431
438
|
}
|
|
432
439
|
|
|
433
440
|
}
|
|
@@ -468,11 +475,7 @@ class webpeerjs{
|
|
|
468
475
|
const now = new Date().getTime();
|
|
469
476
|
const metadata = {addrs:address,last:now};
|
|
470
477
|
this.#connectedPeers.set(senderPeerId,metadata);
|
|
471
|
-
this.#
|
|
472
|
-
for(const peer of this.#connectedPeers){
|
|
473
|
-
const item = {id:peer[0],address:peer[1].addrs};
|
|
474
|
-
this.#connectedPeersArr.push(item);
|
|
475
|
-
}
|
|
478
|
+
this.#updatePeers();
|
|
476
479
|
}
|
|
477
480
|
|
|
478
481
|
//dial if not connected
|
|
@@ -536,11 +539,7 @@ class webpeerjs{
|
|
|
536
539
|
const metadata = {addrs:address,last:now};
|
|
537
540
|
this.#connectedPeers.set(id,metadata);
|
|
538
541
|
this.#webPeersAddrs.set(id,address);
|
|
539
|
-
this.#
|
|
540
|
-
for(const peer of this.#connectedPeers){
|
|
541
|
-
const item = {id:peer[0],address:peer[1].addrs};
|
|
542
|
-
this.#connectedPeersArr.push(item);
|
|
543
|
-
}
|
|
542
|
+
this.#updatePeers();
|
|
544
543
|
}
|
|
545
544
|
|
|
546
545
|
|
|
@@ -586,17 +585,6 @@ class webpeerjs{
|
|
|
586
585
|
if(signal == 'ping'){
|
|
587
586
|
//console.log('rooms',rooms)
|
|
588
587
|
}
|
|
589
|
-
|
|
590
|
-
//update connected webpeers
|
|
591
|
-
/*const now = new Date().getTime()
|
|
592
|
-
const metadata = {addrs:address,last:now}
|
|
593
|
-
this.#connectedPeers.set(id,metadata)
|
|
594
|
-
this.#webPeersAddrs.set(id,address)
|
|
595
|
-
this.#connectedPeersArr.length = 0
|
|
596
|
-
for(const peer of this.#connectedPeers){
|
|
597
|
-
const item = {id:peer[0],address:peer[1].addrs}
|
|
598
|
-
this.#connectedPeersArr.push(item)
|
|
599
|
-
}*/
|
|
600
588
|
|
|
601
589
|
}
|
|
602
590
|
}
|
|
@@ -673,9 +661,8 @@ class webpeerjs{
|
|
|
673
661
|
count++;
|
|
674
662
|
this.#trackDisconnect.set(id,count);
|
|
675
663
|
//console.log(this.#trackDisconnect)
|
|
676
|
-
if(count>
|
|
664
|
+
if(count>10){
|
|
677
665
|
if(this.#dbstoreData.has(id)){
|
|
678
|
-
//await this.#dbstore.delete(new Key(id))
|
|
679
666
|
this.#dbstoreData.delete(id);
|
|
680
667
|
}
|
|
681
668
|
|
|
@@ -688,6 +675,11 @@ class webpeerjs{
|
|
|
688
675
|
this.#trackDisconnect.set(id,0);
|
|
689
676
|
}
|
|
690
677
|
|
|
678
|
+
let peerexchangelist = [];
|
|
679
|
+
for(const peer of this.#peerexchangedata.values()){
|
|
680
|
+
peerexchangelist.push(peer.id);
|
|
681
|
+
}
|
|
682
|
+
|
|
691
683
|
//if this disconnected peer is web peer redial it
|
|
692
684
|
if(this.#webPeersId.includes(id)){
|
|
693
685
|
const addr = this.#connections.get(id);
|
|
@@ -705,6 +697,14 @@ class webpeerjs{
|
|
|
705
697
|
mddrs.push(addrs);
|
|
706
698
|
this.#dialMultiaddress(mddrs);
|
|
707
699
|
}
|
|
700
|
+
|
|
701
|
+
else if(peerexchangelist.includes(id)){
|
|
702
|
+
const addr = this.#connections.get(id);
|
|
703
|
+
let mddrs = [];
|
|
704
|
+
const addrs = multiaddr(addr);
|
|
705
|
+
mddrs.push(addrs);
|
|
706
|
+
this.#dialMultiaddress(mddrs);
|
|
707
|
+
}
|
|
708
708
|
|
|
709
709
|
//redial if this disconnected peer is regular peer
|
|
710
710
|
else {
|
|
@@ -735,38 +735,30 @@ class webpeerjs{
|
|
|
735
735
|
this.#libp2p.addEventListener('peer:identify', (evt) => {
|
|
736
736
|
//console.log('peer:identify '+evt.detail.peerId.toString(),evt.detail)
|
|
737
737
|
if(evt.detail.protocols.includes(CONFIG_PROTOCOL)){
|
|
738
|
-
//console.log('peer:identify '+evt.detail.peerId.toString(),evt
|
|
738
|
+
//console.log('peer:identify '+evt.detail.peerId.toString(),evt)
|
|
739
739
|
|
|
740
740
|
const id = evt.detail.peerId.toString();
|
|
741
741
|
let address = [];
|
|
742
742
|
|
|
743
743
|
for(const addrs of evt.detail.listenAddrs){
|
|
744
744
|
const addr = addrs.toString()+'/p2p/'+id;
|
|
745
|
+
multiaddr(addr);
|
|
745
746
|
if(addr.includes('webtransport')){
|
|
746
747
|
address.push(addr);
|
|
747
748
|
}
|
|
748
749
|
}
|
|
749
750
|
|
|
750
|
-
if(!this.#webPeersId.includes(id))this.#webPeersId.push(id);
|
|
751
|
-
|
|
752
751
|
if(this.#connectedPeers.has(id)){
|
|
753
752
|
//reset this last seen
|
|
754
753
|
const now = new Date().getTime();
|
|
755
754
|
const metadata = {addrs:address,last:now};
|
|
756
755
|
this.#connectedPeers.set(id,metadata);
|
|
757
756
|
}
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
this.#connectedPeers.set(id,metadata);
|
|
764
|
-
this.#connectedPeersArr.length = 0;
|
|
765
|
-
for(const peer of this.#connectedPeers){
|
|
766
|
-
const item = {id:peer[0],address:peer[1].addrs};
|
|
767
|
-
this.#connectedPeersArr.push(item);
|
|
768
|
-
}
|
|
769
|
-
}
|
|
757
|
+
|
|
758
|
+
|
|
759
|
+
const command = 'peer-exchange';
|
|
760
|
+
this.#dialProtocol(id,command);
|
|
761
|
+
|
|
770
762
|
|
|
771
763
|
}
|
|
772
764
|
});
|
|
@@ -847,28 +839,178 @@ class webpeerjs{
|
|
|
847
839
|
|
|
848
840
|
//Listen on new peer connection
|
|
849
841
|
#onConnectFn = () => {}
|
|
850
|
-
|
|
842
|
+
onConnect = f => (this.#onConnectFn = f)
|
|
851
843
|
|
|
852
844
|
|
|
853
845
|
//Listen on peer disconnect
|
|
854
846
|
#onDisconnectFn = () => {}
|
|
855
|
-
|
|
847
|
+
onDisconnect = f => (this.#onDisconnectFn = f)
|
|
848
|
+
|
|
849
|
+
joinRoom = room => {
|
|
850
|
+
if (this.#rooms[room]) {
|
|
851
|
+
return [
|
|
852
|
+
this.#rooms[room].sendMessage,
|
|
853
|
+
this.#rooms[room].listenMessage,
|
|
854
|
+
this.#rooms[room].onMembersChange
|
|
855
|
+
]
|
|
856
|
+
|
|
856
857
|
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
if (!room) {
|
|
861
|
+
throw mkErr('room is required')
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
//join room version 1 user pupsub via pupsub peer discovery
|
|
865
|
+
{
|
|
857
866
|
|
|
867
|
+
const topics = CONFIG_PUBSUB_PEER_DISCOVERY;
|
|
868
|
+
|
|
869
|
+
this.#rooms[room] = {
|
|
870
|
+
onMessage : () => {},
|
|
871
|
+
listenMessage : f => (this.#rooms[room] = {...this.#rooms[room], onMessage: f}),
|
|
872
|
+
sendMessage : async (message) => {
|
|
873
|
+
const msgId = (new Date()).getTime();
|
|
874
|
+
const data = JSON.stringify({prefix:CONFIG_PREFIX,room,message,id:this.#libp2p.peerId.toString(),msgId});
|
|
875
|
+
const peer = {
|
|
876
|
+
publicKey: this.#libp2p.peerId.publicKey,
|
|
877
|
+
addrs: [uint8ArrayFromString(data)],
|
|
878
|
+
};
|
|
879
|
+
const encodedPeer = Peer.encode(peer);
|
|
880
|
+
for(const topic of topics){
|
|
881
|
+
await this.#libp2p.services.pubsub.publish(topic, encodedPeer);
|
|
882
|
+
}
|
|
883
|
+
},
|
|
884
|
+
members : [this.id],
|
|
885
|
+
onMembers : () => {},
|
|
886
|
+
onMembersChange : f => {this.#rooms[room] = {...this.#rooms[room], onMembers: f};this.#rooms[room].onMembers(this.#rooms[room].members);this.#ping();},
|
|
887
|
+
};
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
return [
|
|
891
|
+
this.#rooms[room].sendMessage,
|
|
892
|
+
this.#rooms[room].listenMessage,
|
|
893
|
+
this.#rooms[room].onMembersChange
|
|
894
|
+
]
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
dial(addr){
|
|
898
|
+
let mddrs = [];
|
|
899
|
+
const mddr = multiaddr(addr);
|
|
900
|
+
mddrs.push(mddr);
|
|
901
|
+
this.#dialMultiaddress(mddrs);
|
|
902
|
+
}
|
|
858
903
|
|
|
859
904
|
|
|
860
905
|
/*
|
|
861
906
|
PRIVATE FUNCTION
|
|
862
907
|
*/
|
|
908
|
+
|
|
909
|
+
#updatePeers(){
|
|
910
|
+
this.#connectedPeersArr.length = 0;
|
|
911
|
+
for(const peer of this.#connectedPeers){
|
|
912
|
+
const item = {id:peer[0],address:peer[1].addrs};
|
|
913
|
+
this.#connectedPeersArr.push(item);
|
|
914
|
+
}
|
|
915
|
+
if(this.#connectedPeers.size > 0){
|
|
916
|
+
this.status = 'connected';
|
|
917
|
+
}
|
|
918
|
+
else {
|
|
919
|
+
this.status = 'unconnected';
|
|
920
|
+
}
|
|
921
|
+
}
|
|
863
922
|
|
|
864
923
|
async #registerProtocol(){
|
|
865
|
-
|
|
866
|
-
|
|
924
|
+
|
|
925
|
+
const handler = async ({ connection, stream, protocol }) => {
|
|
926
|
+
try{
|
|
927
|
+
const output = await pipe(
|
|
928
|
+
stream.source,
|
|
929
|
+
(source) => lp.decode(source),
|
|
930
|
+
(source) => map(source, (buf) => uint8ArrayToString(buf.subarray())),
|
|
931
|
+
async function (source) {
|
|
932
|
+
let string = '';
|
|
933
|
+
for await (const msg of source) {
|
|
934
|
+
string += msg.toString();
|
|
935
|
+
}
|
|
936
|
+
return string
|
|
937
|
+
}
|
|
938
|
+
);
|
|
939
|
+
|
|
940
|
+
const id = connection.remotePeer.toString();
|
|
941
|
+
|
|
942
|
+
let json = JSON.parse(output);
|
|
943
|
+
|
|
944
|
+
let jsonMessage = {
|
|
945
|
+
protocol:CONFIG_PROTOCOL,
|
|
946
|
+
command:null,
|
|
947
|
+
data:null
|
|
948
|
+
};
|
|
949
|
+
|
|
950
|
+
if(json.command === 'peer-exchange'){
|
|
951
|
+
|
|
952
|
+
if(json.protocol == CONFIG_PROTOCOL){
|
|
953
|
+
const address = [connection.remoteAddr.toString()];
|
|
954
|
+
if(this.#connectedPeers.has(id)){
|
|
955
|
+
//reset this last seen
|
|
956
|
+
const now = new Date().getTime();
|
|
957
|
+
const metadata = {addrs:address,last:now};
|
|
958
|
+
this.#connectedPeers.set(id,metadata);
|
|
959
|
+
}
|
|
960
|
+
else {
|
|
961
|
+
if(!this.#webPeersId.includes(id))this.#webPeersId.push(id);
|
|
962
|
+
|
|
963
|
+
//add to connected webpeers
|
|
964
|
+
this.#onConnectFn(id);
|
|
965
|
+
const now = new Date().getTime();
|
|
966
|
+
const metadata = {addrs:address,last:now};
|
|
967
|
+
this.#connectedPeers.set(id,metadata);
|
|
968
|
+
this.#updatePeers();
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
if(json.data != null){
|
|
973
|
+
this.#peerexchangedata.set(id,json.data);
|
|
974
|
+
let mddrs = [];
|
|
975
|
+
const dataaddr = json.data.addr;
|
|
976
|
+
const datamddr = multiaddr(dataaddr);
|
|
977
|
+
const dataid = json.data.id;
|
|
978
|
+
mddrs.push(datamddr);
|
|
979
|
+
this.#dialMultiaddress(mddrs);
|
|
980
|
+
if(!this.#dbstoreData.has(dataid)){
|
|
981
|
+
//await this.#dbstore.put(new Key(dataid), new TextEncoder().encode(dataaddr))
|
|
982
|
+
//this.#dbstoreData.set(dataid,dataaddr)
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
const keys = Array.from(this.#dbstoreData.keys());
|
|
987
|
+
const randomKey = Math.floor(Math.random() * keys.length);
|
|
988
|
+
const key = keys[randomKey];
|
|
989
|
+
const addr = this.#dbstoreData.get(key);
|
|
990
|
+
|
|
991
|
+
jsonMessage.command = json.command;
|
|
992
|
+
jsonMessage.data = {id:key,addr};
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
const message = JSON.stringify(jsonMessage);
|
|
996
|
+
//console.log('answer message '+id,message)
|
|
997
|
+
|
|
998
|
+
pipe(
|
|
999
|
+
message,
|
|
1000
|
+
(source) => map(source, (string) => uint8ArrayFromString(string)),
|
|
1001
|
+
(source) => lp.encode(source),
|
|
1002
|
+
stream.sink
|
|
1003
|
+
);
|
|
1004
|
+
}
|
|
1005
|
+
catch(err){
|
|
1006
|
+
//console.warn(err)
|
|
1007
|
+
}
|
|
867
1008
|
};
|
|
868
1009
|
|
|
869
1010
|
await this.#libp2p.handle(CONFIG_PROTOCOL, handler, {
|
|
870
|
-
maxInboundStreams:
|
|
871
|
-
maxOutboundStreams:
|
|
1011
|
+
maxInboundStreams: 50,
|
|
1012
|
+
maxOutboundStreams: 50,
|
|
1013
|
+
runOnTransientConnection:true
|
|
872
1014
|
});
|
|
873
1015
|
|
|
874
1016
|
await this.#libp2p.register(CONFIG_PROTOCOL, {
|
|
@@ -884,6 +1026,96 @@ class webpeerjs{
|
|
|
884
1026
|
|
|
885
1027
|
}
|
|
886
1028
|
|
|
1029
|
+
async #dialProtocol(id,command){
|
|
1030
|
+
|
|
1031
|
+
const connections = this.#libp2p.getConnections().map((con)=>{return {id:con.remotePeer.toString(),addr:con.remoteAddr.toString()}});
|
|
1032
|
+
const connect = connections.find((con)=>con.id == id);
|
|
1033
|
+
const addr = connect.addr;
|
|
1034
|
+
const mddr = multiaddr(addr);
|
|
1035
|
+
|
|
1036
|
+
let jsonMessage = {
|
|
1037
|
+
protocol:CONFIG_PROTOCOL,
|
|
1038
|
+
command:null,
|
|
1039
|
+
data:null
|
|
1040
|
+
};
|
|
1041
|
+
|
|
1042
|
+
if(command === 'peer-exchange'){
|
|
1043
|
+
|
|
1044
|
+
if(this.#peerexchangedata.has(id))return
|
|
1045
|
+
|
|
1046
|
+
const keys = Array.from(this.#dbstoreData.keys());
|
|
1047
|
+
const randomKey = Math.floor(Math.random() * keys.length);
|
|
1048
|
+
const key = keys[randomKey];
|
|
1049
|
+
const addr = this.#dbstoreData.get(key);
|
|
1050
|
+
|
|
1051
|
+
jsonMessage.command = command;
|
|
1052
|
+
jsonMessage.data = {id:key,addr};
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
const message = JSON.stringify(jsonMessage);
|
|
1056
|
+
//console.log('ask message '+id,message)
|
|
1057
|
+
|
|
1058
|
+
try{
|
|
1059
|
+
|
|
1060
|
+
const stream = await this.#libp2p.dialProtocol(mddr, CONFIG_PROTOCOL,{runOnTransientConnection:true});
|
|
1061
|
+
|
|
1062
|
+
const output = await pipe(
|
|
1063
|
+
message,
|
|
1064
|
+
(source) => map(source, (string) => uint8ArrayFromString(string)),
|
|
1065
|
+
(source) => lp.encode(source),
|
|
1066
|
+
stream,
|
|
1067
|
+
(source) => lp.decode(source),
|
|
1068
|
+
(source) => map(source, (buf) => uint8ArrayToString(buf.subarray())),
|
|
1069
|
+
async function (source) {
|
|
1070
|
+
let string = '';
|
|
1071
|
+
for await (const msg of source) {
|
|
1072
|
+
string += msg.toString();
|
|
1073
|
+
}
|
|
1074
|
+
return string
|
|
1075
|
+
}
|
|
1076
|
+
);
|
|
1077
|
+
|
|
1078
|
+
const json = JSON.parse(output);
|
|
1079
|
+
if(json.protocol == CONFIG_PROTOCOL){
|
|
1080
|
+
const address = [addr];
|
|
1081
|
+
if(this.#connectedPeers.has(id)){
|
|
1082
|
+
//reset this last seen
|
|
1083
|
+
const now = new Date().getTime();
|
|
1084
|
+
const metadata = {addrs:address,last:now};
|
|
1085
|
+
this.#connectedPeers.set(id,metadata);
|
|
1086
|
+
}
|
|
1087
|
+
else {
|
|
1088
|
+
if(!this.#webPeersId.includes(id))this.#webPeersId.push(id);
|
|
1089
|
+
|
|
1090
|
+
//add to connected webpeers
|
|
1091
|
+
this.#onConnectFn(id);
|
|
1092
|
+
const now = new Date().getTime();
|
|
1093
|
+
const metadata = {addrs:address,last:now};
|
|
1094
|
+
this.#connectedPeers.set(id,metadata);
|
|
1095
|
+
this.#updatePeers();
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
if(json.command == 'peer-exchange'){
|
|
1099
|
+
if(json.data != null){
|
|
1100
|
+
this.#peerexchangedata.set(id,json.data);
|
|
1101
|
+
let mddrs = [];
|
|
1102
|
+
const dataaddr = json.data.addr;
|
|
1103
|
+
const datamddr = multiaddr(dataaddr);
|
|
1104
|
+
const dataid = json.data.id;
|
|
1105
|
+
mddrs.push(datamddr);
|
|
1106
|
+
this.#dialMultiaddress(mddrs);
|
|
1107
|
+
if(!this.#dbstoreData.has(dataid)){
|
|
1108
|
+
//await this.#dbstore.put(new Key(dataid), new TextEncoder().encode(dataaddr))
|
|
1109
|
+
//this.#dbstoreData.set(dataid,dataaddr)
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
catch(err){
|
|
1115
|
+
//console.warn(err)
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
|
|
887
1119
|
#findHybridPeer(){
|
|
888
1120
|
setTimeout(async()=>{
|
|
889
1121
|
for(const target of CONFIG_KNOWN_BOOTSTRAP_HYBRID_IDS){
|
|
@@ -921,6 +1153,7 @@ class webpeerjs{
|
|
|
921
1153
|
//check the last seen in web peer
|
|
922
1154
|
#trackLastSeen(){
|
|
923
1155
|
const timeout = 25*1000;
|
|
1156
|
+
const forcetimeout = 60*1000;
|
|
924
1157
|
const now = new Date().getTime();
|
|
925
1158
|
|
|
926
1159
|
//if webpeer last seen grather then timeout send onDisconnect
|
|
@@ -928,13 +1161,10 @@ class webpeerjs{
|
|
|
928
1161
|
const id = peer[0];
|
|
929
1162
|
const last = peer[1].last;
|
|
930
1163
|
const time = now-last;
|
|
931
|
-
if(time>timeout){
|
|
1164
|
+
if((time>timeout && !this.#isConnected(id))||(time>forcetimeout)){
|
|
1165
|
+
|
|
932
1166
|
this.#connectedPeers.delete(id);
|
|
933
|
-
this.#
|
|
934
|
-
for(const peer of this.#connectedPeers){
|
|
935
|
-
const item = {id:peer[0],address:peer[1].addrs};
|
|
936
|
-
this.#connectedPeersArr.push(item);
|
|
937
|
-
}
|
|
1167
|
+
this.#updatePeers();
|
|
938
1168
|
this.#onDisconnectFn(id);
|
|
939
1169
|
|
|
940
1170
|
//remove id from room member
|
|
@@ -946,6 +1176,7 @@ class webpeerjs{
|
|
|
946
1176
|
this.#rooms[room].onMembers(this.#rooms[room].members);
|
|
947
1177
|
}
|
|
948
1178
|
}
|
|
1179
|
+
|
|
949
1180
|
}
|
|
950
1181
|
}
|
|
951
1182
|
}
|
|
@@ -971,13 +1202,25 @@ class webpeerjs{
|
|
|
971
1202
|
|
|
972
1203
|
const id = mddrs[0].toString().split('/').pop();
|
|
973
1204
|
|
|
974
|
-
const
|
|
1205
|
+
const queueids = this.#dialQueue.map((arr)=> arr[0].toString().split('/').pop());
|
|
975
1206
|
|
|
976
1207
|
//if peer id is already in the queque cancel queque
|
|
977
|
-
if(
|
|
1208
|
+
if(queueids.includes(id)){
|
|
978
1209
|
return
|
|
979
1210
|
}
|
|
980
1211
|
|
|
1212
|
+
const webPeerCount = this.#connectedPeers.size;
|
|
1213
|
+
const allPeerCount = this.#libp2p.getPeers().length;
|
|
1214
|
+
const nodePeerCount = allPeerCount - webPeerCount;
|
|
1215
|
+
const limitCount = CONFIG_MAX_CONNECTIONS / 2;
|
|
1216
|
+
|
|
1217
|
+
if(this.#webPeersId.includes(id)){
|
|
1218
|
+
if(webPeerCount>limitCount)return
|
|
1219
|
+
}
|
|
1220
|
+
else {
|
|
1221
|
+
if(nodePeerCount>limitCount)return
|
|
1222
|
+
}
|
|
1223
|
+
|
|
981
1224
|
if(this.#webPeersId.includes(id) || CONFIG_KNOWN_BOOTSTRAP_PEERS_IDS.includes(id) || CONFIG_KNOWN_BOOTSTRAP_HYBRID_IDS.includes(id)){
|
|
982
1225
|
this.#dialQueue.unshift(mddrs);
|
|
983
1226
|
}
|
|
@@ -991,7 +1234,7 @@ class webpeerjs{
|
|
|
991
1234
|
//dial multiaddr address in queue list
|
|
992
1235
|
#dialQueueList(){
|
|
993
1236
|
|
|
994
|
-
if(!this.#isDialEnabled)return
|
|
1237
|
+
if(!this.#isDialEnabled || !navigator.onLine)return
|
|
995
1238
|
|
|
996
1239
|
const mddrsToDial = 5;
|
|
997
1240
|
|
|
@@ -1056,55 +1299,6 @@ class webpeerjs{
|
|
|
1056
1299
|
await this.#libp2p.services.pubsub.publish(topic, encodedPeer);
|
|
1057
1300
|
}
|
|
1058
1301
|
}
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
joinRoom = room => {
|
|
1062
|
-
if (this.#rooms[room]) {
|
|
1063
|
-
return [
|
|
1064
|
-
this.#rooms[room].sendMessage,
|
|
1065
|
-
this.#rooms[room].listenMessage,
|
|
1066
|
-
this.#rooms[room].onMembersChange
|
|
1067
|
-
]
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
}
|
|
1071
|
-
|
|
1072
|
-
if (!room) {
|
|
1073
|
-
throw mkErr('room is required')
|
|
1074
|
-
}
|
|
1075
|
-
|
|
1076
|
-
//join room version 1 user pupsub via pupsub peer discovery
|
|
1077
|
-
{
|
|
1078
|
-
|
|
1079
|
-
const topics = CONFIG_PUBSUB_PEER_DISCOVERY;
|
|
1080
|
-
|
|
1081
|
-
this.#rooms[room] = {
|
|
1082
|
-
onMessage : () => {},
|
|
1083
|
-
listenMessage : f => (this.#rooms[room] = {...this.#rooms[room], onMessage: f}),
|
|
1084
|
-
sendMessage : async (message) => {
|
|
1085
|
-
const msgId = (new Date()).getTime();
|
|
1086
|
-
const data = JSON.stringify({prefix:CONFIG_PREFIX,room,message,id:this.#libp2p.peerId.toString(),msgId});
|
|
1087
|
-
const peer = {
|
|
1088
|
-
publicKey: this.#libp2p.peerId.publicKey,
|
|
1089
|
-
addrs: [uint8ArrayFromString(data)],
|
|
1090
|
-
};
|
|
1091
|
-
const encodedPeer = Peer.encode(peer);
|
|
1092
|
-
for(const topic of topics){
|
|
1093
|
-
await this.#libp2p.services.pubsub.publish(topic, encodedPeer);
|
|
1094
|
-
}
|
|
1095
|
-
},
|
|
1096
|
-
members : [this.id],
|
|
1097
|
-
onMembers : () => {},
|
|
1098
|
-
onMembersChange : f => {this.#rooms[room] = {...this.#rooms[room], onMembers: f};this.#rooms[room].onMembers(this.#rooms[room].members);this.#ping();},
|
|
1099
|
-
};
|
|
1100
|
-
}
|
|
1101
|
-
|
|
1102
|
-
return [
|
|
1103
|
-
this.#rooms[room].sendMessage,
|
|
1104
|
-
this.#rooms[room].listenMessage,
|
|
1105
|
-
this.#rooms[room].onMembersChange
|
|
1106
|
-
]
|
|
1107
|
-
}
|
|
1108
1302
|
|
|
1109
1303
|
|
|
1110
1304
|
//dial discovered peers
|
|
@@ -1207,8 +1401,7 @@ class webpeerjs{
|
|
|
1207
1401
|
if(besttime>bestlimit){
|
|
1208
1402
|
const addr = remote.toString();
|
|
1209
1403
|
const id = peer.toString();
|
|
1210
|
-
if(!this.#webPeersId.includes(id) && !CONFIG_KNOWN_BOOTSTRAP_PEERS_IDS.includes(id) && !this.#dbstoreData.
|
|
1211
|
-
//await this.#dbstore.delete(new Key(id))
|
|
1404
|
+
if(!this.#webPeersId.includes(id) && !CONFIG_KNOWN_BOOTSTRAP_PEERS_IDS.includes(id) && !this.#dbstoreData.has(id) && !addr.includes('p2p-circuit') && addr.includes('webtransport')){
|
|
1212
1405
|
await this.#dbstore.put(new Key(id), new TextEncoder().encode(addr));
|
|
1213
1406
|
this.#dbstoreData.set(id,addr);
|
|
1214
1407
|
}
|
|
@@ -1223,26 +1416,31 @@ class webpeerjs{
|
|
|
1223
1416
|
}
|
|
1224
1417
|
|
|
1225
1418
|
|
|
1226
|
-
let peers = [];
|
|
1227
|
-
for(const peer of this.#libp2p.getPeers()){
|
|
1228
|
-
peers.push(peer.toString());
|
|
1229
|
-
}
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
1419
|
//connect to saved best peer address
|
|
1233
1420
|
//working great
|
|
1234
1421
|
for(const peer of this.#dbstoreData){
|
|
1235
1422
|
const id = peer[0];
|
|
1236
1423
|
const addr = peer[1];
|
|
1237
|
-
if(
|
|
1424
|
+
if(this.#isConnected(id)){
|
|
1238
1425
|
this.#connectionTrackerStore.set(id,0);
|
|
1239
1426
|
continue
|
|
1240
1427
|
}else {
|
|
1241
1428
|
if(this.#connectionTrackerStore.has(id)){
|
|
1242
1429
|
let current = this.#connectionTrackerStore.get(id);
|
|
1243
|
-
if(current>10)continue
|
|
1244
1430
|
current++;
|
|
1245
1431
|
this.#connectionTrackerStore.set(id,current);
|
|
1432
|
+
if(current>5){
|
|
1433
|
+
if(!this.#connections.has(id) && !CONFIG_KNOWN_BOOTSTRAP_PEERS_IDS.includes(id) && navigator.onLine)
|
|
1434
|
+
{
|
|
1435
|
+
setTimeout(async ()=> {
|
|
1436
|
+
if(this.#dbstoreData.has(id) && !this.#connections.has(id)){
|
|
1437
|
+
this.#dbstoreData.delete(id);
|
|
1438
|
+
await this.#dbstore.delete(new Key(id));
|
|
1439
|
+
}
|
|
1440
|
+
},60*1000);
|
|
1441
|
+
}
|
|
1442
|
+
continue
|
|
1443
|
+
}
|
|
1246
1444
|
}
|
|
1247
1445
|
else {
|
|
1248
1446
|
this.#connectionTrackerStore.set(id,0);
|
|
@@ -1257,7 +1455,7 @@ class webpeerjs{
|
|
|
1257
1455
|
//connect to good peer address if it is disconnected
|
|
1258
1456
|
const goods = Array.from(this.#dialedGoodPeers.keys());
|
|
1259
1457
|
for(const id of goods){
|
|
1260
|
-
if(
|
|
1458
|
+
if(this.#isConnected(id)){
|
|
1261
1459
|
this.#dialedGoodPeers.set(id,0);
|
|
1262
1460
|
continue
|
|
1263
1461
|
}
|
|
@@ -1326,6 +1524,10 @@ class webpeerjs{
|
|
|
1326
1524
|
|
|
1327
1525
|
//dial based on known bootsrap peers address
|
|
1328
1526
|
#dialKnownBootstrap(){
|
|
1527
|
+
|
|
1528
|
+
if(!navigator.onLine)return
|
|
1529
|
+
if(!this.#isDialEnabled)return
|
|
1530
|
+
|
|
1329
1531
|
const bootstrap = CONFIG_KNOWN_BOOTSTRAP_PEERS_ADDRS;
|
|
1330
1532
|
for(const peer of bootstrap){
|
|
1331
1533
|
const address = peer.Peers[0].Addrs;
|
|
@@ -1348,6 +1550,10 @@ class webpeerjs{
|
|
|
1348
1550
|
}
|
|
1349
1551
|
|
|
1350
1552
|
async #dialSavedKnownID(){
|
|
1553
|
+
|
|
1554
|
+
if(!navigator.onLine)return
|
|
1555
|
+
if(!this.#isDialEnabled)return
|
|
1556
|
+
|
|
1351
1557
|
let firsttime = true;
|
|
1352
1558
|
for(const target of CONFIG_KNOWN_BOOTSTRAP_PEERS_IDS){
|
|
1353
1559
|
if(this.#dbstoreData.has(target)){
|
|
@@ -1370,6 +1576,7 @@ class webpeerjs{
|
|
|
1370
1576
|
const api = CONFIG_DELEGATED_API;
|
|
1371
1577
|
const delegatedClient = createDelegatedRoutingV1HttpApiClient(api);
|
|
1372
1578
|
const peer = await first(delegatedClient.getPeers(peerIdFromString(target)));
|
|
1579
|
+
if(!peer)continue
|
|
1373
1580
|
const address = peer.Addrs;
|
|
1374
1581
|
const id = peer.ID;
|
|
1375
1582
|
let mddrs = [];
|
|
@@ -1390,12 +1597,26 @@ class webpeerjs{
|
|
|
1390
1597
|
}
|
|
1391
1598
|
|
|
1392
1599
|
async #dialUpdateSavedKnownID(){
|
|
1600
|
+
|
|
1601
|
+
if(!navigator.onLine)return
|
|
1602
|
+
if(!this.#isDialEnabled)return
|
|
1603
|
+
|
|
1604
|
+
let firsttime = true;
|
|
1393
1605
|
for(const target of CONFIG_KNOWN_BOOTSTRAP_PEERS_IDS){
|
|
1394
|
-
if(
|
|
1606
|
+
if(this.#dbstoreData.has(target)){
|
|
1607
|
+
firsttime = false;
|
|
1608
|
+
}
|
|
1609
|
+
if(!this.#connections.has(target) && (this.#dbstoreData.has(target) || firsttime)){
|
|
1395
1610
|
//console.log('#dialUpdateSavedKnownID()',target)
|
|
1396
1611
|
const api = CONFIG_DELEGATED_API;
|
|
1397
1612
|
const delegatedClient = createDelegatedRoutingV1HttpApiClient(api);
|
|
1398
1613
|
const peer = await first(delegatedClient.getPeers(peerIdFromString(target)));
|
|
1614
|
+
if(!peer){
|
|
1615
|
+
if (navigator.onLine) {
|
|
1616
|
+
await this.#dbstore.delete(new Key(target));
|
|
1617
|
+
}
|
|
1618
|
+
continue
|
|
1619
|
+
}
|
|
1399
1620
|
const address = peer.Addrs;
|
|
1400
1621
|
const id = peer.ID;
|
|
1401
1622
|
let mddrs = [];
|
|
@@ -1418,6 +1639,10 @@ class webpeerjs{
|
|
|
1418
1639
|
|
|
1419
1640
|
//dial based on known peers ID
|
|
1420
1641
|
async #dialKnownID(){
|
|
1642
|
+
|
|
1643
|
+
if(!navigator.onLine)return
|
|
1644
|
+
if(!this.#isDialEnabled)return
|
|
1645
|
+
|
|
1421
1646
|
//console.log('#dialKnownID()')
|
|
1422
1647
|
const api = CONFIG_DELEGATED_API;
|
|
1423
1648
|
const delegatedClient = createDelegatedRoutingV1HttpApiClient(api);
|