JavaScript पर WebSocket के साथ उन्नत कार्य: प्रोटोटाइप से प्रोडक्शन तक
\nWebSocket एक प्रोटोकॉल है जो एक स्थायी TCP कनेक्शन के माध्यम से क्लाइंट और सर्वर के बीच पूर्ण-द्वैध संचार प्रदान करता है। पिछले लेखों में, हमने मूल बातें कवर कीं: कनेक्शन स्थापित करना, संदेश भेजना और सरल चैट। हालांकि, वास्तव में विश्वसनीय और स्केलेबल रियल-टाइम एप्लिकेशन (ऑनलाइन गेम, ट्रेडिंग प्लेटफॉर्म, सहयोगी संपादन सिस्टम) बनाने के लिए, उन्नत तकनीकों में महारत हासिल करना आवश्यक है। इस सामग्री में, हम Node.js पर प्रोडक्शन-ग्रेड WebSocket सर्वर के आर्किटेक्चर पर विचार करेंगे, जिसमें स्केलिंग, स्थिति प्रबंधन, प्रमाणीकरण और त्रुटि प्रबंधन शामिल है।
\n\n1. उन्नत सर्वर आर्किटेक्चर और रूम प्रबंधन
\nसबसे सरल WebSocket सर्वर (ws लाइब्रेरी पर आधारित) सभी क्लाइंट को एक वैश्विक ऑब्जेक्ट में संभालता है। वास्तविक परियोजनाओं में, तार्किक अलगाव की आवश्यकता होती है - रूम और चैनल।
RoomManager वर्ग का उपयोग करके आर्किटेक्चर के एक उदाहरण पर विचार करें:
const WebSocket = require('ws');\n\nclass RoomManager {\n constructor() {\n this.rooms = new Map(); // roomName -> Set<WebSocket>\n }\n\n join(ws, roomName) {\n if (!this.rooms.has(roomName)) {\n this.rooms.set(roomName, new Set());\n }\n this.rooms.get(roomName).add(ws);\n ws.room = roomName; // सॉकेट पर रूम सहेजें\n }\n\n leave(ws) {\n if (ws.room && this.rooms.has(ws.room)) {\n this.rooms.get(ws.room).delete(ws);\n if (this.rooms.get(ws.room).size === 0) {\n this.rooms.delete(ws.room);\n }\n }\n }\n\n broadcast(roomName, message, excludeWs = null) {\n if (!this.rooms.has(roomName)) return;\n this.rooms.get(roomName).forEach(client => {\n if (client !== excludeWs && client.readyState === WebSocket.OPEN) {\n client.send(JSON.stringify(message));\n }\n });\n }\n}\n\n// उपयोग\nconst wss = new WebSocket.Server({ port: 8080 });\nconst roomManager = new RoomManager();\n\nwss.on('connection', (ws) => {\n ws.on('message', (data) => {\n const msg = JSON.parse(data);\n switch (msg.type) {\n case 'join':\n roomManager.join(ws, msg.room);\n break;\n case 'message':\n roomManager.broadcast(ws.room, { user: msg.user, text: msg.text }, ws);\n break;\n }\n });\n\n ws.on('close', () => roomManager.leave(ws));\n});\nयह कोड पृथक चैट या गेम सत्र बनाने की अनुमति देता है। कनेक्शन बंद करने की हैंडलिंग पर ध्यान दें - मेमोरी लीक को रोकने के लिए यह महत्वपूर्ण है।
\n\n2. स्केलिंग: क्लस्टरीकरण और Redis Pub/Sub
\nएक Node.js प्रक्रिया एक से अधिक CPU कोर का कुशलतापूर्वक उपयोग नहीं कर सकती है। स्केलिंग के लिए, हम अंतर्निहित cluster मॉड्यूल का उपयोग करते हैं। हालांकि, एक समस्या उत्पन्न होती है: WebSocket कनेक्शन एक विशिष्ट वर्कर से बंधे होते हैं। किसी अन्य वर्कर से जुड़े उपयोगकर्ता को संदेश कैसे भेजें?
समाधान - एक बाहरी संदेश ब्रोकर, जैसे Redis Pub/Sub।
\nconst cluster = require('cluster');\nconst http = require('http');\nconst { Server } = require('ws');\nconst redis = require('redis');\n\nconst REDIS_CHANNEL = 'ws:messages';\n\nif (cluster.isMaster) {\n // कोर की संख्या के अनुसार वर्कर चलाएं\n const numCPUs = require('os').cpus().length;\n for (let i = 0; i < numCPUs; i++) {\n cluster.fork();\n }\n\n cluster.on('exit', (worker) => {\n console.log(`Worker ${worker.process.pid} died`);\n cluster.fork(); // पुनरारंभ\n });\n} else {\n // Worker\n const server = http.createServer();\n const wss = new Server({ server });\n\n // Redis से कनेक्ट करें\n const pub = redis.createClient();\n const sub