Merge branch 'bobbyd-multiple-bootstrap-peers'
This commit is contained in:
@@ -27,13 +27,13 @@ export class PeerManager {
|
||||
RPC_remote: Map<string, Function> = new Map();
|
||||
rpc: { [key: string]: Function } = {};
|
||||
isBootstrapPeer: boolean = false;
|
||||
bootstrapPeerConnection: PeerConnection | null = null;
|
||||
bootstrapPeerConnections: Map<string, PeerConnection> | null = null;
|
||||
sessionID = generateID();
|
||||
userID: string;
|
||||
peerID: PeerID;
|
||||
|
||||
websocket: WebSocket | null = null;
|
||||
bootstrapPeerID: string | null = null;
|
||||
bootstrapPeerIDs: Set<string> | null = null;
|
||||
connectPromiseCallbacks: { resolve: Function, reject: Function } | null = null;
|
||||
connectPromise: Promise<null> | null = null;
|
||||
|
||||
@@ -42,7 +42,7 @@ export class PeerManager {
|
||||
eventListeners: Map<PeerEventTypes, Function[]> = new Map();
|
||||
reconnectPeriod: number = 10;
|
||||
messageSuperlog = false;
|
||||
watchdogInterval: ReturnType<typeof setTimeout> |null = null;
|
||||
watchdogInterval: ReturnType<typeof setTimeout> | null = null;
|
||||
reconnectTimer: number | null = null;
|
||||
peerStateSuperlog: boolean = true;
|
||||
|
||||
@@ -118,11 +118,11 @@ export class PeerManager {
|
||||
|
||||
if (message.type === "hello2") {
|
||||
|
||||
if (!this.isBootstrapPeer) {
|
||||
this.bootstrapPeerID = message.bootstrapPeers[0];
|
||||
if (!this.isBootstrapPeer && Array.isArray(message?.bootstrapPeers)) {
|
||||
this.bootstrapPeerIDs = new Set(message.bootstrapPeers);
|
||||
}
|
||||
|
||||
this.onHello2Received(this.bootstrapPeerID as string);
|
||||
this.onHello2Received(this.bootstrapPeerIDs);
|
||||
}
|
||||
|
||||
if (message.type === "peer_message") {
|
||||
@@ -175,21 +175,41 @@ export class PeerManager {
|
||||
return newPeer;
|
||||
}
|
||||
|
||||
async onHello2Received(bootstrapPeerID: string) {
|
||||
async onHello2Received(bootstrapPeerIDs: Set<string> | null) {
|
||||
|
||||
if (this.isBootstrapPeer) {
|
||||
this.connectPromiseCallbacks?.resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!bootstrapPeerID) {
|
||||
console.log.apply(null, log("Didn't get bootstrap peer, waiting 10 seconds..."));
|
||||
if (!bootstrapPeerIDs) {
|
||||
console.log.apply(null, log("Didn't get any bootstrap peer, waiting 10 seconds..."));
|
||||
// let callSendHello2OnTimeout = () => { console.log(this, "jajajajaj");this.sendHello2() };
|
||||
// setTimeout(callSendHello2OnTimeout, 5_000);
|
||||
return;
|
||||
}
|
||||
|
||||
this.bootstrapPeerConnection = await this.connectToPeer(bootstrapPeerID);
|
||||
let bootstrapPeerConnectionPromises = [];
|
||||
|
||||
for (let peerID of bootstrapPeerIDs.keys()) {
|
||||
// this.bootstrapPeerConnection = await this.connectToPeer(peerID);
|
||||
|
||||
|
||||
let bootstrapPeerConnectionPromise = new Promise( async (resolve, reject)=>{
|
||||
let peerConnection = await this.connectToPeer(peerID);
|
||||
if (!peerConnection) {
|
||||
reject(peerConnection);
|
||||
}
|
||||
this.bootstrapPeerConnections?.set(peerID, peerConnection);
|
||||
resolve(peerConnection);
|
||||
})
|
||||
|
||||
|
||||
bootstrapPeerConnectionPromises.push(bootstrapPeerConnectionPromise);
|
||||
}
|
||||
|
||||
await Promise.race(bootstrapPeerConnectionPromises);
|
||||
|
||||
this.connectPromiseCallbacks?.resolve();
|
||||
}
|
||||
|
||||
@@ -321,7 +341,7 @@ export class PeerManager {
|
||||
|
||||
let output = `Current status:` + "\n" + `[${logID(this.peerID)}]${this.getPeername(this.peerID)}[local]` + "\n";
|
||||
for (let [peerID, peer] of this.peers) {
|
||||
output += `[${logID(peerID)}]${peer.rtcPeer?.connectionState}:${this.getPeername(peerID)}${(peerID === this.bootstrapPeerID) ? "[Bootstrap]" : ""}` + "\n";
|
||||
output += `[${logID(peerID)}]${peer.rtcPeer?.connectionState}:${this.getPeername(peerID)}${this.bootstrapPeerIDs?.has(peerID) ? "[Bootstrap]" : ""}` + "\n";
|
||||
}
|
||||
|
||||
output += `numActivePeers: ${numActive}` + "\n";
|
||||
@@ -409,9 +429,9 @@ export class PeerManager {
|
||||
// We should disconnect from the websocket once we connect to our intial peers.
|
||||
|
||||
// If we have no peer connections, try to connect. If connection fails, start a timer to reconnect.
|
||||
if (peerID === this.bootstrapPeerID) {
|
||||
this.bootstrapPeerID = null;
|
||||
this.bootstrapPeerConnection = null;
|
||||
if (this.bootstrapPeerIDs?.has(peerID)) {
|
||||
this.bootstrapPeerIDs.delete(peerID);
|
||||
this.bootstrapPeerConnections?.delete(peerID);
|
||||
}
|
||||
|
||||
this.peerStateSuperlog && console.log.apply(null, log(`PeerManager: disconnected from peer ${peerID}`));
|
||||
@@ -501,10 +521,11 @@ class PeerConnection {
|
||||
private ignoreOffer: boolean = false;
|
||||
private isSettingRemoteAnswerPending: boolean = false;
|
||||
private polite = true;
|
||||
private webRTCSuperlog = true;
|
||||
private webRTCSuperlog = false;
|
||||
private dataChannelSuperlog = false;
|
||||
private chunkSize = (16 * 1024) - 100;
|
||||
messageSuperlog: boolean = false;
|
||||
sendQueueSuperLog: boolean = false;
|
||||
rpcSuperlog: boolean = false;
|
||||
pendingRPCs: Map<
|
||||
string,
|
||||
@@ -522,10 +543,10 @@ class PeerConnection {
|
||||
{ urls: "stun:ddln.app" },
|
||||
// { urls: "turn:ddln.app", username: "a", credential: "b" },
|
||||
{ urls: "stun:stun.l.google.com" }, // keeping this for now as my STUN server is not returning ipv6
|
||||
{ urls: "stun:stun1.l.google.com" },
|
||||
{ urls: "stun:stun2.l.google.com" },
|
||||
{ urls: "stun:stun3.l.google.com" },
|
||||
{ urls: "stun:stun4.l.google.com" },
|
||||
{ urls: "stun:stun1.l.google.com" },
|
||||
{ urls: "stun:stun2.l.google.com" },
|
||||
{ urls: "stun:stun3.l.google.com" },
|
||||
{ urls: "stun:stun4.l.google.com" },
|
||||
],
|
||||
};
|
||||
// longMessageQueue: string[] = [];
|
||||
@@ -565,7 +586,7 @@ class PeerConnection {
|
||||
this.send({ type: "hello datachannel", from: this.peerManager.peerID, to: this.remotePeerID });
|
||||
// this.dataChannel?.send(`{typeHello datachannel from: ${this.peerManager.peerID}`);
|
||||
|
||||
console.log.apply(null, log([...this.peerManager.peers.keys()]));
|
||||
// console.log.apply(null, log([...this.peerManager.peers.keys()]));
|
||||
|
||||
if (this.peerManager.isBootstrapPeer) {
|
||||
this.send({ type: 'initial_peers', from: this.peerManager.peerID, peers: [...this.peerManager.peers.keys()].filter(entry => entry !== this.remotePeerID) });
|
||||
@@ -588,7 +609,7 @@ class PeerConnection {
|
||||
this.peerManager.disconnectFromPeer(this.remotePeerID);
|
||||
}
|
||||
|
||||
this.dataChannel.onerror = (e: RTCErrorEvent) => {
|
||||
this.dataChannel.onerror = (e: RTCErrorEvent) => {
|
||||
this.dataChannelSuperlog && console.log.apply(null, log(`datachannel from peer ${this.remotePeerID} error:`, e.error));
|
||||
}
|
||||
}
|
||||
@@ -656,7 +677,7 @@ class PeerConnection {
|
||||
|
||||
}
|
||||
|
||||
this.rtcPeer.oniceconnectionstatechange = (event:Event) => {
|
||||
this.rtcPeer.oniceconnectionstatechange = (event: Event) => {
|
||||
this.webRTCSuperlog && console.log.apply(null, log("oniceconnectionstatechange:", this.rtcPeer?.iceConnectionState));
|
||||
|
||||
}
|
||||
@@ -776,8 +797,11 @@ class PeerConnection {
|
||||
throw new Error("Send called but datachannel is null");
|
||||
}
|
||||
|
||||
// this.sendQueueSuperLog && console.log.apply(null, log(`[${logID(this.remotePeerID)}]<-datachannel[${logID(this.peerManager.peerID)}]: bufferedAmount ${this.dataChannel.bufferedAmount}`));
|
||||
|
||||
|
||||
while (this.dataChannel.bufferedAmount >= 8 * 1024 * 1024) {
|
||||
this.sendQueueSuperLog && console.log.apply(null, log(`[${logID(this.remotePeerID)}]<-datachannel[${logID(this.peerManager.peerID)}]: send buffer full, waiting 1 second`));
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
setTimeout(() => resolve(), 1000);
|
||||
})
|
||||
|
||||
@@ -60,10 +60,10 @@ export class PeerManager {
|
||||
}
|
||||
this.messageSuperlog && console.log.apply(null, log("->signaler:", message));
|
||||
if (message.type === "hello2") {
|
||||
if (!this.isBootstrapPeer) {
|
||||
this.bootstrapPeerID = message.bootstrapPeers[0];
|
||||
if (!this.isBootstrapPeer && Array.isArray(message?.bootstrapPeers)) {
|
||||
this.bootstrapPeerIDs = new Set(message.bootstrapPeers);
|
||||
}
|
||||
this.onHello2Received(this.bootstrapPeerID);
|
||||
this.onHello2Received(this.bootstrapPeerIDs);
|
||||
}
|
||||
if (message.type === "peer_message") {
|
||||
let peerConnection = this.peers.get(message.from);
|
||||
@@ -104,18 +104,31 @@ export class PeerManager {
|
||||
this.onPeerConnected(newPeer.remotePeerID);
|
||||
return newPeer;
|
||||
}
|
||||
async onHello2Received(bootstrapPeerID) {
|
||||
async onHello2Received(bootstrapPeerIDs) {
|
||||
if (this.isBootstrapPeer) {
|
||||
this.connectPromiseCallbacks?.resolve();
|
||||
return;
|
||||
}
|
||||
if (!bootstrapPeerID) {
|
||||
console.log.apply(null, log("Didn't get bootstrap peer, waiting 10 seconds..."));
|
||||
if (!bootstrapPeerIDs) {
|
||||
console.log.apply(null, log("Didn't get any bootstrap peer, waiting 10 seconds..."));
|
||||
// let callSendHello2OnTimeout = () => { console.log(this, "jajajajaj");this.sendHello2() };
|
||||
// setTimeout(callSendHello2OnTimeout, 5_000);
|
||||
return;
|
||||
}
|
||||
this.bootstrapPeerConnection = await this.connectToPeer(bootstrapPeerID);
|
||||
let bootstrapPeerConnectionPromises = [];
|
||||
for (let peerID of bootstrapPeerIDs.keys()) {
|
||||
// this.bootstrapPeerConnection = await this.connectToPeer(peerID);
|
||||
let bootstrapPeerConnectionPromise = new Promise(async (resolve, reject) => {
|
||||
let peerConnection = await this.connectToPeer(peerID);
|
||||
if (!peerConnection) {
|
||||
reject(peerConnection);
|
||||
}
|
||||
this.bootstrapPeerConnections?.set(peerID, peerConnection);
|
||||
resolve(peerConnection);
|
||||
});
|
||||
bootstrapPeerConnectionPromises.push(bootstrapPeerConnectionPromise);
|
||||
}
|
||||
await Promise.race(bootstrapPeerConnectionPromises);
|
||||
this.connectPromiseCallbacks?.resolve();
|
||||
}
|
||||
sendHello2() {
|
||||
@@ -152,10 +165,10 @@ export class PeerManager {
|
||||
this.RPC_remote = new Map();
|
||||
this.rpc = {};
|
||||
this.isBootstrapPeer = false;
|
||||
this.bootstrapPeerConnection = null;
|
||||
this.bootstrapPeerConnections = null;
|
||||
this.sessionID = generateID();
|
||||
this.websocket = null;
|
||||
this.bootstrapPeerID = null;
|
||||
this.bootstrapPeerIDs = null;
|
||||
this.connectPromiseCallbacks = null;
|
||||
this.connectPromise = null;
|
||||
this.pingPeers = [];
|
||||
@@ -243,7 +256,7 @@ export class PeerManager {
|
||||
}
|
||||
let output = `Current status:` + "\n" + `[${logID(this.peerID)}]${this.getPeername(this.peerID)}[local]` + "\n";
|
||||
for (let [peerID, peer] of this.peers) {
|
||||
output += `[${logID(peerID)}]${peer.rtcPeer?.connectionState}:${this.getPeername(peerID)}${(peerID === this.bootstrapPeerID) ? "[Bootstrap]" : ""}` + "\n";
|
||||
output += `[${logID(peerID)}]${peer.rtcPeer?.connectionState}:${this.getPeername(peerID)}${this.bootstrapPeerIDs?.has(peerID) ? "[Bootstrap]" : ""}` + "\n";
|
||||
}
|
||||
output += `numActivePeers: ${numActive}` + "\n";
|
||||
console.log.apply(null, log(output));
|
||||
@@ -309,9 +322,9 @@ export class PeerManager {
|
||||
// Eventually we want the bootstrap peer to be no different than any other peer anyway.
|
||||
// We should disconnect from the websocket once we connect to our intial peers.
|
||||
// If we have no peer connections, try to connect. If connection fails, start a timer to reconnect.
|
||||
if (peerID === this.bootstrapPeerID) {
|
||||
this.bootstrapPeerID = null;
|
||||
this.bootstrapPeerConnection = null;
|
||||
if (this.bootstrapPeerIDs?.has(peerID)) {
|
||||
this.bootstrapPeerIDs.delete(peerID);
|
||||
this.bootstrapPeerConnections?.delete(peerID);
|
||||
}
|
||||
this.peerStateSuperlog && console.log.apply(null, log(`PeerManager: disconnected from peer ${peerID}`));
|
||||
this.dispatchEvent(PeerEventTypes.PEER_DISCONNECTED, { peerID: peerID });
|
||||
@@ -373,10 +386,11 @@ class PeerConnection {
|
||||
this.ignoreOffer = false;
|
||||
this.isSettingRemoteAnswerPending = false;
|
||||
this.polite = true;
|
||||
this.webRTCSuperlog = true;
|
||||
this.webRTCSuperlog = false;
|
||||
this.dataChannelSuperlog = false;
|
||||
this.chunkSize = (16 * 1024) - 100;
|
||||
this.messageSuperlog = false;
|
||||
this.sendQueueSuperLog = false;
|
||||
this.rpcSuperlog = false;
|
||||
this.pendingRPCs = new Map();
|
||||
this.connectionPromise = null;
|
||||
@@ -406,7 +420,7 @@ class PeerConnection {
|
||||
this.dataChannelSuperlog && console.log.apply(null, log("data channel is open to: ", this.remotePeerID, " from: ", this.peerManager.peerID));
|
||||
this.send({ type: "hello datachannel", from: this.peerManager.peerID, to: this.remotePeerID });
|
||||
// this.dataChannel?.send(`{typeHello datachannel from: ${this.peerManager.peerID}`);
|
||||
console.log.apply(null, log([...this.peerManager.peers.keys()]));
|
||||
// console.log.apply(null, log([...this.peerManager.peers.keys()]));
|
||||
if (this.peerManager.isBootstrapPeer) {
|
||||
this.send({ type: 'initial_peers', from: this.peerManager.peerID, peers: [...this.peerManager.peers.keys()].filter(entry => entry !== this.remotePeerID) });
|
||||
// this.dataChannel.send(JSON.stringify());
|
||||
@@ -565,7 +579,9 @@ class PeerConnection {
|
||||
if (!this.dataChannel) {
|
||||
throw new Error("Send called but datachannel is null");
|
||||
}
|
||||
// this.sendQueueSuperLog && console.log.apply(null, log(`[${logID(this.remotePeerID)}]<-datachannel[${logID(this.peerManager.peerID)}]: bufferedAmount ${this.dataChannel.bufferedAmount}`));
|
||||
while (this.dataChannel.bufferedAmount >= 8 * 1024 * 1024) {
|
||||
this.sendQueueSuperLog && console.log.apply(null, log(`[${logID(this.remotePeerID)}]<-datachannel[${logID(this.peerManager.peerID)}]: send buffer full, waiting 1 second`));
|
||||
await new Promise((resolve, reject) => {
|
||||
setTimeout(() => resolve(), 1000);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user