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));