TIL

내일배움캠프 11주차 금요일 TIL

news0516 2025. 1. 10. 19:52

웹소켓을 통한 실시간 알림을 위해 서버 측 웹소켓 구성과 임시 html파일을 구성 후 테스트하였다.

import express from 'express';
import dotenv from 'dotenv';
import cookieParser from 'cookie-parser';
import { Server } from 'socket.io';
import http from 'http'; // Node.js 기본 내장 모듈
import cors from 'cors'; // CORS 모듈 import 추가
import fs from 'fs/promises'; // 파일 시스템 모듈로, Promise 기반으로 파일을 읽고 쓸 수 있게 해줌
...
// express 객체 생성
const app = express();
// express http 서버 생성
const server = http.createServer(app);
// 생성된 http 서버에 Socket.IO를 바인딩 >> 실시간 통신 기능을 추
const io = new Server(server);
const PORT = 3000;
...
app.use('/public', express.static('public')); // public 폴더 내의 정적 파일을 제공
app.use(cors()); // CORS 미들웨어 추가 >>  다른 도메인에서의 요청을 허용
...
// 소켓 연결 관리
// 클라이언트가 서버에 연결될 때 호출
io.on('connection', (socket) => {
  // 클라이언트에서 유저 타입, 유저 Id data로 전달
  socket.on('register', (data) => {
    socket.role = data.role; // 역할 저장 (owner 또는 user)
    socket.ownerId = data.ownerId;
    socket.userId = data.userId;

    if (socket.role === 'owner') {
      console.log(socket.role, 'connected', {
        ownerId: socket.ownerId,
      });
    } else if (socket.role === 'user') {
      console.log(socket.role, 'connected', {
        userId: socket.userId,
      });
    }
    socket.on('status_update', (data) => {
      if (socket.role === 'owner') {
        // 유저들에게 상태 업데이트 전달
        io.emit('status_update', { status: data.status });
      }
    });
	// 연결 종료 알림
    socket.on('disconnect', () => {
      if (socket.role === 'owner') {
        console.log(socket.role, ' user disconnected', {
          ownerId: socket.ownerId,
        });
      } else if (socket.role === 'user') {
        console.log(socket.role, ' user disconnected', {
          userId: socket.userId,
        });
      }
    });
  });
});
// 사장 주문현황 html 파일 클라이언트에 제공
app.get('/owner', async (req, res) => {
  try {
    const data = await fs.readFile('./public/ownerOrder/owner.html');
    res.writeHead(200, { 'Content-Type': 'text/html' });
    res.end(data);
  } catch (err) {
    res.status(500).send('파일을 로드할 수 없습니다.');
  }
});

// 유저 주문현황 html 파일 클라이언트에 제공
app.get('/user', async (req, res) => {
  try {
    const data = await fs.readFile('./public/userOrder/user.html');
    res.writeHead(200, { 'Content-Type': 'text/html' });
    res.end(data);
  } catch (err) {
    res.status(500).send('파일을 로드할 수 없습니다.');
  }
});

server.listen(PORT, () => {
  console.log(PORT, '포트로 서버가 열렸어요!');
});

Express와 Socket.IO를 사용하여 주문 현황 관리를 사장이 고객에게 실시간으로 알릴 수 있는 서버를 구축하였다.

<script src="/socket.io/socket.io.js"></script>
<script>
        const ownerId = 1 /* 테스트용 코드 */
        const socket = io();

        // 사장 역할 등록
        socket.emit('register', { role: 'owner', ownerId: ownerId });

        // 상태 업데이트 전송
        const updateStatus = () => {
            const status = document.getElementById('status').value;
            socket.emit('status_update', { status });
        };
 </script>

//////////////
 
<script src="/socket.io/socket.io.js"></script>
 <script>
        const userId = 2 /* 테스트용 코드 */
        const socket = io();

        // 유저 역할 등록
        socket.emit('register', { role: 'user', userId: userId });

        // 상태 업데이트 수신
        socket.on('status_update', (data) => {
            document.getElementById('status').innerText = `배달 상태: ${data.status}`;
        });
</script>

임시 구성한 사장 주문현황, 고객 주문현황 html파일의 스크립트 부분을 구성하였다.
<script src="/socket.io/socket.io.js"></script>에서 Socket.IO 라이브러리를 로드하고, 이를 통해 이벤트나 데이터를 실시간으로 업데이트 한다.

 


이후 해당 html을 결제목록 페이지로 만들어 로그인 성공 시 쿠키로 보내지는 데이터를 활용해 db의 테이블들과 연계하는 과정이 필요하다.