কম্পিউটার টিউটোরিয়াল

Node.js, Socket.IO, এবং Redis দিয়ে স্কেলেবল রিয়েল-টাইম মাল্টিপ্লেয়ার টিক-ট্যাক-টো গেম বানান

Node.js, Socket.IO, এবং Redis দিয়ে স্কেলেবল রিয়েল-টাইম মাল্টিপ্লেয়ার টিক-ট্যাক-টো গেম বানান

এই টিউটোরিয়ালে, আমরা Node.js, Socket.IO, এবং Redis ব্যবহার করে একটি রিয়েল-টাইম মাল্টিপ্লেয়ার টিক-ট্যাক-টো গেম বিল্ড করব। এই গেম দুজন খেলোয়াড়কে আলাদা ব্রাউজার ট্যাব থেকে কানেক্ট হয়ে খেলতে দেবে, টার্ন অনুযায়ী খেলবে, এবং খেলার время রিয়েল-টাইম আপডেট দেখাবে। আমরা Redis ব্যবহার করব গেম স্টেট সিঙ্ক্রোনাইজেশন মাল্টিপল WebSocket সার্ভারের মাঝপথে ম্যানেজ করার জন্য, যা আমাদের অ্যাপ্লিকেশনকে স্কেলেবল করবে।

শেষে, আপনার কাছে একটি ফুলি ফাংশনাল গেম থাকবে রিয়েল-টাইম ক্যাপাবিলিটির সাথে এবং WebSockets এবং Redis ব্যবহার করে স্কেলেবল রিয়েল-টাইম অ্যাপ্লিকেশন বিল্ড করার একটি স olid বোঝাপড়া।

আপনি কী শিখবেন

  • Socket.IO কীভাবে ব্যবহার করতে হয় রিয়েল-টাইম কমিউনিকেশনের জন্য।

  • Redis Pub/Sub কীভাবে ব্যবহার করতে হয় গেম স্টেট মাল্টিপল ক্লায়েন্টের মাঝপথে সিঙ্ক্রোনাইজ করার জন্য।

  • স্কেলেবল WebSocket সার্ভার আর্কিটেকচার কীভাবে সেট আপ করতে হয়।

পূর্বশর্ত

শুরু করার আগে, নিচের موارد ইনস্টলড আছে কিনা নিশ্চিত করুন:

  • Node.js (v16 বা উচ্চতর)

  • Redis

  • Docker (অপশনাল, কন্টেইনারে Redis রান করার জন্য)

  • JavaScript, Node.js, এবং WebSockets-এর বেসিক জ্ঞান।

সূচিপত্র

  • প্রজেক্ট ওভারভিউ

  • স্টেপ ১: ডেভেলপমেন্ট এনভায়রনমেন্ট সেট আপ করা

  • স্টেপ ২: প্রজেক্ট সেট আপ করা

  • স্টেপ ৩: Redis-এ WebSocket সার্ভার ইমপ্লিমেন্ট করা

  • স্টেপ ৪: React ফ্রন্টএন্ড ইন্টারফেস ইমপ্লিমেন্ট করা

  • স্টেপ ৫: অ্যাপ্লিকেশন চালানো

  • স্টেপ ৬: রিয়েল-টাইমে Redis মেসেজ দেখা

  • ডেমো

  • উপসংহার

প্রজেক্ট ওভারভিউ

আমরা একটি রিয়েল-টাইম টিক-ট্যাক-টো গেম বিল্ড করব নিচের ফিচারগুলো সহ:

  • দুই খেলোয়াড় কানেক্ট होकर গেম খেলতে পারবে।

  • গেম বোর্ড রিয়েল-টাইমে আপডেট হবে আলাদা ব্রাউজার ট্যাবের মাঝপথে।

  • গেম বোর্ড ফুল হলে ভেনর ঘোষণা করবে বা ড্র declarar করবে।

