इस ट्यूटोरियल में, हम Node.js, Socket.IO, और Redis का उपयोग करके एक रीयल-टाइम मल्टीप्लेयर टिक-टैक-टो गेम बनाएंगे। यह गेम दो खिलाड़ियों को विभिन्न ब्राउज़र टैब से कनेक्ट करने, बारी-बारी से खेलने, और खेलते समय रीयल-टाइम अपडेट देखने की अनुमति देता है। हम Redis का उपयोग कई WebSocket सर्वरों में गेम स्टेट सिंक्रनाइज़ेशन को प्रबंधित करने के लिए करेंगे, जिससे हमारा एप्लिकेशन स्केलेबल बनेगा।
अंत तक, आपके पास रीयल-टाइम क्षमताओं के साथ एक पूरी तरह से कार्यात्मक गेम होगा और WebSockets और Redis का उपयोग करके स्केलेबल रीयल-टाइम एप्लिकेशन बनाने का एक ठोस समझ होगी।
आप क्या सीखेंगे
Socket.IO का उपयोग रीयल-टाइम संचार के लिए कैसे करें।
Redis Pub/Sub का उपयोग कई क्लाइंट में गेम स्टेट को सिंक्रनाइज़ करने के लिए कैसे करें।
स्केलेबल WebSocket सर्वर आर्किटेक्चर कैसे सेटअप करें।
पूर्वापेक्षाएँ
शुरू करने से पहले, सुनिश्चित करें कि आपके पास निम्न इंस्टॉल हैं:
Node.js (v16 या उच्चतर)
Redis
Docker (वैकल्पिक, कंटेनर में Redis चलाने के लिए)
JavaScript, Node.js, और WebSockets का बुनियादी ज्ञान।
विषय सूची
प्रोजेक्ट अवलोकन
चरण 1: अपने डेवलपमेंट वातावरण को सेटअप करना
चरण 2: प्रोजेक्ट सेटअप करना
चरण 3: Redis के साथ WebSocket सर्वर लागू करना
चरण 4: React फ्रंटएंड इंटरफ़ेस लागू करना
चरण 5: एप्लिकेशन चलाना
चरण 6: रीयल-टाइम में Redis मैसेज देखना
डेमो
निष्कर्ष
प्रोजेक्ट अवलोकन
हम निम्नलिखित विशेषताओं के साथ एक रीयल-टाइम टिक-टैक-टो गेम बनाएंगे:
दो खिलाड़ी कनेक्ट हो सकते हैं और एक गेम खेल सकते हैं।
गेम बोर्ड विभिन्न ब्राउज़र टैब में रीयल-टाइम में अपडेट होता है।
जब बोर्ड भर जाता है तो गेम विजेता की घोषणा करता है या ड्रॉ घोषित करता है।
हम उपयोग करेंगे:
Node.js Socket.IO के साथ WebSocket कनेक्शन संभालने के लिए।
Redis Pub/Sub क्लाइंट में गेम स्टेट सिंक्रनाइज़ेशन प्रबंधित करने के लिए।
चरण 1: अपने डेवलपमेंट वातावरण को सेटअप करना
Node.js इंस्टॉल करना
सुनिश्चित करें कि आपके सिस्टम पर Node.js इंस्टॉल है:
node -v
यदि आपके पास यह इंस्टॉल नहीं है, तो Node.js से डाउनलोड करें।
Redis इंस्टॉल करना
आप Redis को स्थानीय रूप से इंस्टॉल कर सकते हैं या इसे Docker कंटेनर में चला सकते हैं।
macOS (Homebrew का उपयोग करके)
नीचे दिए गए कमांड चलाने से पहले सुनिश्चित करें कि आपके सिस्टम पर Homebrew इंस्टॉल है:
brew install redis
brew services start redis
निम्न कमांड के साथ Redis कंटेनर चल रहा है या नहीं सत्यापित करें:
redis-cli ping
आपको देखना चाहिए:
PONG
Docker का उपयोग करके Redis चलाना
docker run --name redis-server -p 6379:6379 -d redis
जांचें कि Redis चल रहा है या नहीं:
docker exec -it redis-server redis-cli ping
चरण 2: प्रोजेक्ट सेटअप करना
1. प्रोजेक्ट डायरेक्टरी बनाएं
mkdir tic-tac-toe
cd tic-tac-toe
npm init -y
2. डिपेंडेंसी इंस्टॉल करें
npm install express socket.io redis dotenv
3. एनवायरनमेंट वेरिएबल बनाएं
अपने प्रोजेक्ट रूट में निम्न सामग्री के साथ एक .env फ़ाइल बनाएं:
PORT=3000
REDIS_HOST=localhost
REDIS_PORT=6379
चरण 3: Redis के साथ WebSocket सर्वर लागू करना
इस चरण में, हम एक WebSocket सर्वर सेटअप करेंगे जो Node.js, Socket.IO, और Redis का उपयोग करके रीयल-टाइम गेम इंटरैक्शन को संभालता है। यह सर्वर गेम स्टेट को प्रबंधित करेगा, खिलाड़ी की चाल को संभालेगा, और Redis Pub/Sub का उपयोग करके कई क्लाइंट में सिंक्रनाइज़ेशन सुनिश्चित करेगा।
हम कोड के प्रत्येक खंड को तोड़ देंगे ताकि आप समझ सकें कि सब कुछ कैसे एक साथ फिट होता है।सर्वर कोड व्याख्या
server.js नामक एक फ़ाइल बनाएं और निम्न कोड जोड़ें:
import dotenv from 'dotenv';
import express from 'express';
import http from 'http';
import { Server } from 'socket.io';
import { createClient } from 'redis';
dotenv.config(); // .env फ़ाइल से एनवायरनमेंट वेरिएबल लोड करें
const app = express();
const server = http.createServer(app);
const io = new Server(server, {
cors: {
origin: "https://localhost:5173",
methods: ["GET", "POST"],
}
});
dotenv: संवेदनशील जानकारी जैसे पोर्ट और कुंजियों को सुरक्षित रखने के लिए
.envफ़ाइल से एनवायरनमेंट वेरिएबल लोड करता है।express: HTTP रिक्वेस्ट को संभालने के लिए एक बेसिक Express सर्वर सेटअप करता है।
http: हम Node के बिल्ट-इन
httpमॉड्यूल का उपयोग करके एक HTTP सर्वर बनाते हैं, जिसे हम Socket.IO के साथ WebSocket संचार के लिए उपयोग करेंगे।Socket.IO: यह लाइब्रेरी सर्वर और क्लाइंट के बीच रीयल-टाइम, द्विदिश संचार को सक्षम करती है।
CORS कॉन्फिगरेशन: हमारे फ्रंटएंड से क्रॉस-ओरिजिन रिक्वेस्ट की अनुमति देता है जो
localhost:5173पर चल रहा है।
फिर, Redis पब्लिशर और सब्सक्राइबर क्लाइंट बनाने के लिए, हम server.js में निम्न कोड जोड़ेंगे:
// Redis क्लाइंट इनिशियलाइज़ करें
const pubClient = createClient();
const subClient = createClient();
await pubClient.connect();
await subClient.connect();
हम Redis का उपयोग कनेक्टेड क्लाइंट के बीच रीयल-टाइम डेटा सिंक्रनाइज़ेशन को संभालने के लिए करते हैं।
pubClient: मैसेज पब्लिश करने के लिए उपयोग किया जाता है (जैसे गेम स्टेट अपडेट)।
subClient: मैसेज सब्सक्राइब करने के लिए उपयोग किया जाता है (अपडेट के लिए सुनता है)।
- connect(): Redis सर्वर के साथ एक कनेक्शन स्थापित करता है।
इस पैराडाइम में, एक क्लाइंट का उपयोग अपडेट पब्लिश करने के लिए किया जाता है, और दूसरा अपडेट सब्सक्राइब करता है। यह ब्लॉकिंग व्यवहार से बचने में मदद करता है, चूंकि सब्सक्राइब मोड में Redis क्लाइंट केवल मैसेज प्राप्त कर सकते हैं।
गेम अपडेट के लिए Redis चैनल्स को सब्सक्राइब करने के लिए, हम server.js में निम्न कोड जोड़ेंगे:
// गेम अपडेट के लिए Redis चैनल सब्सक्राइब करें
await subClient.subscribe('game-moves', (message) => {
gameState = JSON.parse(message);
io.emit('gameState', gameState);
});
subClient.subscribe:
game-movesचैनल पर मैसेज सुनता है।जब भी कोई खिलाड़ी चाल चलता है, तो गेम स्टेट को Redis में अपडेट किया जाता है, और सभी कनेक्टेड क्लाइंट को नई स्थिति की सूचना दी जाती है।
messageपैरामीटर में गेम स्टेट एक स्ट्रिंग के रूप में होता है। हम इसे एक JavaScript ऑब्जेक्ट में पार्स करते हैं और Socket.IO का उपयोग करके अपडेटेड स्थिति को ब्रॉडकास्ट करते हैं।
अगला, गेम स्टेट और फ़ंक्शन को परिभाषित करने के लिए, हम server.js में निम्न कोड जोड़ेंगे:
// प्रारंभिक गेम स्टेट परिभाषित करें
let gameState = {
board: Array(9).fill(null),
xIsNext: true,
};
// गेम को रीसेट करने का फ़ंक्शन
function resetGame() {
gameState = {
board: Array(9).fill(null),
xIsNext: true,
};
}
gameState: बोर्ड की वर्तमान स्थिति और किसकी बारी है (
xIsNext) को ट्रैक करता है।बोर्ड को 9 सेल की सरणी के रूप में दर्शाया गया है (प्रत्येक 'X', 'O', या
nullहो सकता है)।xIsNextफ्लैग निर्धारित करता है कि किस खिलाड़ी की बारी है।
resetGame(): बोर्ड और टर्न इंडिकेटर को उनकी प्रारंभिक स्थिति में रीसेट करता है, जिससे एक नया गेम शुरू हो सके।
अगला, WebSocket कनेक्शन को संभालने के लिए, आइए server.js में निम्न कोड जोड़ें:
io.on('connection', (socket) => {
console.log('New client connected:', socket.id);
// नव कनेक्टेड क्लाइंट को वर्तमान गेम स्टेट भेजें
socket.emit('gameState', gameState);
io.on('connection')इवेंट तब ट्रिगर होता है जब एक नया क्लाइंट कनेक्ट होता है।socket.id: प्रत्येक कनेक्टेड क्लाइंट के लिए एक यूनिक आइडेंटिफायर।
हम तुरंत नए क्लाइंट को वर्तमान
gameStateभेजते हैं ताकि वे वर्तमान बोर्ड देख सकें।
खिलाड़ी की चाल को संभालने के लिए, हम server.js में निम्न कोड जोड़ेंगे:
// खिलाड़ी की चाल को संभालें
socket.on('makeMove', (index) => {
// चाल चलने से रोकें यदि सेल पहले से लिया गया है या गेम समाप्त हो गया है
if (gameState.board[index] || calculateWinner(gameState.board)) return;
// बोर्ड अपडेट करें और बारी बदलें
gameState.board[index] = gameState.xIsNext ? 'X' : 'O';
gameState.xIsNext = !gameState.xIsNext;
// अपडेटेड गेम स्टेट को Redis पर पब्लिश करें
pubClient.publish('game-moves', JSON.stringify(gameState));
io.emit('gameState', gameState);
});
makeMove: यह इवेंट तब ट्रिगर होता है जब कोई खिलाड़ी किसी सेल पर क्लिक करता है।
वैलिडेशन: हम चाल चलने से पहले जांचते हैं कि सेल पहले से भरा हुआ है या गेम समाप्त हो गया है।
गेम स्टेट अपडेट करना: यदि चाल वैध है, तो हम बोर्ड को अपडेट करते हैं और बारी बदलते हैं।
अपडेटेड गेम स्टेट तब:
Redis पर पब्लिश किया जाता है: यह सुनिश्चित करता है कि सर्वर के सभी इंस्टेंस सिंक में रहें।
सभी क्लाइंट को ब्रॉडकास्ट किया जाता है: यह सभी खिलाड़ियों के लिए गेम बोर्ड को तुरंत अपडेट करता है।
गेम रीस्टार्ट को संभालने के लिए, हम server.js में निम्न कोड जोड़ेंगे:
// गेम रीस्टार्ट को संभालें
socket.on('restartGame', () => {
resetGame();
io.emit('gameState', gameState);
});
क्लाइंट डिस्कनेक्शन को संभालने के लिए, हम server.js में निम्न कोड जोड़ेंगे:
socket.on('disconnect', () => {
console.log('Client disconnected:', socket.id);
});});
अंत में, गेम के लॉजिक को प्रोसेस करने के लिए, हम server.js में निम्न फ़ंक्शन जोड़ेंगे:
// जांचने का फ़ंक्शन कि क्या कोई विजेता है
function calculateWinner(board) {
const lines = [
[0, 1, 2], [3, 4, 5], [6, 7, 8],
[0, 3, 6], [1, 4, 7], [2, 5, 8],
[0, 4, 8], [2, 4, 6]
];
for (let [a, b, c] of lines) {
if (board[a] && board[a] === board[b] && board[a] === board[c]) {
return board[a];
}
}
return null;
}
function isBoardFull(board) {
return board.every((cell) => cell !== null);
}
calculateWinner(): जांचता है कि बोर्ड पर कोई विनिंग कॉम्बिनेशन है या नहीं।
isBoardFull(): जांचता है कि क्या सभी सेल भरे हुए हैं, जो ड्रॉ को इंगित करता है।
चरण 4: React फ्रंटएंड इंटरफ़ेस लागू करना
इस चरण में, हम अपने टिक-टैक-टो गेम के लिए एक सरल और इंटरैक्टिव React फ्रंटएंड बनाते हैं। यह फ्रंटएंड खिलाड़ियों को WebSocket सर्वर से कनेक्ट करने, चाल चलने, और गेम बोर्ड को रीयल-टाइम में अपडेट होते देखने की अनुमति देता है।
App.jsx में, निम्न कोड जोड़ें:
import React, { useEffect, useState } from 'react';
import io from 'socket.io-client';
const socket = io('https://localhost:3000');
function App() {
const [gameState, setGameState] = useState({
board: Array(9).fill(null),
xIsNext: true,
winner: null
});
useEffect(() => {
socket.on('gameState', (state) => {
setGameState(state);
});
return () => socket.off('gameState');
}, []);
const handleClick = (index) => {
if (gameState.board[index] || gameState.winner) return;
socket.emit('makeMove', index);
};
const renderCell = (index) => (
);
return (
Multiplayer Tic-Tac-Toe
{[...Array(9)].map((_, i) => renderCell(i))}
);
}
export default App;
यहां React ऐप का ब्रेकडाउन है:
WebSocket कनेक्शन:
- फ्रंटएंड
socket.io-clientका उपयोग करके सर्वर से कनेक्शन स्थापित करता है।
- फ्रंटएंड
स्टेट मैनेजमेंट:
गेम स्टेट (
gameState) को React केuseStateके साथ प्रबंधित किया जाता है और इसमें शामिल हैं:बोर्ड (9 सेल)।
वर्तमान खिलाड़ी की बारी को इंगित करने के लिए फ्लैग xIsNext।
विजेता स्थिति।
रीयल-टाइम अपडेट:
useEffectहुक:सर्वर से
gameStateअपडेट के लिए सुनता है।परिवर्तन का पता चलने पर स्थानीय गेम स्टेट को अपडेट करता है।
कंपोनेंट अनमाउंट होने पर WebSocket लिसनर को क्लीन अप करता है।
खिलाड़ी की चाल को संभालना:
handleClickफ़ंक्शन:चाल की अनुमति देने से पहले जांचता है कि कोई सेल पहले से भरा हुआ है या गेम में विजेता है।
क्लिक किए गए सेल इंडेक्स के साथ सर्वर को
makeMoveइवेंट भेजता है।
गेम बोर्ड रेंडरिंग:
renderCellफ़ंक्शन बोर्ड पर प्रत्येक सेल के लिए एक बटन बनाता है।बोर्ड को 3x3 ग्रिड का उपयोग करके प्रदर्शित किया जाता है।
गेम रीस्टार्ट:
- "Restart Game" बटन सभी खिलाड़ियों के लिए गेम बोर्ड को रीसेट करने के लिए
restartGameइवेंट उत्सर्जित करता है।
- "Restart Game" बटन सभी खिलाड़ियों के लिए गेम बोर्ड को रीसेट करने के लिए
यूज़र इंटरफ़ेस:
- एक सरल और इंटरैक्टिव लेआउट जो खिलाड़ियों को बारी-बारी से खेलने और रीयल-टाइम में अपडेट देखने की अनुमति देता है।
चरण 5: एप्लिकेशन चलाना
बैकएंड शुरू करना
बैकएंड सर्वर शुरू करने के लिए, एक नया टर्मिनल विंडो खोलें और निम्न कमांड चलाएं:
cd tic-tac-toe
npm start
फ्रंटएंड शुरू करना
React फ्रंटएंड सर्वर शुरू करने के लिए, एक नया टर्मिनल विंडो खोलें और नीचे दिए गए कमांड चलाएं (उसी का उपयोग न करें जिस पर बैकएंड सर्वर चल रहा है, क्योंकि आपको गेम चलाने के लिए दोनों को एक साथ चलाने की आवश्यकता है)।
cd tic-tac-toe-client
npm run dev
गेम एक्सेस करना
अपना ब्राउज़र खोलें और नेविगेट करें:
https://localhost:5173
चरण 6: रीयल-टाइम में Redis मैसेज देखना
गेम चलने के दौरान, आप Redis मैसेज देख सकते हैं ताकि रीयल-टाइम गेम स्टेट अपडेट देख सकें।
एक टर्मिनल खोलें और चलाएं:
redis-cli SUBSCRIBE game-moves
यह गेम अपडेट प्रदर्शित करेगा:
1) "message"
2) "game-moves"
3) "{"board":["X",null,"O",null,"X",null,null,null,null],"xIsNext":false}"
हर बार जब कोई चाल चली जाती है या गेम स्टेट बदलता है, तो सर्वर अपडेटेड गेम स्टेट को game-moves चैनल पर पब्लिश करता है। redis-cli का उपयोग करके, आप इन अपडेट को रीयल-टाइम में मॉनिटर कर सकते हैं, जैसे गेम खेला जा रहा है।
डेमो
इस डेमो में, आप टिक टैक टो गेम को स्थानीय रूप से चलते हुए देखेंगे, जो खिलाड़ियों के बारी-बारी से खेलने पर रीयल-टाइम अपडेट प्रदर्शित करता है।
गेमप्ले टर्न स्विचिंग, बोर्ड अपडेट, और गेम स्टेट घोषणाओं (विजेता या ड्रॉ) जैसी विशेषताओं को प्रदर्शित करता है। यह दर्शाता है कि गेम WebSocket संचार का लाभ कैसे उठाता है एक सहज, इंटरैक्टिव अनुभव प्रदान करने के लिए।
निष्कर्ष
बधाई हो, आपने Node.js, Socket.IO, और Redis का उपयोग करके एक रीयल-टाइम मल्टीप्लेयर टिक-टैक-टो गेम को सफलतापूर्वक बनाया है। यहां आपने क्या सीखा:
Socket.IO का उपयोग करके रीयल-टाइम WebSocket संचार।
Redis Pub/Sub का उपयोग करके गेम स्टेट मैनेजमेंट।
React के साथ एक रिस्पॉन्सिव फ्रंट-एंड बनाना।
अगले कदम
खिलाड़ी प्रमाणीकरण जोड़ें।
चैट फीचर लागू करें।
स्केलेबिलिटी के लिए अपने एप्लिकेशन को क्लाउड प्रोवाइडर पर डिप्लॉय करें।
हैप्पी कोडिंग!