본문 바로가기
개발/Next.js

Socket.io 를 활용한 상태값 주기적 체크

by oneday-lifeDev 2025. 1. 9.
반응형

Replicate 에서 Training 하면서 겪은 일

외부 API를 활용하여 , AI 이미지 학습을 시키고 있는 와중에 , 학습을 하는 시간이 생각보다 길어져서 , 이걸 클라이언트 화면에서 화면을 구현하는데 있어서 주기적으로 상태 체크하는 방법을 찾던 중, Cron, SetInterval 같은 스케쥴링을 생각을 했었다. 위에 두 방식으로 하는걸로 생각했을때 , 즉각적인 상태 반영이 불가능 하는 방면, 불필요한 부하가 걱정이 되어서 , 고민이 깊어질 시기 동료 개발자에게 현재 고충에 있어서 물어보게 되었다.

Socket.io 를 활용한 ** 하트비트 **

이게 왜 실시간 상태를 체크하는게 중요한 이유가 있었다. Replicate 에서는 학습, 생성된 이미지에 있어서 결과 이미지 URL 을 제공하지만
제한 시간이라는게 존재했다.

이걸 Cron , SetInterval 을 통해서 가능한 시간내로 핸들링을 하면 결과 URL 을 DB 에 저장하는데 있어서 해결은 할 수 있지만 기능상
문제가 생길것만 같아서 동료에게 Socket.io 를 활용한 ** HearBeat ** 방법을 생각해보면 된다고 해서 구글에서 사례들을 찾아보며
나와 같은 상황인 개발자분들이 굉장히 많았다.

  1. 설계 및 구현

2.1 설계 목표

  • 클라이언트는 Socket.IO를 통해 서버에 주기적으로 상태 확인 요청(heartbeat)을 보냄
  • 서버는 받은 요청을 처리하고, 외부 API 호출이나 데이터베이스 상태 확인 작업을 수행.
  • 처리 결과를 클라이언트로 즉시 전송.

2.2 기술 스택

  • Next.js : API Route를 사용하여 Socket.IO 서버를 설정.
  • Socket.IO : 클라이언트와 서버 간 실시간 통신 구현
  • Node.js : 서버 환경에서 상태 확인 및 외부 API 호출

2.3 구현 코드

 

1) 서버 설정 (API Route)

다음 코드는 Next.js src/pages/api/socket/index.ts

 

import { Server as SocketIOServer } from "socket.io";
import type { NextApiRequest, NextApiResponse } from "next";


export default function handler(req: NextApiRequest, res: NextApiResponse)
{ const server = res.socket?.server; // Socket.IO 서버 초기화 if (server && !server?.io)
{ console.log("Initializing Socket.IO server..."); 

const io = new SocketIOServer(server, 
{ path: "/api/socket", cors: { origin: "*", // 제한된 도메인만 허용하도록 수정 권장 }, });
server.io = io; 
// 클라이언트 연결 처리 
io.on("connection", (socket) => { 
console.log("Client connected:", socket.id);
// 클라이언트에서 하트비트 이벤트 수신 
socket.on("heartbeat", (data) => { console.log("Heartbeat received:", data);
// 상태값 처리 후 클라이언트에 결과 전송 
socket.emit("statusUpdate", { message: "Status updated", data, }); }); 
// 연결 해제 이벤트
socket.on("disconnect", () => { console.log("Client disconnected:", socket.id); }); }); }
else { 
console.log("Socket.IO server is already running.");
} 
res.end(); 
}

 

 

 

2)클라이언트 설정

다음 코드는 Next.js src/pages/StatusChecker.tsx

import { useEffect } from "react"; 
import { io, Socket } from "socket.io-client";
let socket: Socket; 

const StatusChecker = () => { 
useEffect(() => { 
// Socket.IO 클라이언트 연결 
socket = io("http://localhost:3000",
{ path: "/api/socket", }); 
// 서버로 하트비트 전송 (5초마다)
const interval = setInterval(() => { 
socket.emit("heartbeat", { clientId: "12345" });
}, 5000); 

// 서버로부터 상태 업데이트 수신
socket.on("statusUpdate", (data) => { 
console.log("Status update from server:", data);
}); 

// 연결 해제 및 타이머 정리 
return () => { clearInterval(interval); socket.disconnect(); }; 

}, []); 

return

}

Socket.IO 기반 상태 체크 클라이언트

; }; export default StatusChecker;

3. Socket.IO와 CRON 작업 비교

특징 CRON 작업 Socket.IO
실시간성 작업 완료 후 알림을 기다려야 함 즉시 상태를 업데이트 및 전달 가능
주기적 작업 설정 서버에서 작업 주기 고정 클라이언트 주도로 유연하게 설정 가능
서버 부하 작업량이 많아질 경우 부하 발생 가능 연결 유지 비용은 있으나 이벤트 기반 처리
구현 복잡도 단순히 스케줄링 설정 클라이언트-서버 간 양방향 통신 구현 필요

이 방식을 선택한 이유

  • 실시간성 필요: 작업 상태가 업데이트되면 즉시 클라이언트에 반영해야 했기 때문에, CRON 작업보다는 Socket.IO가 적합했습니다.
  • 유연성: 클라이언트에서 하트비트를 전송하여 필요할 때만 작업을 수행할 수 있으므로 서버 리소스를 효율적으로 사용할 수 있었습니다.
  • 확장성: 여러 클라이언트가 연결된 상태에서도 이벤트 기반으로 각각의 상태를 관리할 수 있습니다.
반응형

'개발 > Next.js' 카테고리의 다른 글

Next.js + Graphql  (0) 2025.08.22