আমরা ব্যবহার করব:

  • Node.js সাথে Socket.IO WebSocket কানেকশন হ্যান্ডেল করার জন্য।

  • Redis Pub/Sub ক্লায়েন্টের মাঝপথে গেম স্টেট সিঙ্ক্রোনাইজেশন ম্যানেজ করার জন্য।

স্টেপ ১: ডেভেলপমেন্ট এনভায়রনমেন্ট সেট আপ করা

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

স্টেপ ২: প্রজেক্ট সেট আপ করা

১. প্রজেক্ট ডিরেক্টরি তৈরি করা

mkdir tic-tac-toe
cd tic-tac-toe
npm init -y

২. ডিপেন্ডেন্সি ইনস্টল করা

npm install express socket.io redis dotenv

৩. এনভায়রনমেন্ট ভেরিয়েবল তৈরি করা

প্রজেক্ট রুটে একটি .env ফাইল তৈরি করুন নিচের কন্টেন্টসহ:

PORT=3000
REDIS_HOST=localhost
REDIS_PORT=6379

স্টেপ ৩: 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 ক্লায়েন্ট subscribe মোডে শুধু মেসেজ রিসিভ করতে পারে।

Redis চ্যানেল সাবস্ক্রাইব করার জন্য গেম আপডেটের জন্য, আমরা server.js-এ নিচের কোড যোগ করব:

