본문 바로가기
Runtime/Node.js

28. 웹소켓

by 김엉배 2023. 4. 30.
728x90
반응형

 

1.  웹소켓이란
  •  하나의 TCP 접속에 전이중 통신 채널을 제공하는 컴퓨터 통신 프로토콜로 클라이언트와 서버 간의 양방향 통신을 가능하게 하며,
      실시간 데이터 전송을 할 수 있게 해 준다.
      즉, 클라이언트와 서버 간 소켓 연결을 유지해서 언제든지 양방향 통신이 가능하도록 하는 기술이다.

  • 실무에서 웹소켓 기술을 사용하는 사례
    - 지도 : 지도상에 움직이는 특정 객체의 위치를 실시간으로 표기해야 하는 경우 (카카오 T의 실시간 위치, 배달의 민족 라이더 위치
                표시, 구글지도에서 움직이는 내 위치 표시 등)
    - 대시보드 : 기업의 실시간 매출 지표, 성과 지표 등을 대시보드로 구성해서 사용 (매출 성과 대시보드, KPI 대시보드 등)
    - 실시간 지표 : 주식, 환율 등 실시간 변화하는 수치를 제공하는 경우

2. 웹소켓 서버 구현

→ Node.js에서 웹소켓 구현을 위해 사용되는 대표적인 모듈은 socket.io

  • socket.io 설치
npm install socket.io

 

  • app_socket.io 파일 생성 후 코드를 작성
const express = require("express");
const { createServer } = require("http");
const { Server } = require("socket.io");

const io = new Server(httpServer);

httpServer.listen(3000, () => {
  console.log('서버가 실행되었습니다.');
});

 

  • 클라이언트가 socket.io 서버에 접속하면 connection 이벤트가 발생. io 객체는 socket.io 서버와 연결된 전체 클라이언트와 메시지를 송수신하는 인터랙션을 위한 객체이다. connection 이벤트가 발생하면 이벤트 핸들러 함수로 socket 객체가 전달된다.
io.on('connection', (socket) => {

});

 

  • 클라이언트가 전송한 메시지를 수신하거나 접속한 클라이언트에게 메시지를 전송할 수 있다.
    (현재 접속되어 있는 클라이언트로부터 메시지를 수신하기 위해서는 socket 객체의 on() 함수를 사용)
//클라이언트에서 서버로 메시지 전달 시 지정한 이벤트명(event_name)과 동일한 이름으로 socket 객체의 on()
//함수를 정의
socket.on('event_name', (data) => {
	console.log(data); // 클라이언트로부터 전달된 메시지
});

 

  • 서버에서 클라이언트로 메시지를 전달하는 함수는 다음과 같다.
// 접속된 모든 클라이언트에게 메시지를 전송
io.emit('event_name', msg);

// 메시지를 전송할 클라이언트에게만 메시지를 전송
socket.emit('event_name', msg);

// 메시지를 전송한 클라이언트를 제외한 나머지 클라리언트 모두에게 메시지를 전송
socket.broadcast.emit('event_name', msg);

// 지정된(id) 특정 클라이언트에게만 메시지를 전송
io.to(id).emit('event_name', msg);

 

  • 클라이언트의 접속이 종료되면 disconnect 이벤트가 발생
socket.io('disconnect', () => {
	// socket 연결이 종료했을 때
});

 

  • CORS 처리가 필요한 경우는 cors 옵션을 사용해서 처리할 수 있다.
const io = require('socket.io')(server, {
	cors: { // CORS 처리
    origin: 'http://localhost:8080', // 허용할 호스트
    methods: ['GET', 'POST'] // 허용할 HTTP 메소드 정의
 }
});

 

  • 웹소켓 이벤트 처리를 위해 app_socket.js 코드 작성
const express = require("express");
const { createServer } = require("http");
const { Server } = require("socket.io");
const cors = require('cors');

const app = express();
const httpServer = createServer(app);


const corsOptions = {
  origin: 'http://localhost:5500', // 허용할 도메인 설정
  optionsSuccessStatus: 200 
}

app.use(cors(corsOptions)) // cors를 모든 라우터에 적용

const io = new Server(httpServer, { 
    cors: { // CORS 처리
    origin: 'http://localhost:5500',  // 허용할 호스트
    methods: ['GET', 'POST'] // 허용할 HTTP 메소드 정의
  }
 });

io.on('connection', (socket) => { 
  socket.on('disconnect', () => {
    // socket 연결이 종료됐을 때
  });

  // 클라이언트에서 서버로 메시지 전달 시 지정한 이벤트명(event_name)과 동일한 이름으로 socket 객체의 on 함수를 정의
  socket.on('client2server', (data) => {
    console.log(data); // 클라이언트로 부터 전달된 메시지
  });
});

const sendMsgToClient = () => {
  setInterval(() => {
    // 데이터가 변경이 되었는지 코드 구현
    // 데이터가 변경이 되었으면 클라이언트로 변경된 데이터 전송
    io.emit('server2client', {code:`item${Math.random()}`, price:Math.random()});
  }, 1000);
}

// /socket 라우트로 접속하면 1초 마다 데이터 변경 여부 체크 후 변경이 되었다면 변경된 데이터 전송 
app.get('/socket', (req, res) => {
  sendMsgToClient(); // 클라이언트로 메시지 전송 함수 호출
  res.send('메시지 전송 시작');
});

httpServer.listen(3000, () => {
  console.log('서버가 실행됐습니다. http://localhost:3000');
});

 

3.  웹소켓 클라이언트 구현

 

  • Vue.js 혹은 React에서 npm으로 설치할 때는 다음 명령어를 사용
npm install sokcet.io-client

 

  • app.socket.html 파일 생성 후 코드를 다음과 같이 작성
<!DOCTYPE html>
<html>
  <head>
    <title>Document</title>
  </head>
  <body>
    <input type="text" id="msg" value="" />
    <button onclick="sendMsg();">전송</button>
    <button onclick="receiveMsg();">메시지 수신 시작</button>
    <script
      src="https://cdn.socket.io/4.2.0/socket.io.min.js"
      integrity="sha384-PiBR5S00EtOj2Lto9Uu81cmoyZqR57XcOna1oAuVuIEjzj0wpqDVfD0JA9eXlRsj"
      crossorigin="anonymous"
    ></script>

    <script>
      const socket = io("http://localhost:3000"); // 도메인이 다른 경우

      socket.on("connect", () => {
        // 소켓 연결이 되면
        console.log(socket.id); // 소켓 아이디 출력
      });

      socket.on("server2client", (msg) => {
        // 서버로 부터 전송된 메시지 출력
        console.log(msg);
      });

      // 클라이언트에서 서버로 메시지 전송
      function sendMsg() {
        let msg = document.getElementById("msg").value;

        socket.emit("client2server", msg);
      }

      function receiveMsg() {
        // 서버로 메시지 수신 요청
        fetch("http://localhost:3000/socket", {
          method: "GET",
          headers: {
            "Content-Type": "application/json",
          },
        }).then((response) => {
          console.log(response);
        });
      }
    </script>
  </body>
</html>
728x90
반응형

'Runtime > Node.js' 카테고리의 다른 글

30. forever  (2) 2023.05.01
29. 크롤링  (0) 2023.04.30
27. 엑셀 파일 처리(엑셀 파일 생성)  (4) 2023.04.26
26. 엑셀 파일 처리(엑셀 파일 내용 수정)  (3) 2023.04.24
25. 엑셀 파일 처리(엑셀 파일 읽기)  (4) 2023.04.24