Moving to MultiSwarm with proper connection tracking per topic

This commit is contained in:
Raven Scott 2024-06-13 21:44:30 -04:00
parent b1ea06018b
commit 2faf2b6f78

92
app.js
View File

@ -13,7 +13,6 @@ const drive = new Hyperdrive(store);
await drive.ready(); await drive.ready();
let swarm;
let activeRooms = []; let activeRooms = [];
const eventEmitter = new EventEmitter(); const eventEmitter = new EventEmitter();
@ -36,10 +35,25 @@ function getRandomPort() {
return Math.floor(Math.random() * (65535 - 49152 + 1)) + 49152; return Math.floor(Math.random() * (65535 - 49152 + 1)) + 49152;
} }
function currentTopic() {
return document.querySelector('#chat-room-topic').innerText;
}
function getCurrentPeerCount() {
const topic = currentTopic();
const room = activeRooms.find(room => room.topic === topic);
return room ? room.swarm.connections.size : 0;
}
function updatePeerCount() {
const peerCountElement = document.querySelector('#peers-count');
if (peerCountElement) {
peerCountElement.textContent = getCurrentPeerCount(); // Display the actual peer count
}
}
async function initialize() { async function initialize() {
try { try {
swarm = new Hyperswarm();
servePort = getRandomPort(); servePort = getRandomPort();
const serve = new ServeDrive({ port: servePort, get: ({ key, filename, version }) => drive }); const serve = new ServeDrive({ port: servePort, get: ({ key, filename, version }) => drive });
await serve.ready(); await serve.ready();
@ -63,10 +77,6 @@ async function initialize() {
handleIncomingMessage(messageObj); handleIncomingMessage(messageObj);
}); });
swarm.on('connection', handleConnection);
swarm.on('error', (err) => console.error('Swarm error:', err));
swarm.on('close', () => console.log('Swarm closed'));
document.addEventListener("DOMContentLoaded", (event) => { document.addEventListener("DOMContentLoaded", (event) => {
hljs.highlightAll(); hljs.highlightAll();
}); });
@ -109,7 +119,7 @@ function setupEventListeners() {
} }
if (removeRoomBtn) { if (removeRoomBtn) {
removeRoomBtn.addEventListener('click', () => { removeRoomBtn.addEventListener('click', () => {
const topic = document.querySelector('#chat-room-topic').innerText; const topic = currentTopic();
leaveRoom(topic); leaveRoom(topic);
}); });
} }
@ -162,30 +172,18 @@ function handleIncomingMessage(messageObj) {
} }
function handleConnection(connection, info) { function handleConnection(connection, info) {
updatePeerCount(); console.log('New connection', info);
console.log('Peer connected, current peer count:', swarm.connections.size);
// Send the current user's icon to the new peer
drive.get(`/icons/${config.userName}.png`).then(iconBuffer => {
if (iconBuffer) {
const iconMessage = JSON.stringify({
type: 'icon',
username: config.userName,
avatar: b4a.toString(iconBuffer, 'base64'),
});
connection.write(iconMessage);
}
});
connection.on('data', (data) => { connection.on('data', (data) => {
const messageObj = JSON.parse(data.toString()); const messageObj = JSON.parse(data.toString());
eventEmitter.emit('onMessage', messageObj); eventEmitter.emit('onMessage', messageObj);
}); });
connection.on('close', () => { connection.on('close', () => {
console.log('Connection closed', info);
updatePeerCount(); updatePeerCount();
console.log('Peer disconnected, current peer count:', swarm.connections.size);
}); });
updatePeerCount();
} }
function setupTalkButton() { function setupTalkButton() {
@ -211,7 +209,7 @@ function setupTalkButton() {
const arrayBuffer = await audioBlob.arrayBuffer(); const arrayBuffer = await audioBlob.arrayBuffer();
const buffer = new Uint8Array(arrayBuffer); const buffer = new Uint8Array(arrayBuffer);
const topic = document.querySelector('#chat-room-topic').innerText; const topic = currentTopic();
const filePath = `/audio/${Date.now()}.webm`; const filePath = `/audio/${Date.now()}.webm`;
await drive.put(filePath, buffer); await drive.put(filePath, buffer);
@ -228,7 +226,7 @@ function setupTalkButton() {
console.log('Sending audio message:', audioMessage); // Debugging log console.log('Sending audio message:', audioMessage); // Debugging log
const peers = [...swarm.connections]; const peers = [...activeRooms.find(room => room.topic === topic).swarm.connections];
for (const peer of peers) { for (const peer of peers) {
peer.write(JSON.stringify(audioMessage)); peer.write(JSON.stringify(audioMessage));
} }
@ -315,10 +313,15 @@ async function joinSwarm(topicBuffer) {
const topic = b4a.toString(topicBuffer, 'hex'); const topic = b4a.toString(topicBuffer, 'hex');
if (!activeRooms.some(room => room.topic === topic)) { if (!activeRooms.some(room => room.topic === topic)) {
try { try {
const swarm = new Hyperswarm();
const discovery = swarm.join(topicBuffer, { client: true, server: true }); const discovery = swarm.join(topicBuffer, { client: true, server: true });
await discovery.flushed(); await discovery.flushed();
activeRooms.push({ topic, discovery }); swarm.on('connection', (connection, info) => {
handleConnection(connection, info);
});
activeRooms.push({ topic, swarm, discovery });
console.log('Joined room:', topic); // Debugging log console.log('Joined room:', topic); // Debugging log
@ -385,8 +388,7 @@ function exitEditMode(roomItem, input, topic) {
} }
// Check if the edited room is the current room in view // Check if the edited room is the current room in view
const currentTopic = document.querySelector('#chat-room-topic').innerText; if (currentTopic() === topic) {
if (currentTopic === topic) {
const chatRoomName = document.querySelector('#chat-room-name'); const chatRoomName = document.querySelector('#chat-room-name');
if (chatRoomName) { if (chatRoomName) {
chatRoomName.innerText = newAlias; chatRoomName.innerText = newAlias;
@ -430,7 +432,7 @@ function leaveRoom(topic) {
const roomIndex = activeRooms.findIndex(room => room.topic === topic); const roomIndex = activeRooms.findIndex(room => room.topic === topic);
if (roomIndex !== -1) { if (roomIndex !== -1) {
const room = activeRooms[roomIndex]; const room = activeRooms[roomIndex];
room.discovery.destroy(); room.swarm.destroy();
activeRooms.splice(roomIndex, 1); activeRooms.splice(roomIndex, 1);
} }
@ -455,7 +457,7 @@ function sendMessage(e) {
const message = document.querySelector('#message').value; const message = document.querySelector('#message').value;
document.querySelector('#message').value = ''; document.querySelector('#message').value = '';
const topic = document.querySelector('#chat-room-topic').innerText; const topic = currentTopic();
console.log('Sending message:', message); // Debugging log console.log('Sending message:', message); // Debugging log
@ -470,7 +472,7 @@ function sendMessage(e) {
timestamp: Date.now() timestamp: Date.now()
}); });
const peers = [...swarm.connections]; const peers = [...activeRooms.find(room => room.topic === topic).swarm.connections];
for (const peer of peers) { for (const peer of peers) {
peer.write(messageObj); peer.write(messageObj);
} }
@ -486,7 +488,7 @@ async function handleFileInput(event) {
await drive.put(filePath, buffer); await drive.put(filePath, buffer);
const fileUrl = `http://localhost:${servePort}${filePath}`; const fileUrl = `http://localhost:${servePort}${filePath}`;
const topic = document.querySelector('#chat-room-topic').innerText; const topic = currentTopic();
const fileMessage = { const fileMessage = {
type: 'file', type: 'file',
@ -500,7 +502,7 @@ async function handleFileInput(event) {
console.log('Sending file message:', fileMessage); // Debugging log console.log('Sending file message:', fileMessage); // Debugging log
const peers = [...swarm.connections]; const peers = [...activeRooms.find(room => room.topic === topic).swarm.connections];
for (const peer of peers) { for (const peer of peers) {
peer.write(JSON.stringify(fileMessage)); peer.write(JSON.stringify(fileMessage));
} }
@ -550,19 +552,11 @@ function addFileMessage(from, fileName, fileUrl, fileType, avatar, topic) {
$div.appendChild($content); $div.appendChild($content);
// Only render the message if it's for the current room // Only render the message if it's for the current room
const currentTopic = document.querySelector('#chat-room-topic').innerText; if (currentTopic() === topic) {
if (currentTopic === topic) {
document.querySelector('#messages').appendChild($div); document.querySelector('#messages').appendChild($div);
scrollToBottom(); scrollToBottom();
} else { } else {
console.log(`Message for topic ${topic} not rendered because current topic is ${currentTopic}`); // Debugging log console.log(`Message for topic ${topic} not rendered because current topic is ${currentTopic()}`); // Debugging log
}
}
function updatePeerCount() {
const peerCountElement = document.querySelector('#peers-count');
if (peerCountElement) {
peerCountElement.textContent = swarm.connections.size; // Display the actual peer count
} }
} }
@ -583,8 +577,7 @@ function onMessageAdded(from, message, avatar, topic) {
addMessageToStore(topic, messageObj); addMessageToStore(topic, messageObj);
// Only render messages for the current room // Only render messages for the current room
const currentTopic = document.querySelector('#chat-room-topic').innerText; if (currentTopic() === topic) {
if (currentTopic === topic) {
const $div = document.createElement('div'); const $div = document.createElement('div');
$div.classList.add('message'); $div.classList.add('message');
@ -624,7 +617,7 @@ function onMessageAdded(from, message, avatar, topic) {
document.querySelector('#messages').appendChild($div); document.querySelector('#messages').appendChild($div);
scrollToBottom(); scrollToBottom();
} else { } else {
console.log(`Message for topic ${topic} not rendered because current topic is ${currentTopic}`); // Debugging log console.log(`Message for topic ${topic} not rendered because current topic is ${currentTopic()}`); // Debugging log
} }
} }
@ -658,12 +651,11 @@ function addAudioMessage(from, audioUrl, avatar, topic) {
$div.appendChild($content); $div.appendChild($content);
// Only render the message if it's for the current room // Only render the message if it's for the current room
const currentTopic = document.querySelector('#chat-room-topic').innerText; if (currentTopic() === topic) {
if (currentTopic === topic) {
document.querySelector('#messages').appendChild($div); document.querySelector('#messages').appendChild($div);
scrollToBottom(); scrollToBottom();
} else { } else {
console.log(`Message for topic ${topic} not rendered because current topic is ${currentTopic}`); // Debugging log console.log(`Message for topic ${topic} not rendered because current topic is ${currentTopic()}`); // Debugging log
} }
} }