상세 컨텐츠

본문 제목

[Node.js 1] 12장 웹 소켓으로 실시간 데이터 전송하기

23-24/Node.js 1

by YUZ 유즈 2024. 1. 12. 10:00

본문

728x90

 

 

 

 

 

 

  • 웹 소켓 이해하기

- 웹 소켓은 실시간 양방향 데이터 전송을 위한 기술로, WS라는 프로토콜을 사용한다.

- Socket.IO는 웹 소켓을 편리하게 사용할 수 있도록 도와주는 라이브러리이다.

 

 

 

  • ws 모듈로 웹 소켓 사용하기
  "dependencies": {
    "cookie-parser": "^1.4.6",
    "dotenv": "^16.0.1",
    "express": "^4.18.1",
    "express-session": "^1.17.0",
    "morgan": "^1.9.1",
    "nunjucks": "^3.2.1",
    "ws": "^8.2.3"
  },

- 위 코드를 참고하여 package.json 파일을 작성하고, 패키지를 설치한다.

- https://github.com/zerocho/nodejs-book의 소스코드를 참고하여 .env와 app.js, routes/index.js 파일을 작성한다.

- npm i ws 명령어를 통해 ws 모듈을 설치한다.

- app.js에서 웹 소켓을 익스프레스 서버에 연결하고, socket.js 파일을 작성한다.

- 웹 소켓 서버에 이벤트 리스너를 붙인다. 웹 소켓은 이벤트 기반으로 작동된다.

- 클라이언트와 서버가 웹 소켓 연결을 맺을 때 connection 이벤트가 발생한다.

- 웹 소켓 객체에는 message, error, close 이벤트 리스너를 연결한다.

- 웹 소켓에는 connecting(연결 중), open(열림), closing(닫는 중), closed(닫힘) 네 가지 상태가 존재한다.

 

 

 

  • Socket.IO 사용하기

- npm i socket.io@2 명령어를 통해 Socket.IO를설치한다.

- socket.io 패키지를 불러와 익스프레스 서버와 연결한다. 그리고 이벤트 리스너를 붙인다.

- 클라이언트가 접속하면 connection 이벤트가 발생하고, 콜백으로 소켓 객체를 제공한다.

- ws 모듈과 다르게 http 프로토콜을 사용한다.

- Socket.IO는 먼저 폴링 방식으로 서버와 연결하고, 웹 소켓을 사용할 수 있으면 웹 소켓으로 업그레이드한다.

 

 

  • 실시간 GIF 채팅방 만들기

- npm i mongoose multer axios color-hash 명령어를 통해 필요한 모듈을 설치한다.

- 채팅방 스키마를 만든다. 방 제목, 최대 수용 인원, 방장, 비밀번호, 생성 시간 등을 받는다.

- 채팅 스키마를 만든다. 채팅방 아이디, 채팅을 한 사람, 채팅 내역, GIF 이미지 주소, 채팅 시간을 저장한다. 채팅방 아이디 필드는 채팅방 스키마와 연결한다.

- schema/index.js에서 몽고디비와 연결한다.

- app.js에서 서버와 몽구스를 연결한다.

- https://github.com/zerocho/nodejs-book의 소스코드를 참고하여 html 파일과 css 파일들을 작성한다.

- main.html에서 io.connect 메서드의 주소 뒤에 /room 네임스페이스를 붙인다.

  - /room 네임스페이스를 붙이면 서버에서 /room 네임스페이스를 통해 보낸 데이터만 분류해 받을 수 있다.

- chat.html에서는 io.connect 메서드의 주소 뒤에 /chat 네임스페이스를 붙인다.

- socket.js에 웹 소켓 이벤트를 연결한다.

  - of 메서드는 Socket.IO에 네임스페이스를 부여하는 메서드이다.

  - /room 네임스페이스와 /chat 네임스페이스 각각에 이벤트 리스너를 붙인다.

 

 

 

  • 미들웨어와 소켓 연결하기

