Spaces:
Sleeping
Sleeping
File size: 3,738 Bytes
d3bdf51 42e18e6 d3bdf51 7fe989f d3bdf51 7fe989f d3bdf51 7fe989f d441744 7fe989f d441744 7fe989f d441744 7fe989f d441744 7fe989f d3bdf51 7fe989f d441744 d3bdf51 d441744 7fe989f d441744 d3bdf51 d441744 7fe989f d441744 7fe989f d3bdf51 7fe989f d3bdf51 7fe989f d3bdf51 6d4d78a 7fe989f d3bdf51 7fe989f d3bdf51 7fe989f d3bdf51 7fe989f 6d4d78a d3bdf51 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | // server.js (for Bun)
import { serve } from "bun";
const rooms = new Map(); // roomId → Set<WebSocket>
serve({
port: Number(process.env.PORT) || 7860,
// Serve the HTML page at “/”
async fetch(req) {
const url = new URL(req.url);
if (url.pathname !== "/") return new Response("Not Found", { status: 404 });
return new Response(`<!doctype html>
<html>
<head>
<title>Dubem Realtime Rooms</title>
<meta charset="utf-8" />
<style>
body { font-family: sans-serif; padding: 20px; background: #f0f0f0; }
#log { border: 1px solid #ccc; height: 200px; overflow-y: auto; padding: 10px; background: #fff; }
input, button { margin: 5px 0; padding: 8px; font-size: 16px; }
</style>
</head>
<body>
<h2>Join a Room & Send Messages</h2>
<input id="room" placeholder="Room ID" />
<button onclick="joinRoom()">Join Room</button>
<div id="log"></div>
<input id="msg" placeholder="Type a message" style="width:80%;" />
<button onclick="sendMsg()">Send</button>
<script>
let ws;
let currentRoom = null;
window.addEventListener('load', () => {
const scheme = location.protocol === 'https:' ? 'wss' : 'ws';
ws = new WebSocket(\`\${scheme}://\${location.host}\`);
ws.onopen = () => log('🔌 Connected to server');
ws.onmessage = ({data}) => {
const msg = JSON.parse(data);
log(\`[\${msg.roomId}] \${msg.message}\`);
};
ws.onclose = () => log('❌ Disconnected');
ws.onerror = err => log('⚠️ WebSocket error: ' + err.message);
});
function joinRoom() {
const roomId = document.getElementById('room').value.trim();
if (!roomId) return alert('Please enter a room ID');
ws.send(JSON.stringify({ action: 'join', roomId }));
currentRoom = roomId;
log('➡️ Joined room: ' + roomId);
}
function sendMsg() {
const txt = document.getElementById('msg').value.trim();
if (!txt) return;
if (!currentRoom) return alert('Join a room first');
ws.send(JSON.stringify({ action: 'post', roomId: currentRoom, message: txt }));
document.getElementById('msg').value = '';
}
function log(t) {
const el = document.getElementById('log');
el.innerHTML += '<div>' + t + '</div>';
el.scrollTop = el.scrollHeight;
}
</script>
</body>
</html>`, {
headers: { "Content-Type": "text/html; charset=utf-8" },
});
},
// Hook into Bun's WebSocket handling
websocket: {
open(ws) {
// no-op here; clients join via “join” action
},
message(ws, raw) {
let msg;
try {
msg = JSON.parse(raw.toString());
} catch {
return;
}
if (msg.action === "join" && msg.roomId) {
// remove from all rooms
for (const clients of rooms.values()) {
clients.delete(ws);
}
// add to new room
const roomSet = rooms.get(msg.roomId) || new Set();
roomSet.add(ws);
rooms.set(msg.roomId, roomSet);
return;
}
if (msg.action === "post" && msg.roomId && msg.message) {
const clients = rooms.get(msg.roomId);
if (!clients) return;
const payload = JSON.stringify({
roomId: msg.roomId,
message: msg.message,
timestamp: Date.now(),
});
for (const client of clients) {
if (client.readyState === 1) { // OPEN
client.send(payload);
}
}
}
},
close(ws) {
// on disconnect, remove from all rooms
for (const clients of rooms.values()) {
clients.delete(ws);
}
},
},
});
console.log("✅ Bun realtime server running on port " + (process.env.PORT || 7860)); |