Commit 2d181551 authored by lazorfuzz's avatar lazorfuzz
Browse files

Fix reconnection when dropped below minPeers

parent 3e4caec1
......@@ -59,7 +59,7 @@ const webrtc = new LioWebRTC({
```
### Partial mesh network
Peers only form direct connections with a maximum of maxPeers and a minimum of minPeers. shout()ing still works because peers wil re-propagate messages to other peers.
Peers only form direct connections with a maximum of maxPeers and a minimum of minPeers. shout()ing still works because peers wil re-propagate messages to other peers. Note: partial mesh networks only work if you're only using data channels.
```js
const webrtc = new LioWebRTC({
dataOnly: true,
......
......@@ -69,6 +69,9 @@ export default class PeerGraph {
}
deleteEdge(edge) {
if (!edge) {
return;
}
if (this.edges[edge.getId()]) {
delete this.edges[edge.getId()];
}
......
......@@ -13,9 +13,6 @@ export function addConnection(node1Id, node2Id, latency = 0) {
const nodeA = Graph.getNodeById(node1Id) || new PeerNode(node1Id);
const nodeB = Graph.getNodeById(node2Id) || new PeerNode(node2Id);
const edgeAB = new Edge(nodeA, nodeB, latency);
console.log('ADDED CONNECTION', node1Id, node2Id, latency);
console.log(Graph.nodes);
console.log(Graph.edges);
return Graph.addEdge(edgeAB);
}
......@@ -25,6 +22,21 @@ export function removeConnection(node1Id, node2Id) {
if (nodeA && nodeB) Graph.deleteEdge(Graph.findEdge(nodeA, nodeB));
}
export function getNeighbors(nodeId) {
const node = Graph.getNodeById(nodeId);
const neighbors = node.getNeighbors();
return neighbors.map(n => n.getId());
}
export function isNeighbor(node1Id, node2Id) {
const nodeA = Graph.getNodeById(node1Id) || new PeerNode(node1Id);
const nodeB = Graph.getNodeById(node2Id) || new PeerNode(node2Id);
if (nodeA.hasNeighbor(nodeB)) {
return true;
}
return false;
}
export function getPeerLatencies(nodeId) {
const node = Graph.findNodeById(nodeId);
if (node) {
......@@ -39,12 +51,6 @@ export function getPeerLatencies(nodeId) {
}
}
export function getConnectedPeers(nodeId) {
const node = Graph.getNodeById(nodeId);
const neighbors = node.getNeighbors();
return neighbors.map(n => n.getId());
}
export function average(vals) {
const total = vals.reduce((sum, val) => val + sum);
return total / vals.length;
......
......@@ -4,7 +4,7 @@ import mockconsole from 'mockconsole';
import WebRTC from './webrtc';
import webrtcSupport from './webrtcsupport';
import SocketIoConnection from './socketioconnection';
import { Graph, addNode, addConnection, getConnectedPeers, getDroppablePeers } from './PeerOptimizer';
import { Graph, addNode, addConnection, removeConnection, getNeighbors, isNeighbor, getDroppablePeers } from './PeerOptimizer';
import { inheritedMethods, defaultConfig, defaultChannel } from './constants';
class LioWebRTC extends WildEmitter {
......@@ -70,7 +70,7 @@ class LioWebRTC extends WildEmitter {
});
// if (!peer) peer = peers[0]; // fallback for old protocol versions
}
if (this.config.network.maxPeers > 0 && totalPeers >= this.config.network.maxPeers) {
if (this.config.dataOnly && this.config.network.maxPeers > 0 && totalPeers >= this.config.network.maxPeers) {
return;
}
if (!peer) {
......@@ -168,6 +168,16 @@ class LioWebRTC extends WildEmitter {
self.webrtc.sendToAll('mute', { name: 'video' });
});
self.on('removedPeer', (peer) => {
if (peer.id) {
removeConnection(this.id, peer.id);
}
if (this.config.dataOnly && this.config.network.maxPeers > 0 && getNeighbors(this.id).length < this.config.network.minPeers) {
this.connectToRandomPeer();
}
});
this.webrtc.on('channelMessage', (peer, label, data) => {
if (data.payload._id && this.peerDataCache[data.payload._id]) {
return;
......@@ -251,7 +261,6 @@ class LioWebRTC extends WildEmitter {
}
sendPing(peer, peerId, firstPing = false, channel = defaultChannel) {
console.log('SENDING PING', peer);
const self = this;
if (firstPing) peer.start();
setTimeout(() => {
......@@ -260,28 +269,24 @@ class LioWebRTC extends WildEmitter {
if (firstPing) this.emit('createdPeer', peer);
} else {
// The channel is closed, remove the peer
console.log('removing peer, ping failed', peerId);
// console.log('removing peer, ping failed', peerId);
self.unconnectivePeers[peerId] = true;
peer.end();
this.getClients((err, clients) => {
console.log('CLIENT RESULTS', clients);
const ids = Object.keys(clients).filter((c) => {
if (self.unconnectivePeers[c] === true || c === this.id) {
return false;
}
return true;
});
console.log('IDS', ids, self.unconnectivePeers);
if (!ids.length) {
return;
}
const randId = ids[Math.floor(Math.random() * ids.length)];
this.connectToPeer(randId, clients[randId]);
});
this.connectToRandomPeer();
}
}, 1000);
}
connectToRandomPeer() {
this.getClients((err, clients) => {
const ids = Object.keys(clients).filter(c => !(this.unconnectivePeers[c] === true || c === this.id || isNeighbor(this.id, c)));
if (ids.length) {
const randId = ids[Math.floor(Math.random() * ids.length)];
this.connectToPeer(randId, clients[randId]);
}
});
}
sendConnections(peer, channel = defaultChannel) {
if (peer.sendDirectly('_connections', this.getPeers().map((p) => {
const edge = Graph.findEdge(this.id, p.id);
......@@ -382,15 +387,16 @@ class LioWebRTC extends WildEmitter {
let peer;
this.roomCount = Object.keys(roomDescription.clients).length;
console.log(roomDescription);
// console.log(roomDescription);
this.id = roomDescription.you;
addNode(this.id);
this.unconnectivePeers[this.id] = true;
for (id of Object.keys(roomDescription.clients).reverse().filter(item => item !== this.id)) {
client = roomDescription.clients[id];
for (type in client) {
if (client[type]) {
const peerCount = this.webrtc.getPeers().length;
if (this.config.network.maxPeers > 0 && (peerCount >= this.config.network.minPeers || peerCount >= this.config.network.maxPeers)) {
if (this.config.dataOnly && this.config.network.maxPeers > 0 && (peerCount >= this.config.network.minPeers || peerCount >= this.config.network.maxPeers)) {
break;
}
peer = self.webrtc.createPeer({
......@@ -460,7 +466,6 @@ class LioWebRTC extends WildEmitter {
}
connectToPeer(peerId, client) {
console.log('CONNECTING TO', peerId);
let type;
let peer;
for (type in client) {
......@@ -470,7 +475,7 @@ class LioWebRTC extends WildEmitter {
break;
}
peer = this.webrtc.createPeer({
peerId,
id: peerId,
type,
enableDataChannels: this.config.enableDataChannels && type !== 'screen',
receiveMedia: {
......@@ -478,7 +483,6 @@ class LioWebRTC extends WildEmitter {
offerToReceiveVideo: !this.config.dataOnly && this.config.receiveMedia.offerToReceiveVideo ? 1 : 0,
},
});
console.log('ABOUT TO SEND PING', peer);
this.sendPing(peer, peerId, true);
}
}
......
......@@ -2,7 +2,6 @@ import PeerConnection from 'rtcpeerconnection';
import WildEmitter from 'wildemitter';
import FileTransfer from 'filetransfer';
import webrtcSupport from './webrtcsupport';
import { removeConnection } from './PeerOptimizer';
function isAllTracksEnded(stream) {
let isAllTracksEnded = true;
......@@ -63,7 +62,6 @@ class Peer extends WildEmitter {
case 'closed':
this.handleStreamRemoved(false);
self.parent.emit('removedPeer', self);
removeConnection(self.parent.id, this.id);
break;
default:
break;
......@@ -192,7 +190,6 @@ class Peer extends WildEmitter {
// if we don't have one by this label, create it
channel = this.channels[name] = this.pc.createDataChannel(name, opts);
this._observeDataChannel(channel);
console.log('CHANNEL', channel);
return channel;
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment