Skip to content

Commit

Permalink
com: Fix closed connections not getting purged
Browse files Browse the repository at this point in the history
  • Loading branch information
Core447 committed Jan 27, 2025
1 parent 0199531 commit 817d408
Showing 1 changed file with 51 additions and 46 deletions.
97 changes: 51 additions & 46 deletions src/app/com/page.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
"use client";
import { Button } from "@/components/ui/button";
import { DataConnection, Peer } from "peerjs";
import { use, useCallback, useEffect, useMemo, useState } from "react";
import { useCallback, useEffect, useMemo, useState } from "react";
import { adjectives, animals, colors, uniqueNamesGenerator } from "unique-names-generator";
import { useQuery } from "@tanstack/react-query";

interface Data {
name: string
Expand All @@ -12,92 +13,98 @@ export default function Page() {
const [connectedCons, setConnectedCons] = useState<DataConnection[]>([]);

const peerName = useMemo(() => {
// Just for easier testing - discovery either via fastapi backend or next.js server
// if (navigator.userAgent.toLowerCase().includes("firefox")) {
// return "firefox";
// }
// return "chrome";
return uniqueNamesGenerator({
dictionaries: [adjectives, animals, colors],
length: 2
});
}, []);

// Function to fetch peer names from the server
const getOtherPeerNames = useCallback(async (): Promise<string[]> => {
const response = await fetch("http://localhost:9000/blockchain/peerjs/peers");
const data = await response.json();
return data.filter((p: string) => p !== peerName);
}, [peerName]);

// Set up TanStack Query to fetch peer list every second
const { data: activePeers = [] } = useQuery({
queryKey: ['peers'],
queryFn: getOtherPeerNames,
refetchInterval: 1000, // Refetch every second
});

// Clean up disconnected peers whenever the active peers list updates
useEffect(() => {
setConnectedCons(prev => {
return prev.filter(conn => {
// Keep the connection if:
// 1. It's still in the active peers list
// 2. The connection is still open
const isPeerActive = activePeers.includes(conn.peer);
const isConnectionOpen = conn.open;

if (!isPeerActive || !isConnectionOpen) {
console.log(`Removing disconnected peer: ${conn.peer}`);
conn.close(); // Clean up the connection
return false;
}
return true;
});
});
}, [activePeers]);

const addConnection = useCallback((conn: DataConnection) => {
setConnectedCons(prev => {
const exists = prev.some(c => c.peer === conn.peer); // we cant use connectedCons for checking, but have to use prev as we call addConnection multiple times before the next re-render when the connectedCons updates
const exists = prev.some(c => c.peer === conn.peer);
if (exists) return prev;
return [...prev, conn];
});
}, []);

useEffect(() => {
const usedIds = connectedCons.map((c) => c.peer);
console.log("used ids", usedIds);

}, [connectedCons]);

const peer = useMemo(() => {
const peer = new Peer(peerName, {
host: "localhost",
port: 9000,
path: "/blockchain",
});

peer.on("open", () => {
// peer is ready
loadConnections();
})

async function getOtherPeerNames(): Promise<string[]> {
const response = await fetch("http://localhost:9000/blockchain/peerjs/peers"); //server start command: peerjs --port 9000 --key peerjs --path /blockchain --allow_discovery
const data = await response.json();
return data.filter((p: string) => p !== peerName);
}
});

async function loadConnections() {
const initialOtherPeerNames = await getOtherPeerNames();
initialOtherPeerNames.forEach((otherPeerName) => {
// if (peer.id === "chrome") {
// return;
// }
const conn = peer.connect(otherPeerName);
conn.on("open", () => {
conn.send("hello");
console.log(`connected to ${otherPeerName}`);
// setConnectedCons((prev) => [...prev, conn]);
addConnection(conn);
});
})
});
}
loadConnections();

return peer;
}, [peerName, addConnection]);


}, [peerName, addConnection, getOtherPeerNames]);

useEffect(() => {
peer.on("connection", (conn) => {
// setConnectedCons((prev) => [...prev, conn]);
conn.on("open", () => {
addConnection(conn);
// console.log("connection open");
})
});
conn.on("data", (data) => {
console.log("received data", data);
});
});
}, [peer, addConnection]);


function sendToAll2() {
function sendToAll() {
console.log(`sending to all ${connectedCons.length} connections`);
connectedCons.forEach((conn) => {
if (conn.open) {
// conn.send("sendToAll");
const data: Data = {
name: "cool name"
}
};
conn.send(data);
} else {
console.warn("Connection is not open:", conn);
Expand All @@ -108,15 +115,13 @@ export default function Page() {
return (
<div>
<p>Peer id: {peer.id}</p>
<button onClick={sendToAll2}>Send To All</button>
<h1>connections:</h1>
{connectedCons.map((conn, index) => {
return (
<div key={index}>
<p>{conn.peer}</p>
</div>
);
})}
<Button onClick={sendToAll}>Send To All</Button>
<h1>Active connections: {connectedCons.length}</h1>
{connectedCons.map((conn, index) => (
<div key={index}>
<p>{conn.peer}</p>
</div>
))}
</div>
);
}

0 comments on commit 817d408

Please sign in to comment.