Skip to main content
Glama
socket.ts4.53 kB
import WebSocket, { WebSocketServer } from 'ws'; import http from 'http'; // Store clients by channel const channels = new Map<string, Set<WebSocket>>(); function handleConnection(ws: WebSocket) { // Don't add to clients immediately - wait for channel join console.log("New client connected"); // Send welcome message to the new client ws.send(JSON.stringify({ type: "system", message: "Please join a channel to start chatting", })); ws.on('close', () => { console.log("Client disconnected"); // Remove client from their channel channels.forEach((clients, channelName) => { if (clients.has(ws)) { clients.delete(ws); // Notify other clients in same channel clients.forEach((client) => { if (client.readyState === WebSocket.OPEN) { client.send(JSON.stringify({ type: "system", message: "A user has left the channel", channel: channelName })); } }); } }); }); ws.on('message', (message: Buffer) => { try { console.log("Received message from client:", message.toString()); const data = JSON.parse(message.toString()); if (data.type === "join") { const channelName = data.channel; if (!channelName || typeof channelName !== "string") { ws.send(JSON.stringify({ type: "error", message: "Channel name is required" })); return; } // Create channel if it doesn't exist if (!channels.has(channelName)) { channels.set(channelName, new Set()); } // Add client to channel const channelClients = channels.get(channelName)!; channelClients.add(ws); // Notify client they joined successfully ws.send(JSON.stringify({ type: "system", message: `Joined channel: ${channelName}`, channel: channelName })); console.log("Sending message to client:", data.id); ws.send(JSON.stringify({ type: "system", message: { id: data.id, result: "Connected to channel: " + channelName, }, channel: channelName })); // Notify other clients in channel channelClients.forEach((client) => { if (client !== ws && client.readyState === WebSocket.OPEN) { client.send(JSON.stringify({ type: "system", message: "A new user has joined the channel", channel: channelName })); } }); return; } // Handle regular messages if (data.type === "message") { const channelName = data.channel; if (!channelName || typeof channelName !== "string") { ws.send(JSON.stringify({ type: "error", message: "Channel name is required" })); return; } const channelClients = channels.get(channelName); if (!channelClients || !channelClients.has(ws)) { ws.send(JSON.stringify({ type: "error", message: "You must join the channel first" })); return; } // Broadcast to all clients in the channel channelClients.forEach((client) => { if (client.readyState === WebSocket.OPEN) { console.log("Broadcasting message to client:", data.message); client.send(JSON.stringify({ type: "broadcast", message: data.message, sender: client === ws ? "You" : "User", channel: channelName })); } }); } } catch (err) { console.error("Error handling message:", err); } }); } // Create HTTP server const server = http.createServer((req, res) => { // Handle CORS res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); if (req.method === 'OPTIONS') { res.writeHead(200); res.end(); return; } res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('WebSocket server running'); }); // Create WebSocket server const wss = new WebSocketServer({ server }); wss.on('connection', handleConnection); const port = 3055; server.listen(port, () => { console.log(`WebSocket server running on port ${port}`); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/YelowFlash09/figma_mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server