Socket.IO with Next.js
Next.js-এর সাথে Socket.IO — custom server, client component ও serverless caveat বাংলায়।
Next.js-এর সাথে Socket.IO ব্যবহার করা যায়, তবে একটি গুরুত্বপূর্ণ শর্ত আছে: Socket.IO-র দীর্ঘস্থায়ী server process দরকার, যা serverless function-এ সম্ভব নয়। তাই সাধারণত custom server বা আলাদা socket server ব্যবহার করা হয়।
শেখার লক্ষ্য
- কেন সাধারণ API route-এ Socket.IO host করা যায় না
- custom server দিয়ে Next.js + Socket.IO চালানো
- client component-এ socket lifecycle handle করা
- deployment-এর বাস্তবতা বোঝা
গুরুত্বপূর্ণ সতর্কতা
- Vercel-এর মতো serverless platform-এ WebSocket persistent connection ধরে রাখা যায় না — function-এর আয়ুক্ষণ কম
- তাই Next.js project-এ socket চালাতে custom Node server (self-hosted VPS, Docker, Railway, Render ইত্যাদি) বা আলাদা Socket.IO server ব্যবহার করুন
- Next.js app-এর বাইরে যখন আলাদা socket server, তখন client সরাসরি সেই server-এর URL-এ connect করে
পদ্ধতি ১: Custom Server
Next.js-এর নিজের request handler-এর সাথে একটি http.Server-এর উপর Socket.IO বসান।
// server.ts
import { createServer } from "node:http";
import next from "next";
import { Server } from "socket.io";
const dev = process.env.NODE_ENV !== "production";
const app = next({ dev });
const handle = app.getRequestHandler();
app.prepare().then(() => {
const httpServer = createServer(handle);
const io = new Server(httpServer, {
cors: { origin: "*" },
});
io.on("connection", (socket) => {
console.log("connected:", socket.id);
socket.on("client:message", (msg) => {
io.emit("server:message", msg);
});
});
httpServer.listen(3000, () => {
console.log("ready on http://localhost:3000");
});
});# package.json scripts
"scripts": {
"dev": "tsx server.ts",
"build": "next build",
"start": "NODE_ENV=production tsx server.ts"
}Client Component
Next.js-এ socket শুধু client component-এ (\"use client\") ব্যবহার হবে।
// app/chat/chat.tsx
"use client";
import { useEffect, useState } from "react";
import { io, type Socket } from "socket.io-client";
export default function Chat() {
const [socket, setSocket] = useState<Socket | null>(null);
const [messages, setMessages] = useState<string[]>([]);
useEffect(() => {
const s = io();
setSocket(s);
s.on("server:message", (msg: string) => {
setMessages((prev) => [...prev, msg]);
});
return () => {
s.disconnect();
};
}, []);
return (
<div>
<button onClick={() => socket?.emit("client:message", "হ্যালো")}>
পাঠান
</button>
<ul>{messages.map((m, i) => <li key={i}>{m}</li>)}</ul>
</div>
);
}socket কখনো module scope-এ তৈরি করবেন না (SSR-এ ভেঙে যাবে ও hot-reload-এ duplicate connection হবে)। সবসময় useEffect-এর ভিতরে তৈরি করুন এবং cleanup-এ disconnect() দিন।
পদ্ধতি ২: আলাদা Socket Server
Next.js API-কে REST-এর জন্য রাখুন, আর socket একটি স্বতন্ত্র server-এ (যেমন socket-server/) চালান। client-এ:
const socket = io(process.env.NEXT_PUBLIC_SOCKET_URL!, {
auth: { token },
});app/api/socket/route.ts-এ একবার new Server(...) বানালেও serverless-এ প্রতিটি request আলাদা instance-এ যেতে পারে — shared connection থাকে না। স্থায়ী Node server ছাড়া এটি নির্ভরযোগ্য নয়।
সাধারণ ভুল ও সমাধান
- Vercel-এ deploy করে socket খোঁজা — কাজ করবে না; আলাদা persistent host দরকার
\"use client\"না দেওয়া —useEffect, socket সবই client-only- cleanup না করা — route বদলে গেলে connection জমে leak;
return () => s.disconnect() withCredentialsও CORS মেলানো — auth cookie ব্যবহার হলে server-এ নির্দিষ্ট origin ওcredentials: true
Practice Task
- custom server-এ Next.js + Socket.IO চালিয়ে একটি echo event test করুন
- client component unmount-এ
disconnect()verify করুন (Network tab-এ) - একটি আলাদা socket server বানিয়ে Next.js client থেকে connect করুন
সম্পর্কিত অধ্যায়: Socket.IO with Express.js · Socket.IO with TypeScript · Building a Real-Time Chat Application