7u.pl के लिए एक यूनिवर्सल WebSocket सर्वर का निर्माण
ध्यान दें: पोलिश संस्करण मूल है। यह अनुवाद एआई द्वारा तैयार किया गया है और इसमें मामूली त्रुटियां हो सकती हैं।

जैसे-जैसे हम 7u.pl इकोसिस्टम में अधिक इंटरैक्टिव माइक्रो-टूल्स जोड़ रहे हैं, पूरी तरह से अलग हो चुके उपकरणों के बीच रीयल-टाइम में स्थिति (state) को सिंक्रनाइज़ करने की आवश्यकता उत्पन्न हुई है।
उदाहरण के लिए: हमारे virtual-keyboard प्रोजेक्ट को एक स्मार्टफोन से एक मैक पर ब्राउज़र तक, और सीधे हार्डवेयर रेस्पबेरी पाई (Raspberry Pi) को ("क्लिक किया गया क्यू बटन") ईवेंट भेजना होता है, और यह दोनों पक्षों पर स्थानीय नेटवर्क प्रतिबंधों को बायपास करते हुए काम करता है।
प्रत्येक एप्लिकेशन के लिए अलग-अलग WebSocket लॉजिक बनाने के बजाय (जो जल्दी से इंफ्रास्ट्रक्चर के डुप्लीकेशन का कारण बनता है), हमने एक एकल, स्वतंत्र, बहुत "मूर्ख" संचार सर्वर बनाने का निर्णय लिया जो केवल एक ही काम करता है, लेकिन इसे निर्दोष रूप से करता है: यह रूम्स (rooms) को सुनता है और ग्राहकों के बीच संदेश प्रसारित (broadcast) करता है।
एक "मूर्ख" सर्वर की वास्तुकला (Architecture)
सार्वभौमिकता (universality) की कुंजी सर्वर पर कोई व्यावसायिक तर्क (business logic) नहीं होना है। सर्वर को यह नहीं पता कि "कीबोर्ड" क्या है, "माउस" क्या है, या नेटवर्क पर भेजे जाने वाले JSON की संरचना कैसी दिखती है।
प्रौद्योगिकी का चुनाव
हमने Socket.IO के साथ Node.js का निर्णय लिया। हालांकि नेटिव WebSockets (ws) हल्के होते हैं, Socket.IO में कनेक्शन को तथाकथित Rooms (कमरों) में व्यवस्थित करने के लिए एक उत्कृष्ट तंत्र है, जो पूरी तरह से विभिन्न एप्लिकेशन को अलग करने की हमारी आवश्यकता से मेल खाता है। इसके अलावा, यह हमें अस्थिर कनेक्शन वाले मोबाइल उपकरणों पर स्वचालित री-कनेक्शन की समस्या से मुक्ति दिलाता है।
संक्षेप में स्रोत कोड
पूरे सर्वर का कोर केवल io इंस्टेंस पर कुछ श्रोताओं (listeners) में निहित है:
io.on('connection', (socket) => {
// क्लाइंट को वर्चुअल रूम से जुड़ें
socket.on('join-room', (roomName) => {
socket.join(roomName);
});
// कमरे में दूसरों को एक संदेश प्रसारित करें (प्रेषक की अनदेखी)
socket.on('broadcast', ({ roomName, eventName, payload }) => {
socket.to(roomName).emit(eventName, payload);
});
// कमरे में सभी को एक संदेश प्रसारित करें (प्रेषक सहित)
socket.on('broadcast-all', ({ roomName, eventName, payload }) => {
io.to(roomName).emit(eventName, payload);
});
});बस इतना ही। सर्वर किसी भी वस्तु (payload) को स्वीकार करता है, एक कमरा (roomName) ढूंढता है, डेवलपर द्वारा निर्दिष्ट एक घटना (eventName) में इसे लपेटता है, और इसे बाकी ग्राहकों के लिए फेंक देता है।
CORS के माध्यम से सुरक्षा
हालाँकि सर्वर प्रेषित डेटा के बारे में कुछ नहीं जानता है, हम यह सुनिश्चित करना चाहते थे कि हमारा सार्वजनिक एंडपॉइंट (endpoint) आधे इंटरनेट के लिए मुफ़्त प्रॉक्सी सर्वर न बन जाए।
तथाकथित हैंडशेक (handshake) के शुरुआती चरण में कनेक्शन को सत्यापित करने के लिए मूल (Origin) हेडर को मान्य करने के लिए कार्यान्वयन को एक सख्त नियम की आवश्यकता है:
const io = new Server(httpServer, {
cors: {
origin: (origin, callback) => {
// ओरिजिन की अनुपस्थिति को अनुमति दें (IoT डिवाइस/स्क्रिप्ट)
if (!origin) return callback(null, true);
// अनुमत: *.7u.pl और स्थानीय वातावरण
const allowedOrigins = [
/^https?:\/\/((.*)\.)?7u\.pl$/,
/^http:\/\/localhost(:\d+)?$/,
/^http:\/\/127\.0\.0\.1(:\d+)?$/
];
if (allowedOrigins.some((regex) => regex.test(origin))) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
}
}
});कठोर स्ट्रिंग्स के बजाय रेगेक्स (Regex) का उपयोग करने के लिए धन्यवाद, जैसे sklep.7u.pl, साथ ही डेवलपर पोर्ट (उदाहरण के लिए, localhost:5173 Vite इकोसिस्टम द्वारा उपयोग किया जाता है) को प्रत्येक नए प्रोजेक्ट के लिए सर्वर को पुनरारंभ और पुन: कॉन्फ़िगर किए बिना, गतिशील रूप से अधिकृत किया जाता है।
परिनियोजन (Deployment) और रखरखाव (Docker)
सर्वर का वजन सिर्फ कुछ मेगाबाइट है। डॉकटर (Docker) छवि (image) node:20-alpine वातावरण के आधार पर बनाई गई थी।
FROM node:20-alpine
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install --only=production
COPY . .
EXPOSE 80
CMD ["npm", "start"]उत्पादन मशीन (production machine) पर, छवि (image) लोड बैलेंसर (NGINX/Cloudflare) के पीछे छिपी हुई है, जो अंतिम टीएलएस (TLS)/एसएसएल (SSL) प्रमाणपत्र समाप्ति (wss://sock.7u.pl) को संभालती है। इस सेटअप का अर्थ है कि नई आधारभूत संरचना (infrastructure) भविष्य के किसी भी संशोधन के लिए पूरी तरह से अदृश्य ("पारदर्शी") हो गई है।
सारांश और लाभ
वेबसॉकेट टर्न-अराउंड पॉइंट ("relay") को एक अलग रिपोजिटरी में स्थानांतरित करने से हमें इन चीजों से मुक्ति मिली:
- बैकएंड को पोर्ट सुनने के लिए मजबूर करना ताकि केवल "फ्रंटएंड" क्लाइंट एक दूसरे को देख सकें,
- प्रमाणीकरण (authentication) प्रणालियों को खरोंच से फिर से बनाना,
- परियोजनाओं में अनावश्यक तकनीकी ऋण (technical debt) बनाए रखना।
अब से, *.7u.pl डोमेन के तहत प्रत्येक आगामी इंटरैक्टिव प्रोजेक्ट आयात (import) की पांच पंक्तियों को जोड़ने के बाद ही रीयल-टाइम कार्यक्षमता प्राप्त करेगा। और वास्तव में अच्छी वास्तुकला (architecture) यही है।