webpeerjs 0.0.8 → 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 +15 -5
- package/dist/esm/webpeerjs.d.ts +3 -2
- package/dist/esm/webpeerjs.js +321 -89
- package/dist/umd/webpeerjs.js +15280 -15052
- package/package.json +11 -14
- package/src/config.js +1 -1
- package/src/utils.js +19 -8
- package/src/webpeerjs.js +320 -86
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# WebpeerJS
|
|
2
|
-
> Simple peer-to-peer with [IPFS](https://ipfs.tech/). Build completely P2P web applications, no trackers or relay servers
|
|
2
|
+
> Simple peer-to-peer with [IPFS](https://ipfs.tech/). Build completely P2P web applications, no trackers or relay servers required.
|
|
3
3
|
|
|
4
4
|
WebpeerJS enables browser to browser connectivity without a central server.
|
|
5
5
|
|
|
@@ -9,6 +9,7 @@ WebpeerJS enables browser to browser connectivity without a central server.
|
|
|
9
9
|
|
|
10
10
|
* ✅ Decentralized Network
|
|
11
11
|
* ✅ Broadcast Message
|
|
12
|
+
* ✅ Works in The Browser
|
|
12
13
|
|
|
13
14
|
## Install
|
|
14
15
|
|
|
@@ -18,7 +19,7 @@ NPM :
|
|
|
18
19
|
npm i webpeerjs
|
|
19
20
|
```
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
Browser `<script>` tag :
|
|
22
23
|
|
|
23
24
|
```
|
|
24
25
|
<script src="https://cdn.jsdelivr.net/npm/webpeerjs@0.0/dist/umd/webpeerjs.min.js"></script>
|
|
@@ -53,9 +54,13 @@ void async function main() {
|
|
|
53
54
|
|
|
54
55
|
- `createWebpeer()` Create a new node.
|
|
55
56
|
- `id` The unique ID of the node as an identity in the global network.
|
|
56
|
-
- `joinRoom()` Adding the node to the room, returns an array of three functions (Broadcaster, onListenMessage, onMembersUpdate).
|
|
57
|
-
- `peers` Get all connected peers.
|
|
58
57
|
- `status` Get the node status, returns `connected` or `unconnected`.
|
|
58
|
+
- `peers` Get all connected peers.
|
|
59
|
+
- `joinRoom(namespace)` Join to the room, returns an array of three functions (Broadcaster, onListenBroadcast, onMembersUpdate).
|
|
60
|
+
|
|
61
|
+
## API Docs
|
|
62
|
+
|
|
63
|
+
[https://nuzulul.github.io/webpeerjs](https://nuzulul.github.io/webpeerjs)
|
|
59
64
|
|
|
60
65
|
## Related
|
|
61
66
|
|
|
@@ -63,6 +68,11 @@ void async function main() {
|
|
|
63
68
|
- [peerjs](https://github.com/peers/peerjs) - Simple peer-to-peer with WebRTC.
|
|
64
69
|
- [trystero](https://github.com/dmotz/trystero) - Build instant multiplayer webapps, no server required.
|
|
65
70
|
|
|
71
|
+
## License
|
|
72
|
+
|
|
73
|
+
MIT
|
|
74
|
+
|
|
66
75
|
## Maintainers
|
|
67
76
|
|
|
68
|
-
[Nuzulul Zulkarnain](https://github.com/nuzulul)
|
|
77
|
+
[Nuzulul Zulkarnain](https://github.com/nuzulul)
|
|
78
|
+
|
package/dist/esm/webpeerjs.d.ts
CHANGED
|
@@ -9,8 +9,9 @@ export class webpeerjs {
|
|
|
9
9
|
};
|
|
10
10
|
address: any[];
|
|
11
11
|
peers: any[];
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
onConnect: (f: any) => any;
|
|
13
|
+
onDisconnect: (f: any) => any;
|
|
14
14
|
joinRoom: (room: any) => any[];
|
|
15
|
+
dial(addr: any): void;
|
|
15
16
|
#private;
|
|
16
17
|
}
|
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;
|
|
@@ -243,16 +247,16 @@ function metrics(data){
|
|
|
243
247
|
fail = errors+timeouts;
|
|
244
248
|
const treshold = errors+timeouts+stats.open+stats.pending;
|
|
245
249
|
|
|
246
|
-
if(treshold>
|
|
250
|
+
if(treshold>30){
|
|
247
251
|
//console.log(`Treeshold hit : ${treshold}`)
|
|
248
252
|
}
|
|
249
253
|
|
|
250
|
-
if(fail>
|
|
254
|
+
if(fail>30){
|
|
251
255
|
//console.log(`Open : ${stats.open} , Pending : ${stats.pending} , Succes : ${totals.success} , Fail : ${fail} `)
|
|
252
256
|
|
|
253
257
|
}
|
|
254
258
|
|
|
255
|
-
if ((fail-lastfailtreshold)>
|
|
259
|
+
if ((fail-lastfailtreshold)>30){
|
|
256
260
|
if(isDialEnabled){
|
|
257
261
|
isDialEnabled = false;
|
|
258
262
|
const str = JSON.stringify({isDialEnabled,fail,lastfailtreshold});
|
|
@@ -333,6 +337,9 @@ class webpeerjs{
|
|
|
333
337
|
//message tracker avoid double
|
|
334
338
|
#msgIdtracker
|
|
335
339
|
|
|
340
|
+
//map of peer exchange data
|
|
341
|
+
#peerexchangedata
|
|
342
|
+
|
|
336
343
|
id
|
|
337
344
|
status
|
|
338
345
|
IPFS
|
|
@@ -361,6 +368,7 @@ class webpeerjs{
|
|
|
361
368
|
this.#dialQueue = [];
|
|
362
369
|
this.#isDialEnabled = true;
|
|
363
370
|
this.#msgIdtracker = [];
|
|
371
|
+
this.#peerexchangedata = new Map();
|
|
364
372
|
|
|
365
373
|
this.peers = (function(f) {
|
|
366
374
|
return f
|
|
@@ -392,7 +400,7 @@ class webpeerjs{
|
|
|
392
400
|
const connect = connections.find((con)=>con.id == id);
|
|
393
401
|
const addr = connect.addr;
|
|
394
402
|
|
|
395
|
-
if(CONFIG_KNOWN_BOOTSTRAP_PEERS_IDS.includes(id)
|
|
403
|
+
if(CONFIG_KNOWN_BOOTSTRAP_PEERS_IDS.includes(id)){
|
|
396
404
|
if(!this.#connections.has(id)&&addr.includes('webtransport')){
|
|
397
405
|
await this.#dbstore.put(new Key(id), new TextEncoder().encode(addr));
|
|
398
406
|
}
|
|
@@ -653,9 +661,8 @@ class webpeerjs{
|
|
|
653
661
|
count++;
|
|
654
662
|
this.#trackDisconnect.set(id,count);
|
|
655
663
|
//console.log(this.#trackDisconnect)
|
|
656
|
-
if(count>
|
|
664
|
+
if(count>10){
|
|
657
665
|
if(this.#dbstoreData.has(id)){
|
|
658
|
-
//await this.#dbstore.delete(new Key(id))
|
|
659
666
|
this.#dbstoreData.delete(id);
|
|
660
667
|
}
|
|
661
668
|
|
|
@@ -668,6 +675,11 @@ class webpeerjs{
|
|
|
668
675
|
this.#trackDisconnect.set(id,0);
|
|
669
676
|
}
|
|
670
677
|
|
|
678
|
+
let peerexchangelist = [];
|
|
679
|
+
for(const peer of this.#peerexchangedata.values()){
|
|
680
|
+
peerexchangelist.push(peer.id);
|
|
681
|
+
}
|
|
682
|
+
|
|
671
683
|
//if this disconnected peer is web peer redial it
|
|
672
684
|
if(this.#webPeersId.includes(id)){
|
|
673
685
|
const addr = this.#connections.get(id);
|
|
@@ -685,6 +697,14 @@ class webpeerjs{
|
|
|
685
697
|
mddrs.push(addrs);
|
|
686
698
|
this.#dialMultiaddress(mddrs);
|
|
687
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
|
+
}
|
|
688
708
|
|
|
689
709
|
//redial if this disconnected peer is regular peer
|
|
690
710
|
else {
|
|
@@ -715,34 +735,30 @@ class webpeerjs{
|
|
|
715
735
|
this.#libp2p.addEventListener('peer:identify', (evt) => {
|
|
716
736
|
//console.log('peer:identify '+evt.detail.peerId.toString(),evt.detail)
|
|
717
737
|
if(evt.detail.protocols.includes(CONFIG_PROTOCOL)){
|
|
718
|
-
//console.log('peer:identify '+evt.detail.peerId.toString(),evt
|
|
738
|
+
//console.log('peer:identify '+evt.detail.peerId.toString(),evt)
|
|
719
739
|
|
|
720
740
|
const id = evt.detail.peerId.toString();
|
|
721
741
|
let address = [];
|
|
722
742
|
|
|
723
743
|
for(const addrs of evt.detail.listenAddrs){
|
|
724
744
|
const addr = addrs.toString()+'/p2p/'+id;
|
|
745
|
+
multiaddr(addr);
|
|
725
746
|
if(addr.includes('webtransport')){
|
|
726
747
|
address.push(addr);
|
|
727
748
|
}
|
|
728
749
|
}
|
|
729
750
|
|
|
730
|
-
if(!this.#webPeersId.includes(id))this.#webPeersId.push(id);
|
|
731
|
-
|
|
732
751
|
if(this.#connectedPeers.has(id)){
|
|
733
752
|
//reset this last seen
|
|
734
753
|
const now = new Date().getTime();
|
|
735
754
|
const metadata = {addrs:address,last:now};
|
|
736
755
|
this.#connectedPeers.set(id,metadata);
|
|
737
756
|
}
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
this.#connectedPeers.set(id,metadata);
|
|
744
|
-
this.#updatePeers();
|
|
745
|
-
}
|
|
757
|
+
|
|
758
|
+
|
|
759
|
+
const command = 'peer-exchange';
|
|
760
|
+
this.#dialProtocol(id,command);
|
|
761
|
+
|
|
746
762
|
|
|
747
763
|
}
|
|
748
764
|
});
|
|
@@ -823,14 +839,67 @@ class webpeerjs{
|
|
|
823
839
|
|
|
824
840
|
//Listen on new peer connection
|
|
825
841
|
#onConnectFn = () => {}
|
|
826
|
-
|
|
842
|
+
onConnect = f => (this.#onConnectFn = f)
|
|
827
843
|
|
|
828
844
|
|
|
829
845
|
//Listen on peer disconnect
|
|
830
846
|
#onDisconnectFn = () => {}
|
|
831
|
-
|
|
847
|
+
onDisconnect = f => (this.#onDisconnectFn = f)
|
|
832
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
|
+
|
|
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
|
+
{
|
|
833
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
|
+
}
|
|
834
903
|
|
|
835
904
|
|
|
836
905
|
/*
|
|
@@ -852,13 +921,96 @@ class webpeerjs{
|
|
|
852
921
|
}
|
|
853
922
|
|
|
854
923
|
async #registerProtocol(){
|
|
855
|
-
|
|
856
|
-
|
|
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
|
+
}
|
|
857
1008
|
};
|
|
858
1009
|
|
|
859
1010
|
await this.#libp2p.handle(CONFIG_PROTOCOL, handler, {
|
|
860
|
-
maxInboundStreams:
|
|
861
|
-
maxOutboundStreams:
|
|
1011
|
+
maxInboundStreams: 50,
|
|
1012
|
+
maxOutboundStreams: 50,
|
|
1013
|
+
runOnTransientConnection:true
|
|
862
1014
|
});
|
|
863
1015
|
|
|
864
1016
|
await this.#libp2p.register(CONFIG_PROTOCOL, {
|
|
@@ -874,6 +1026,96 @@ class webpeerjs{
|
|
|
874
1026
|
|
|
875
1027
|
}
|
|
876
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
|
+
|
|
877
1119
|
#findHybridPeer(){
|
|
878
1120
|
setTimeout(async()=>{
|
|
879
1121
|
for(const target of CONFIG_KNOWN_BOOTSTRAP_HYBRID_IDS){
|
|
@@ -960,13 +1202,25 @@ class webpeerjs{
|
|
|
960
1202
|
|
|
961
1203
|
const id = mddrs[0].toString().split('/').pop();
|
|
962
1204
|
|
|
963
|
-
const
|
|
1205
|
+
const queueids = this.#dialQueue.map((arr)=> arr[0].toString().split('/').pop());
|
|
964
1206
|
|
|
965
1207
|
//if peer id is already in the queque cancel queque
|
|
966
|
-
if(
|
|
1208
|
+
if(queueids.includes(id)){
|
|
967
1209
|
return
|
|
968
1210
|
}
|
|
969
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
|
+
|
|
970
1224
|
if(this.#webPeersId.includes(id) || CONFIG_KNOWN_BOOTSTRAP_PEERS_IDS.includes(id) || CONFIG_KNOWN_BOOTSTRAP_HYBRID_IDS.includes(id)){
|
|
971
1225
|
this.#dialQueue.unshift(mddrs);
|
|
972
1226
|
}
|
|
@@ -980,7 +1234,7 @@ class webpeerjs{
|
|
|
980
1234
|
//dial multiaddr address in queue list
|
|
981
1235
|
#dialQueueList(){
|
|
982
1236
|
|
|
983
|
-
if(!this.#isDialEnabled)return
|
|
1237
|
+
if(!this.#isDialEnabled || !navigator.onLine)return
|
|
984
1238
|
|
|
985
1239
|
const mddrsToDial = 5;
|
|
986
1240
|
|
|
@@ -1045,55 +1299,6 @@ class webpeerjs{
|
|
|
1045
1299
|
await this.#libp2p.services.pubsub.publish(topic, encodedPeer);
|
|
1046
1300
|
}
|
|
1047
1301
|
}
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
joinRoom = room => {
|
|
1051
|
-
if (this.#rooms[room]) {
|
|
1052
|
-
return [
|
|
1053
|
-
this.#rooms[room].sendMessage,
|
|
1054
|
-
this.#rooms[room].listenMessage,
|
|
1055
|
-
this.#rooms[room].onMembersChange
|
|
1056
|
-
]
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
}
|
|
1060
|
-
|
|
1061
|
-
if (!room) {
|
|
1062
|
-
throw mkErr('room is required')
|
|
1063
|
-
}
|
|
1064
|
-
|
|
1065
|
-
//join room version 1 user pupsub via pupsub peer discovery
|
|
1066
|
-
{
|
|
1067
|
-
|
|
1068
|
-
const topics = CONFIG_PUBSUB_PEER_DISCOVERY;
|
|
1069
|
-
|
|
1070
|
-
this.#rooms[room] = {
|
|
1071
|
-
onMessage : () => {},
|
|
1072
|
-
listenMessage : f => (this.#rooms[room] = {...this.#rooms[room], onMessage: f}),
|
|
1073
|
-
sendMessage : async (message) => {
|
|
1074
|
-
const msgId = (new Date()).getTime();
|
|
1075
|
-
const data = JSON.stringify({prefix:CONFIG_PREFIX,room,message,id:this.#libp2p.peerId.toString(),msgId});
|
|
1076
|
-
const peer = {
|
|
1077
|
-
publicKey: this.#libp2p.peerId.publicKey,
|
|
1078
|
-
addrs: [uint8ArrayFromString(data)],
|
|
1079
|
-
};
|
|
1080
|
-
const encodedPeer = Peer.encode(peer);
|
|
1081
|
-
for(const topic of topics){
|
|
1082
|
-
await this.#libp2p.services.pubsub.publish(topic, encodedPeer);
|
|
1083
|
-
}
|
|
1084
|
-
},
|
|
1085
|
-
members : [this.id],
|
|
1086
|
-
onMembers : () => {},
|
|
1087
|
-
onMembersChange : f => {this.#rooms[room] = {...this.#rooms[room], onMembers: f};this.#rooms[room].onMembers(this.#rooms[room].members);this.#ping();},
|
|
1088
|
-
};
|
|
1089
|
-
}
|
|
1090
|
-
|
|
1091
|
-
return [
|
|
1092
|
-
this.#rooms[room].sendMessage,
|
|
1093
|
-
this.#rooms[room].listenMessage,
|
|
1094
|
-
this.#rooms[room].onMembersChange
|
|
1095
|
-
]
|
|
1096
|
-
}
|
|
1097
1302
|
|
|
1098
1303
|
|
|
1099
1304
|
//dial discovered peers
|
|
@@ -1196,8 +1401,7 @@ class webpeerjs{
|
|
|
1196
1401
|
if(besttime>bestlimit){
|
|
1197
1402
|
const addr = remote.toString();
|
|
1198
1403
|
const id = peer.toString();
|
|
1199
|
-
if(!this.#webPeersId.includes(id) && !CONFIG_KNOWN_BOOTSTRAP_PEERS_IDS.includes(id) && !this.#dbstoreData.
|
|
1200
|
-
//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')){
|
|
1201
1405
|
await this.#dbstore.put(new Key(id), new TextEncoder().encode(addr));
|
|
1202
1406
|
this.#dbstoreData.set(id,addr);
|
|
1203
1407
|
}
|
|
@@ -1212,26 +1416,31 @@ class webpeerjs{
|
|
|
1212
1416
|
}
|
|
1213
1417
|
|
|
1214
1418
|
|
|
1215
|
-
let peers = [];
|
|
1216
|
-
for(const peer of this.#libp2p.getPeers()){
|
|
1217
|
-
peers.push(peer.toString());
|
|
1218
|
-
}
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
1419
|
//connect to saved best peer address
|
|
1222
1420
|
//working great
|
|
1223
1421
|
for(const peer of this.#dbstoreData){
|
|
1224
1422
|
const id = peer[0];
|
|
1225
1423
|
const addr = peer[1];
|
|
1226
|
-
if(
|
|
1424
|
+
if(this.#isConnected(id)){
|
|
1227
1425
|
this.#connectionTrackerStore.set(id,0);
|
|
1228
1426
|
continue
|
|
1229
1427
|
}else {
|
|
1230
1428
|
if(this.#connectionTrackerStore.has(id)){
|
|
1231
1429
|
let current = this.#connectionTrackerStore.get(id);
|
|
1232
|
-
if(current>10)continue
|
|
1233
1430
|
current++;
|
|
1234
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
|
+
}
|
|
1235
1444
|
}
|
|
1236
1445
|
else {
|
|
1237
1446
|
this.#connectionTrackerStore.set(id,0);
|
|
@@ -1246,7 +1455,7 @@ class webpeerjs{
|
|
|
1246
1455
|
//connect to good peer address if it is disconnected
|
|
1247
1456
|
const goods = Array.from(this.#dialedGoodPeers.keys());
|
|
1248
1457
|
for(const id of goods){
|
|
1249
|
-
if(
|
|
1458
|
+
if(this.#isConnected(id)){
|
|
1250
1459
|
this.#dialedGoodPeers.set(id,0);
|
|
1251
1460
|
continue
|
|
1252
1461
|
}
|
|
@@ -1315,6 +1524,10 @@ class webpeerjs{
|
|
|
1315
1524
|
|
|
1316
1525
|
//dial based on known bootsrap peers address
|
|
1317
1526
|
#dialKnownBootstrap(){
|
|
1527
|
+
|
|
1528
|
+
if(!navigator.onLine)return
|
|
1529
|
+
if(!this.#isDialEnabled)return
|
|
1530
|
+
|
|
1318
1531
|
const bootstrap = CONFIG_KNOWN_BOOTSTRAP_PEERS_ADDRS;
|
|
1319
1532
|
for(const peer of bootstrap){
|
|
1320
1533
|
const address = peer.Peers[0].Addrs;
|
|
@@ -1337,6 +1550,10 @@ class webpeerjs{
|
|
|
1337
1550
|
}
|
|
1338
1551
|
|
|
1339
1552
|
async #dialSavedKnownID(){
|
|
1553
|
+
|
|
1554
|
+
if(!navigator.onLine)return
|
|
1555
|
+
if(!this.#isDialEnabled)return
|
|
1556
|
+
|
|
1340
1557
|
let firsttime = true;
|
|
1341
1558
|
for(const target of CONFIG_KNOWN_BOOTSTRAP_PEERS_IDS){
|
|
1342
1559
|
if(this.#dbstoreData.has(target)){
|
|
@@ -1359,6 +1576,7 @@ class webpeerjs{
|
|
|
1359
1576
|
const api = CONFIG_DELEGATED_API;
|
|
1360
1577
|
const delegatedClient = createDelegatedRoutingV1HttpApiClient(api);
|
|
1361
1578
|
const peer = await first(delegatedClient.getPeers(peerIdFromString(target)));
|
|
1579
|
+
if(!peer)continue
|
|
1362
1580
|
const address = peer.Addrs;
|
|
1363
1581
|
const id = peer.ID;
|
|
1364
1582
|
let mddrs = [];
|
|
@@ -1379,16 +1597,26 @@ class webpeerjs{
|
|
|
1379
1597
|
}
|
|
1380
1598
|
|
|
1381
1599
|
async #dialUpdateSavedKnownID(){
|
|
1600
|
+
|
|
1601
|
+
if(!navigator.onLine)return
|
|
1602
|
+
if(!this.#isDialEnabled)return
|
|
1603
|
+
|
|
1382
1604
|
let firsttime = true;
|
|
1383
1605
|
for(const target of CONFIG_KNOWN_BOOTSTRAP_PEERS_IDS){
|
|
1384
1606
|
if(this.#dbstoreData.has(target)){
|
|
1385
1607
|
firsttime = false;
|
|
1386
1608
|
}
|
|
1387
|
-
if(!this.#connections.has(target) &&
|
|
1609
|
+
if(!this.#connections.has(target) && (this.#dbstoreData.has(target) || firsttime)){
|
|
1388
1610
|
//console.log('#dialUpdateSavedKnownID()',target)
|
|
1389
1611
|
const api = CONFIG_DELEGATED_API;
|
|
1390
1612
|
const delegatedClient = createDelegatedRoutingV1HttpApiClient(api);
|
|
1391
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
|
+
}
|
|
1392
1620
|
const address = peer.Addrs;
|
|
1393
1621
|
const id = peer.ID;
|
|
1394
1622
|
let mddrs = [];
|
|
@@ -1411,6 +1639,10 @@ class webpeerjs{
|
|
|
1411
1639
|
|
|
1412
1640
|
//dial based on known peers ID
|
|
1413
1641
|
async #dialKnownID(){
|
|
1642
|
+
|
|
1643
|
+
if(!navigator.onLine)return
|
|
1644
|
+
if(!this.#isDialEnabled)return
|
|
1645
|
+
|
|
1414
1646
|
//console.log('#dialKnownID()')
|
|
1415
1647
|
const api = CONFIG_DELEGATED_API;
|
|
1416
1648
|
const delegatedClient = createDelegatedRoutingV1HttpApiClient(api);
|