- Socket.IO에서 세션에 접근하기 위해 app.js와 socket.js 간에 express-session 미들웨어를 공유한다.

- socket.js에서 io.use 메서드에 미들웨어를 장착한다.

- socket.js에서 socket.to(방 아이디) 메서드로 특정 방에 데이터를 보낼 수 있다.

- https://github.com/zerocho/nodejs-book의 소스코드를 참고하여 라우터를 작성한다.

  - GET / 라우터는 채팅방 목록 메인 화면을 렌더링한다.

  - POST /room 라우터는 채팅방을 만드는 라우터이다.

  - GET /room/:id 라우터는 채팅방을 렌더링하는 라우터이다.

  - DELETE /room/:id 라우터는 채팅방을 삭제하는 라우터이다.

 

 

 

  • 채팅 구현하기

- chat.html 파일에 서버에서 보내는 채팅 데이터를 받을 소켓 이벤트 리스너를 작성한다.

- routes/index.js에서 GET /room/:id 라우터를 방 접속 시 기존 채팅 내역을 불러오도록 수정한다.

  - 채팅을 데이터베이스에 저장하는 POST /room/:id/chat 라우터를 생성한다.

 

 

 

  • 프로젝트 마무리하기

- GIF 이미지를 전송하기 위해 chat.html에서 이미지를 선택해 업로드하는 이벤트 리스너를 추가한다.

- 이미지 파일을 데이터베이스에 저장하는 POST /room/:id/gif 라우터를 작성한다.

- app.js에서 이미지를 제공할 폴더를 express.static 미들웨어로 연결한다.

 

 

 

 


 

빈칸 채우기 문제 - (빈칸을 드래그해서 답을 확인해 보세요)

 

1. 웹 소켓과 HTTP는 같은 포트를 사용할 수 (  있다.  )
2. 웹 소켓은 실시간 (  양  )방향 데이터 전송을 위한 기술이다.

3. 웹 소켓을 지원하지 않는 브라우저에서 실시간 통신을 구현하기 위해 (   Socket.IO  )를 사용할 수 있다.

4.  네임스페이스  )를 통해 서버에서 보낸 데이터를 분류해 받을 수 있다.

5. (   of  ) 메서드는 Socket.IO에 네임스페이스를 부여하는 메서드이다.

6. Socket.IO에서  세션  )에 접근하기 위해 app.js와 socket.js 간에 (  express-session  ) 미들웨어를 공유한다.

7. GIF 이미지를 전송하기 위해 app.js에서 이미지를 제공할 폴더를 (  express.static  ) 미들웨어로 연결한다.

 

 

코드 문제 

 

 1. 다음 이벤트 리스너의 빈칸에 알맞은 코드를 작성하시오. (웹 소켓 연결 시 발생할 이벤트)

// socket.js

...

const wss = new WebSocket.Server({ server });

  wss.on(/*여기에 코드를 작성*/, (ws, req) => { // 웹소켓 연결 시
    const ip = req.headers['x-forwarded-for'] || req.socket.remoteAddress;
    console.log('새로운 클라이언트 접속', ip);
    ws.on('message', (message) => { // 클라이언트로부터 메시지
      console.log(message.toString());
    });
   
...

 답 :

더보기
'connection'

(더보기로 확인)

 

 

 

2. Socket.IO에 /room 네임스페이스와 /chat 네임스페이스를 부여하는 코드를 작성하시오. (변수명은 각각 room과 chat으로 한다.)

// socket.js

const SocketIO = require('socket.io');

module.exports = (server, app) => {
  const io = SocketIO(server, { path: '/socket.io' });
  app.set('io', io);
  
  /*여기에 코드를 작성*/
   
...

답:

더보기

const room = io.of('/room');
const chat = io.of('/chat');

(더보기로 확인)

 


출처: 조현영 ,  『Node.js 교과서』 개정판 3판, 길벗, 12.1장 ~ 12.7장

Node.js #1

Editor : 호박

728x90

관련글 더보기