Peer Exchange (PEX) is a decentralized peer discovery mechanism that allows peers to learn about other peers in the swarm without relying on central trackers or DHT (Distributed Hash Table).
In this P2P system, PEX is the only peer discovery method. There are no trackers, no bootstrap servers, and no DHT - just peers sharing information about other peers.
_shouldInitiateConnection(otherPeerId) { // Returns true if this node should initiate connection to the other peer. // Rule: the peer with higher ID initiates the connection. return (otherPeerId && this.id && this.id > otherPeerId);}
// Peer A receives peers message containing Peer C's info_handlePeers(socket, message) { const peersList = message.peers; for (let peer of peersList) { const { id: peerId, host, port } = peer; if (peerId === this.id) continue; // Skip self if (!this.knownPeers.has(peerId)) { this.knownPeers.set(peerId, { id: peerId, host, port, socket: null, availablePieces: new Set(), busy: false }); if (this._shouldInitiateConnection(peerId)) { // Peer A ID: 1a2b... < Peer C ID: 9f8e... // this.id (1a2b...) > peerId (9f8e...) = false // Peer A does NOT initiate console.log(`Descubierto peer ${peerId}. Esperando a que el peer inicie conexión.`); } else { // If the condition was true, Peer A would connect console.log(`Descubierto peer ${peerId} en ${host}:${port}, iniciando conexión...`); this.connectToPeer(host, port); } } }}
Since 1a2b... < 9f8e... (lexicographically), Peer A waits for Peer C to initiate the connection.Meanwhile, when Peer C learns about Peer A:
Peer C ID: 9f8e... > Peer A ID: 1a2b...
Peer C initiates the connection to Peer A
This asymmetric initiation prevents the “connection collision” problem where both peers simultaneously try to connect to each other, potentially creating duplicate connections.
Seeder (S) 6881, ff00... / \ / \Leecher 1 (L1) ←--→ Leecher 2 (L2)6882, aa11... 6883, bb22...# Now all three peers are connected# L1 and L2 can exchange pieces directly# Reduces load on the seeder
Bootstrap Requirement: At least one initial peer address must be known to join the swarm. Without a bootstrap peer, isolated nodes cannot discover each other.
Future enhancements could include:
Multicast discovery on local networks
DHT integration for global peer discovery
Peer list persistence to remember peers across restarts
Peer A learns about Peer B → initiates connectionPeer B learns about Peer A → initiates connectionResult: Two TCP connections between A and B!- Wastes socket descriptors- Confuses message routing- Doubles bandwidth usage
Peer A (ID: 1111) learns about Peer B (ID: 2222)→ 1111 < 2222, so A waitsPeer B (ID: 2222) learns about Peer A (ID: 1111)→ 2222 > 1111, so B connectsResult: Exactly one connection from B to A
The lexicographic comparison of hex IDs provides a deterministic, symmetric decision rule that both peers will independently arrive at the same conclusion.