웹 소켓

ClassBinu·2024년 4월 6일

Node.js 교과서

목록 보기
16/19

웹 소켓

Socket.IO는 웹 소켓을 활용한 라이브러리임.
웹 소켓 그 자체가 아님!

WS 프로토콜

HTTP와 다르게 WS 프로토콜을 씀.
그 전에는 폴링으로 씀.(주기적으로 요청과 응답을 함)

//socket.js
const webSocket = require("ws");

module.exports = (server) => {
  const wss = new webSocket.Server({ server });

  wss.on("connection", (ws, req) => {
    const ip = req.headers["x-forwarded-for"] || req.socket.remoteAddress;
    console.log("새로운 클라이언트 접속", ip);
    ws.on("message", (message) => {
      console.log(message);
    });
    ws.on("error", (error) => {
      console.error(error);
    });
    ws.on("close", () => {
      console.log("클라이언트 접속 해제", ip);
      clearInterval(ws.interval);
    });
    const interval = setInterval(() => {
      if (ws.readyState === ws.OPEN) {
        ws.send("서버에서 클라이언트로 메시지를 보냅니다.");
      }
    }, 3000);
    ws.interval = interval;
  });
};

on은 이벤트를 등록하는 것!
웹 소켓은 이벤트를 기반으로 동작한다.

http와 ws는 같은 포트를 공유할 수 있음!

socket.IO

socket 모듈로 할 수 있지만, io 라이브러리를 쓰면 더 편하게 기능 구현 가능

// socket.js
const SocketIO = require("socket.io");

module.exports = (server) => {
  const io = new SocketIO.Server(server, { path: "/socket.io" });

  io.on("connection", (socket) => {
    const req = socket.request;
    const ip = req.headers["x-forwarded-for"] || req.socket.remoteAddress;
    console.log("새로운 클라이언트 접속!", ip, socket.id);
    socket.on("disconnect", () => {
      console.log("클라이언트 접속 해제", ip, socket.id);
      clearInterval(socket.interval);
    });
    socket.on("error", (error) => {
      console.error(error);
    });
    socket.on("reply", (data) => {
      console.log(data);
    });
    socket.interval = setInterval(() => {
      socket.emit("news", "Hello Socket.IO");
    }, 3000);
  });
};

node 내장 ws 모듈은 커스텀 이벤트 등록 불가능. 단순한 기능만 됨.
구현하려면 message 내용을 분석해서 이벤트를 분기 처리하는 식으로 애플리케이션 레벨에서 구현해야 함.
socket.io는 커스텀 이벤트 등록 가능

socket.io는 먼저 폴링 방식으로 서버와 연결(xhr)
그 다음 웹 소켓 사용 가능하면 웹 소켓으로 업그레이드

SSE

서버 센트 이벤트

웹 소켓을 양방향 통신
SSE는 서버 -> 클라이언트 단방향 통신

웹 소켓으로도 SSE 기능을 구현할 수 있지만,
양방향 통신이 필요 없는 경우는 SSE로도 충분

SSE와 웹 소켓은 동시에 사용 가능
SSE는 HTTP 프로토콜로 구현됨.

npm i sse

const SSE = require('sse');

module.exports = (server) => {
  const sse = new SSE(server);
  sse.on('connection', (client) => {
    setInterval(() => {
      client.send(Date.now().toString());
    }, 1000);
  });
};

스케줄링

npm i node-schedule

트랜잭션

시퀄라이저로 트랜잭션 적용하기

이거 맨날 개념적으로만 알고 있었는데, 코드 자체는 어렵지 않았음!

const { Sequelize } = require('sequelize');
const sequelize = new Sequelize('database', 'username', 'password', {
  host: 'localhost',
  dialect: 'mysql'
});

(async () => {
  try {
    // 트랜잭션 시작
    const transaction = await sequelize.transaction();

    try {
      // 트랜잭션 내에서의 데이터베이스 작업
      const user = await User.create({
        name: 'John Doe',
        email: 'john.doe@example.com'
      }, { transaction });

      const userProfile = await UserProfile.create({
        userId: user.id,
        bio: 'This is a bio.'
      }, { transaction });

      // 모든 작업이 성공적으로 완료되면, 트랜잭션 커밋
      await transaction.commit();
    } catch (error) {
      // 에러 발생 시 트랜잭션 롤백
      await transaction.rollback();
      throw error;
    }
  } catch (error) {
    console.error('Transaction failed', error);
  }
})();

0개의 댓글