Spaces:
Sleeping
Sleeping
| // server.js (Bun) — with CORS enabled for WS and HTTP | |
| const rooms = new Map(); // roomId ⇒ Set<ServerWebSocket> | |
| Bun.serve({ | |
| port: Number(Bun.env.PORT) || 7860, | |
| fetch(req, server) { | |
| const url = new URL(req.url); | |
| // Handle CORS preflight | |
| if (req.method === "OPTIONS") { | |
| return new Response(null, { | |
| status: 204, | |
| headers: { | |
| "Access-Control-Allow-Origin": "*", | |
| "Access-Control-Allow-Methods": "GET, POST, OPTIONS", | |
| "Access-Control-Allow-Headers": "Content-Type, Upgrade", | |
| "Access-Control-Allow-Credentials": "true", | |
| }, | |
| }); | |
| } | |
| // Upgrade to WebSocket if requested | |
| if (req.headers.get("upgrade")?.toLowerCase() === "websocket") { | |
| // Accept the upgrade with CORS headers on the handshake | |
| const upgradeRes = server.upgrade(req, { | |
| headers: { | |
| "Access-Control-Allow-Origin": "*", | |
| "Access-Control-Allow-Credentials": "true", | |
| }, | |
| }); | |
| return upgradeRes ?? new Response("Upgrade failed", { status: 500 }); | |
| } | |
| // Serve HTML UI for non-WebSocket requests | |
| if (url.pathname === "/") { | |
| 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> | |
| var ws, currentRoom; | |
| window.addEventListener('load', function() { | |
| var scheme = location.protocol === 'https:' ? 'wss' : 'ws'; | |
| var socketUrl = scheme + '://' + location.host + '/'; | |
| ws = new WebSocket(socketUrl); | |
| ws.onopen = function(){ log('🔌 Connected'); }; | |
| ws.onmessage = function(ev){ | |
| var m = JSON.parse(ev.data); | |
| log('[' + m.roomId + '] ' + m.message); | |
| }; | |
| ws.onerror = function(){ log('⚠️ WebSocket error'); }; | |
| ws.onclose = function(c){ log('❌ Disconnected (code='+c.code+')'); }; | |
| }); | |
| function joinRoom(){ | |
| var id = document.getElementById('room').value.trim(); | |
| if(!id) return alert('Enter room ID'); | |
| ws.send(JSON.stringify({ action:'join', roomId:id })); | |
| currentRoom = id; log('➡️ Joined '+id); | |
| } | |
| function sendMsg(){ | |
| var t = document.getElementById('msg').value.trim(); | |
| if(!t) return; | |
| if(!currentRoom) return alert('Join a room first'); | |
| ws.send(JSON.stringify({ action:'post', roomId:currentRoom, message:t })); | |
| document.getElementById('msg').value = ''; | |
| } | |
| function log(txt){ | |
| var e = document.getElementById('log'); | |
| e.innerHTML += '<div>'+txt+'</div>'; | |
| e.scrollTop = e.scrollHeight; | |
| } | |
| </script> | |
| </body></html>`, { | |
| headers: { | |
| "Content-Type": "text/html; charset=utf-8", | |
| "Access-Control-Allow-Origin": "*", | |
| } | |
| }); | |
| } | |
| return new Response("Not Found", { | |
| status: 404, | |
| headers: { "Access-Control-Allow-Origin": "*" }, | |
| }); | |
| }, | |
| websocket: { | |
| message(ws, raw) { | |
| let msg; | |
| try { msg = JSON.parse(raw); } catch { return; } | |
| if (msg.action === "join" && msg.roomId) { | |
| // Leave all rooms | |
| for (const set of rooms.values()) set.delete(ws); | |
| // Join target room | |
| let set = rooms.get(msg.roomId); | |
| if (!set) { | |
| set = new Set(); | |
| rooms.set(msg.roomId, set); | |
| } | |
| set.add(ws); | |
| } | |
| if (msg.action === "post" && msg.roomId && msg.message) { | |
| const set = rooms.get(msg.roomId); | |
| if (!set) return; | |
| const payload = JSON.stringify({ | |
| roomId: msg.roomId, | |
| message: msg.message, | |
| timestamp: Date.now(), | |
| }); | |
| for (const client of set) { | |
| if (client.readyState === 1) { // OPEN | |
| client.send(payload); | |
| } | |
| } | |
| } | |
| }, | |
| close(ws) { | |
| // Clean up on disconnect | |
| for (const set of rooms.values()) set.delete(ws); | |
| } | |
| } | |
| }); | |
| console.log("✅ Bun realtime server running on port " + (Bun.env.PORT || 7860)); | |
| // // server.js (Bun) | |
| // // import { serve } from "bun"; | |
| // const rooms = new Map(); // roomId ⇒ Set<ServerWebSocket> | |
| // Bun.serve({ | |
| // port: Number(Bun.env.PORT) || 7860, | |
| // fetch(req, server) { | |
| // const url = new URL(req.url); | |
| // // Upgrade to WebSocket if requested | |
| // if (req.headers.get("upgrade")?.toLowerCase() === "websocket") { | |
| // // Accept the upgrade and attach room data if needed | |
| // return server.upgrade(req) ? undefined : new Response("Upgrade failed", { status: 500 }); | |
| // } | |
| // // Serve HTML UI for non-WebSocket requests | |
| // if (url.pathname === "/") { | |
| // 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> | |
| // var ws, currentRoom; | |
| // window.addEventListener('load', function() { | |
| // var scheme = location.protocol === 'https:' ? 'wss' : 'ws'; | |
| // var socketUrl = scheme + '://' + location.host + '/'; | |
| // ws = new WebSocket(socketUrl); | |
| // ws.onopen = function(){ log('🔌 Connected'); }; | |
| // ws.onmessage = function(ev){ | |
| // var m=JSON.parse(ev.data); | |
| // log('['+m.roomId+'] '+m.message); | |
| // }; | |
| // ws.onerror = function(e){ log('⚠️ WebSocket error'); }; | |
| // ws.onclose = function(c){ log('❌ Disconnected (code='+c.code+')'); }; | |
| // }); | |
| // function joinRoom(){ | |
| // var id = document.getElementById('room').value.trim(); | |
| // if(!id) return alert('Enter room ID'); | |
| // ws.send(JSON.stringify({ action:'join', roomId:id })); | |
| // currentRoom = id; log('➡️ Joined '+id); | |
| // } | |
| // function sendMsg(){ | |
| // var t = document.getElementById('msg').value.trim(); | |
| // if(!t) return; | |
| // if(!currentRoom) return alert('Join a room first'); | |
| // ws.send(JSON.stringify({ action:'post', roomId:currentRoom, message:t })); | |
| // document.getElementById('msg').value = ''; | |
| // } | |
| // function log(txt){ | |
| // var e=document.getElementById('log'); | |
| // e.innerHTML+='<div>'+txt+'</div>'; e.scrollTop=e.scrollHeight; | |
| // } | |
| // </script> | |
| // </body></html>`, { | |
| // headers: { "Content-Type": "text/html; charset=utf-8" } | |
| // }); | |
| // } | |
| // return new Response("Not Found", { status: 404 }); | |
| // }, | |
| // websocket: { | |
| // message(ws, raw) { | |
| // let msg; | |
| // try { msg = JSON.parse(raw); } catch { return; } | |
| // if (msg.action === "join" && msg.roomId) { | |
| // // Leave all rooms | |
| // for (const set of rooms.values()) set.delete(ws); | |
| // // Join target room | |
| // let set = rooms.get(msg.roomId); | |
| // if (!set) { | |
| // set = new Set(); | |
| // rooms.set(msg.roomId, set); | |
| // } | |
| // set.add(ws); | |
| // } | |
| // if (msg.action === "post" && msg.roomId && msg.message) { | |
| // const set = rooms.get(msg.roomId); | |
| // if (!set) return; | |
| // const payload = JSON.stringify({ | |
| // roomId: msg.roomId, | |
| // message: msg.message, | |
| // timestamp: Date.now(), | |
| // }); | |
| // for (const client of set) { | |
| // if (client.readyState === 1) { // 1 === OPEN | |
| // client.send(payload); | |
| // } | |
| // } | |
| // } | |
| // }, | |
| // close(ws) { | |
| // // Clean up on disconnect | |
| // for (const set of rooms.values()) set.delete(ws); | |
| // } | |
| // } | |
| // }); | |
| // console.log("✅ Bun realtime server running on port " + (Bun.env.PORT || 7860)); |