// Redis চ্যানেল সাবস্ক্রাইব করুন গেম আপডেটের জন্য
await subClient.subscribe('game-moves', (message) => {
  gameState = JSON.parse(message);
  io.emit('gameState', gameState);
});
  • subClient.subscribe: game-moves চ্যানেলে মেসেজ লিসেন করে।

  • যখন একটি খেলোয়াড় মুভ করে, গেম স্টেট Redis-এ আপডেট হয়, এবং সব কানেক্টেড ক্লায়েন্টকে নতুন স্টেট জানানো হয়।

  • message প্যারামিটারটি গেম স্টেট ধারণ করে একটি স্ট্রিং হিসেবে। আমরা এটি পার্স করে জাভাস্ক্রিপ্ট অবজেক্ট বানাই এবং 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) ট্র্যাক করে।

    • বোর্ডটি ৯টি সেলের একটি অ্যারে হিসেবে রিপ্রেজেন্ট করা হয়েছে (প্রতিটি '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: এই ইভেন্টটি ট্রিগার হয় যখন একজন খেলোয়াড় একটি সেলে ক্লিক করে।

    • ভ্যালিডেশন: আমরা চেক করি সেলটি ইতিমধ্যে আকুপাইড কিনা বা গেম এন্ড হয়েছে কিনা মুভ করার আগে।

    • গেম স্টেট আপডেট করা: যদি মুভটি ভ্যালিড হয়, তবে আমরা বোর্ড আপডেট করি এবং টার্ন সুইচ করি।

  • আপডেটেড গেম স্টেট তারপর:

    1. Redis-এ পাবলিশ করা হয়: এটি নিশ্চিত করে যে সার্ভারের সব ইন্সট্যান্স সিঙ্কড থাকে।

    2. সকল ক্লায়েন্টে ব্রডকাস্ট করা হয়: এটি সব খেলোয়াড়ের জন্য গেম বোর্ড তৎক্ষণাৎ আপডেট করে।

গেম রিস্টার্ট হ্যান্ডেল করার জন্য, 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(): চেক করে সব সেল ফুল হয়েছে কিনা, ড্রো ইন্ডিকেট করে।

স্টেপ ৪: 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 দিয়ে ম্যানেজ করা হয় এবং এতে থাকছে:

      • বোর্ড (৯টি সেল)।

      • ফ্ল্যাগ xIsNext কারেন্ট খেলোয়াড়ের টার্ন ইন্ডিকেট করার জন্য।

      • ভেনর স্ট্যাটাস।

  • রিয়েল-টাইম আপডেট:

    • useEffect হুক:

      • সার্ভার থেকে gameState আপডেট লিসেন করে।

      • পরিবর্তন ডিটেক্ট হলে লোকাল গেম স্টেট আপডেট করে।

      • কম্পোনেন্ট আনমাউন্ট হলে WebSocket লিসেনার ক্লিন আপ করে।

  • খেলোয়াড়ের মুভ হ্যান্ডেল করা:

    • handleClick ফাংশন:

      • চেক করে একটি সেল ইতিমধ্যে আকুপাইড কিনা বা গেমে ভেনর আছে কিনা মুভ অনুমতি দেওয়ার আগে।

      • সার্ভারে makeMove ইভেন্ট পাঠায় ক্লিক করা সেল ইন্ডেক্সসহ।

  • গেম বোর্ড রেন্ডারিং:

    • renderCell ফাংশন বোর্ডের প্রতিটি সেলের জন্য একটি বাটন তৈরি করে।

    • বোর্ডটি ৩x৩ গ্রিড হিসেবে ডিসপ্লে করা হয়।

  • গেম রিস্টার্ট:

    • "Restart Game" বাটন restartGame ইভেন্ট ইমিট করে সব খেলোয়াড়ের জন্য গেম বোর্ড রিসেট করার জন্য।
  • ইউজার ইন্টারফেস:

    • একটি সিম্পল এবং ইন্টারেক্টিভ লে-আউট যা খেলোয়াড়দের টার্ন নেওয়া এবং রিয়েল-টাইম আপডেট দেখার অনুমতি দেয়।

স্টেপ ৫: অ্যাপ্লিকেশন চালানো

ব্যাকএন্ড শুরু করা

ব্যাকএন্ড সার্ভার শুরু করতে, একটি নতুন টার্মিন্যাল উইন্ডো খুলুন এবং নিচের কমান্ডগুলো চালান:

cd tic-tac-toe
npm start

ফ্রন্টএন্ড শুরু করা

React ফ্রন্টএন্ড সার্ভার শুরু করতে, একটি নতুন টার্মিন্যাল উইন্ডো খুলুন এবং নিচের কমান্ডগুলো চালান (ব্যাকএন্ড সার্ভার যে টার্মিন্যালে চলছে সেটা ব্যবহার করবেন না, কারণ গেম চালানোর জন্য দুটোই একসাথে রানিং থাকতে হবে)।

cd tic-tac-toe-client
npm run dev

গেম এক্সেস করা

আপনার ব্রাউজার খুলুন এবং নেভিগেট করুন:

https://localhost:5173

স্টেপ ৬: রিয়েল-টাইমে 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 দিয়ে রেসপন্সিভ ফ্রন্ট-এন্ড বিল্ড করা।

নেক্সট স্টেপস

  • প্লেয়ার অথেন্টিকেশন যোগ করুন।

  • চ্যাট ফিচার ইমপ্লিমেন্ট করুন।

  • স্কেলেবিলিটির জন্য আপনার অ্যাপ্লিকেশনকে একটি ক্লাউড প্রোভাইডারে ডিপ্লয় করুন।

হ্যাপি কোডিং!

নিঃশুল্ক কোডিং শিখুন। freeCodeCamp-এর ওপেন সোর্স কারিকুলাম ৪০,০০০-এর বেশি মানুষকে ডেভেলপার হিসেবে জব পেতে সাহায্য করেছে। শুরু করুন

  1. PHP-তে imagecrop() ফাংশন ব্যবহার করে ছবি কীভাবে দিয়ে गये রেক্ট্যাঙ্গেলে ক্রপ করবেন?

  2. অ্যান্ড্রয়েডে PriorityBlockingQueue-এ remove() কীভাবে ব্যবহার করবেন?

  3. Matplotlib-এ কাস্টম কালারম্যাপ দিয়ে imshow()-এ ডেটা প্লট করুন

  4. React Native, AWS Lambda এবং সার্ভারলেস রেডিস দিয়ে হাই-পারফরম্যান্স মোবাইল লিডারবোর্ড তৈরি করুন