본문 바로가기

내일배움캠프_개발일지/Node.js 기초

Node.js 심화 - 2

__________________________________________________

 

1-4  소켓이란 무엇인가?

 

=>  < 3.2 Socket.io 02 >

3.2 Socket.io : Socket에 대해 이해하고, socket.io 라이브러리를 이용해 express 서버를 구현한다.

 

 

 

소켓 이란 ?

=> 

1) 소켓의 역할

 

현실로 비유하자면 마치 벽에 있는 콘센트 구멍과 비슷.

소켓은 콘센트 구멍과 같은 “연결부” 에 해당. 마치 전기를 쓰기 위해 반드시 콘센트를 구멍에 꽂아야 하는 것 처럼.

 

우리가 네트워크에서 데이터를 송수신하기 위해 반드시 거쳐야 하는 연결부에 해당

 

 

2) 소켓의 종류

 

소켓의 역할은 언제나 같지만 종류는 여러가지가 있어. 대표적으로 TCP, UDP 프로토콜을 사용하는 2가지의 소켓.

아주 일반적으로는 안정적인 데이터 송수신을 위해 TCP 소켓을 사용하는 경우가 대부분이지만, 

일부 패킷이 손실되어도 괜찮거나 빠른 전송 속도가 필요한 경우 UDP 소켓을 사용하기도.

 

 

어쨌든 소켓이란 걸 매개로 해서 데이터를 전달하고, 전달 받는거야.

 

 

 

패킷 이란 ? 

=>

네트워크 소켓이 현실의 콘센트와 비슷하다면, 패킷은 쉽게 말해 콘센트 배선에 흐르는 전기와 비슷.

소켓을 통해 송수신하는 데이터 덩어리 하나가 한개의 패킷이라고 표현

 

 

 

 

웹 소켓 이란?

=> 

실시간 웹 서비스를 제공하기 위해 만들어진 Socket 이라고 생각하면 편해.

 

만약 실시간으로 데이터나 이미지 등이 바뀌어야 한다? 

사용자가 이벤트를 발생시켰을 때, 구체적으로는 특정 유저가 다른 유저에게 메세지를 보냈을 때

그 메세지를 받게 될 유저는 사이트를 새로 고침 하지 않더라도 실시간으로 메세지를 전달 받을 수 있도록 하는 것.

이러한 기능들을 웹 소켓이라 부를 수 있어.

 

→ MDN에서 제공하는 웹소켓의 하위 호환성을 확인해봐. 참고자료

 

 

 

socket.io 란?

=> 

자바스크립트를 사용해 웹소켓을 사용하길 원한다면 가장 많이 사용되는 라이브러리.

 

그러나 이 라이브러리는 순수한 웹소켓 기술만 이용한 라이브러리가 아냐.

왜? 사실 웹 소켓 이라는 기술은 모든 브라우저에 적용되는 기술이 아니야.

따라서 모든 사용자를 고려할 경우 실 시간성 기능을 구현 하기는 어려워 져.

 

이 어려움을 해결하기 위해 socket.io는,

웹소켓을 사용할 수 없는 브라우저인 경우 서버에서 데이터를 일정 간격마다 받아오는 polling 기능으로 실시간 기능 구현을 가능하게 해줘.

 

 

 

socket.io는 웹소켓과 다르다?

=> 

엄밀히 따지면 socket.io는 웹소켓을 포함하여, 

웹소켓을 사용하지 못하는 환경에서도 웹소켓과 비슷하게 사용이 가능하도록 구현 해놓은 라이브러리.

 

 

 

 

 

 

 

 

 

__________________________________________________

 

1-5  socket.io 사용해보기

 

=>  < 3.2 Socket.io 03 >

3.2 Socket.io : Socket에 대해 이해하고, socket.io 라이브러리를 이용해 express 서버를 구현한다.

 

 

 

폴더 : kimminsoo -> sparta -> node_js -> learning -> third_step -> socket_prac

파일 : index.html, app.js

 

 

 

1.

Npm 패키지 설정 및 모듈 설치

——

npm init -y

npm i socket.io -S

——

 

 

 

2.

index.html 내부 코드 구성 중 script 

——

 

<head>

    <meta charset="UTF-8" />

    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

    // socket.io 를 사용하기 위한 스크립트를 다운받아 사용하는 부분.

    <title>Hello Socket.io!</title>

</head>

 

 

    <script>

      const socket = io("ws://localhost:3000"); // 웹 소켓 접속.

      socket.on("connect", () => { // 웹 소켓에 접속했을 때 어떤 식으로 동작하는 가.

        socket.send("Hello!");

      });

 

      socket.on("message", (data) => { // 메세지를 받았을 때 어떤 식으로 동작하는 가.

        console.log(data);

      });

    </script>

——

=> 프론트엔드에서 socket.io를 사용할 수 있도록,

script 태그로 socket.io 파일을 불러와 서버에 연결 요청하는 코드가 포함되어 있어.

 

 

 

 

3.

서버에서 socket.io 연결 준비.

 

——

// app.js

 

const io = require("socket.io")(3000, {

    cors: {

      origin: "*",

      methods: ["GET", "POST"],

    },

});

  

io.on("connection", (socket) => {

    console.log("새로운 소켓이 연결됐어요!");

  

    socket.on("message", (data) => {

      console.log(data);

    });

        /*

        html 에서 

        socket.on("connect", () => {

            socket.send("Hello!");

        });

        즉, connect 가 되었을 때(브라우저가 서버에 접속했을 때) socket.send() 로 메세지를 서버에 보낸다는 뜻.

        서버에서는 socket.on("message") 함수가 send() 메소드의 호출을 받아서 "message" 이벤트를 발생시킨 것.

        */

});

 

——

=> 공식 문서에 있는 내용을 따라서 시도.

sockey.io 를 리콰이어로 가져올 건데, 그럼 이렇게 가져온 소켓io 는 어떤 포트를 사용할 것인가. 3000을 사용할 것이다.

 

cors 란?

origin 과 methods 라는 키를 가지고 있어.

origin 은, 어떤 사용자들에게만 서버에 접속이 가능하도록 리소스를 제한한다. * 일 경우 모든 사람들에게 cors 를 열어 주겠다.

 

methods 란?

이 경우 get, post 두 메소드만 열어주겠다 라는 뜻.

 

io.on(“connection”, (socket) => {})이란?

소켓이 연결이 되어 있는데, 어떤 식으로 연결할 것인가.

특정 사용자가 "connection" 이벤트를 발생시켰을 때 우선 console 을 띄워.

 

그 다음으로 socket.on(“message”, (data) => {}) 는?

만약 message 라는 소켓에 데이터가 들어왔을 때 어떻게 할 것이냐 라는 뜻. 즉 message 라는 이벤트가 발생했을 때 처리법.

 

 

 

 

 

6.

Node app.js 실행.

->

index.html 을 직접 더블클릭 해서 크롬 브라우저에 띄우기.

이 상태에서 개발자 도구를 켜서 network 카테고리를 보고 있는 채로 새로고침을 누르면 socket.io 가 자동으로 다운된 것을 확인할 수 있어.

=> 사실 서버가 켜진 상태에서 직접 index.html 파일을 열어도 io.on(‘“connection”) 이벤트가 발생.

단 새로고침을 해야지 sockect.io 를 다운 받아오더라.

 

 

——

  • 백엔드에서 연결 확인하기

——

 

 

 

——

  • 프론트엔드에서 연결 확인하기

——

 

 

 

 

— 서버에서 데이터를 보내는 코드 작성법 —

——

io.on("connection", (socket) => {

  socket.send("Hello!");

 

  socket.on("message", (data) => {

    console.log(data);

  });

});

——

 

 

 

 

 

7.

ndex.html 파일에 커스텀 이벤트 핸들링 코드 추가하기

 

——

// index.html

 

 

socket.on("customEventName", (data) => {

        console.log(data);

      });

——

=> “customEventName” 이라는 이름으로 서버측에서 데이터를 송신했을 때,

socket.io 가 깔려있는 브라우저에서 그 데이터를 받아서 콘솔로 찍겠다.

 

 

 

 

8.

서버의 커스텀 이벤트로 데이터 발행하기

 

socket.emit("이벤트이름", "데이터") 이렇게 함수를 호출하면 특정 이벤트특정 데이터를 보낼 수 있어.

서버에서 사용자가 접속하였을 때, customEventName에 해당하는 커스텀 이벤트가 전달되게 아래 코드를 입력.

 

——

// app.js

 

const io = require("socket.io")(3000, {

    cors: {

      origin: "*",

      methods: ["GET", "POST"],

    },

});

  

io.on("connection", (socket) => {   

    /*

    이게 언제 일어나는데? 

    const socket = io("ws://localhost:3000"); 이 html 에서 명시되면서.

    브라우저에서 변수가 명시됨과 동시에 io.on("connection",) 이벤트가 발생.

 

    서버에서 connection 이벤트가 발생하면 console.log("새로운 소켓이 연결됐어요!"); 를 찍어.

 

    한 편 서버측의 connection 이벤트를 감지한 브라우저는, 이후 연쇄적으로 socket.on("connect", ) 을 실행시켜서 

    socket.send("Hello!"); 를 실행.

    서버측은 socket.on("message",) 라는 함수로 브라우저 측에서 발생한 "message" 이벤트로부터 data 를 받아서 콘솔에 출력.

 

    브라우저와 서버의 socekt.on() 이라는 메소드는 기본적으로 수동적.

    첫 번째 인자의 이벤트가 발생한다면, 해당 이벤트로 송신한 데이터를 수신해서 콜백 함수로 동작을 처리한다.

 

    아래에 명시된 커스텀 이벤트 핸들링 코드 

                => socket.emit("customEventName", "this is custom event data");

    emit() 이 능동적으로 "이 이벤트가 발생했을 때 값을 보낸다" 라고 선언.

    그리고 해당 emit() 은 io.on("connection", ) 이벤트 안에 있지.

            => io.on() 이 내부적으로 '특정 사용자' 를 인지할 수 있어.

            즉 서버는 emit()으로 "customEventName" 라는 이벤트를 미리 정의해 둔거야. 

            근데 그 이벤트가 io.on("connection") 안에 있다보니 바로 emit을 떼려버리는 것이고.

    프론트에서는 socket.on("customEventName", ) 라고 명시하면 "customEventName" 이벤트가 발생하여

    데이터를 받아서 내부 콜백 함수를 처리하겠지.

 

    서버가 const io = require("socket.io")(http, {cors: {},}); 로 io 명시

        -> 클라이언트에서 const socket = io("ws://localhost:3000"); 로 서버측의 socket.io 를 가져와

        -> 서버의 io.on("connection", ) 커넥션 이벤트 발생. on() 으로 미리 정의해 뒀다가 해당 이벤트가 발생하면 수신.

        -> 클라이언트의 socket.on("connect", () => { socket.send("Hello!"); });

            클라이언트가 socket을 선언하고 서버 측에서 io.on("connection")이 발생하면 이에 따라 체이닝으로

            클라이언트가 socket.on("connect") 소켓 커넥트 이벤트를 감지하고는 socket.send() 로 메시지를 보내

        -> 서버측에서 미리 선언되어 있던 socket.on("message", (data) => {console.log(data);}); 는,

            클라이언트의 send() 를 감지하여 .on("message", ) 로 수신하고는 해당 콜백 함수를 실행.

    

    즉, socket.on("event", () => {}) 는 해당 "event" 라는 이벤트가 발생했을 때 그 이벤트가 발생하면서 전달한 데이터를

    받아서 콜백 함수 안에서 처리하겠다 라고 사전에 미리 선언해 둔 로직.

 

    socket.send("Hello!"); 는 기본적으로 socket.on("message") 로 send() 를 받아.

    socket.emit("customEventName", "this is custom event data"); 의 경우 커스텀 이벤트 핸들링인데,

    마찬가지로 socket.on("customEventName") 로 데이터를 수신 받아서 콜백 함수로 로직을 처리할 수 있지. 

    */

    

    console.log("새로운 소켓이 연결됐어요!");

  

    socket.on("message", (data) => {

      console.log(data);

    });

        /*

        html 에서 

        socket.on("connect", () => {

            socket.send("Hello!");

        });

        즉, connect 가 되었을 때(브라우저가 서버에 접속했을 때) socket.send() 로 메세지를 서버에 보낸다는 뜻.

        서버에서는 socket.on("message") 함수가 send() 메소드의 호출을 받아서 "message" 이벤트를 발생시킨 것.

        */

    

    socket.emit("customEventName", "this is custom event data");

});

——

 

 

 

 

9.

express와 같이 사용해보기

 

우선 npm i express -S 로 모듈 설치.

-> express 앱 생성, http 서버 생성

 

——

// app.js

const express = require("express");

const { createServer } = require("http");

 

const app = express();

const http = createServer(app);     // http 서버를 통해서 모듈을 만들어 보자.

——

 

 

 

10.

socket.io 모듈 붙이기

 

——

// app.js

const express = require("express");

const { createServer } = require("http");

 

const app = express();

const http = createServer(app);     // http 서버를 통해서 모듈을 만들어 보자.

 

const io = require("socket.io")(http, {

    cors: {

      origin: "*",

      methods: ["GET", "POST"],

    },

});

 

http.listen(3000, () => {

    console.log("서버가 요청을 받을 준비가 됐어요");

});

  

io.on("connection", (socket) => {   

    /*

    이게 언제 일어나는데? 

    const socket = io("ws://localhost:3000"); 이 html 에서 명시되면서.

    브라우저에서 변수가 명시됨과 동시에 io.on("connection",) 이벤트가 발생.

 

    서버에서 connection 이벤트가 발생하면 console.log("새로운 소켓이 연결됐어요!"); 를 찍어.

 

    한 편 서버측의 connection 이벤트를 감지한 브라우저는, 이후 연쇄적으로 socket.on("connect", ) 을 실행시켜서 

    socket.send("Hello!"); 를 실행.

    서버측은 socket.on("message",) 라는 함수로 브라우저 측에서 발생한 "message" 이벤트로부터 data 를 받아서 콘솔에 출력.

 

    브라우저와 서버의 socekt.on() 이라는 메소드는 기본적으로 수동적.

    첫 번째 인자의 이벤트가 발생한다면, 해당 이벤트로 송신한 데이터를 수신해서 콜백 함수로 동작을 처리한다.

 

    아래에 명시된 커스텀 이벤트 핸들링 코드 

                => socket.emit("customEventName", "this is custom event data");

    emit() 이 능동적으로 "이 이벤트가 발생했을 때 값을 보낸다" 라고 선언.

    그리고 해당 emit() 은 io.on("connection", ) 이벤트 안에 있지.

            => io.on() 이 내부적으로 '특정 사용자' 를 인지할 수 있어.

            즉 서버는 emit()으로 "customEventName" 라는 이벤트를 미리 정의해 둔거야.

    근데 그 이벤트가 io.on("connection") 안에 있다보니 커넥션과 동시에 바로 발동한 것이고.

    프론트에서는 socket.on("customEventName", ) 라고 명시하면 "customEventName" 이벤트가 발생하여

    데이터를 받아서 내부 콜백 함수를 처리하겠지.

 

    서버가 const io = require("socket.io")(http, {cors: {},}); 로 io 명시

        -> 클라이언트에서 const socket = io("ws://localhost:3000"); 로 서버측의 socket.io 를 가져와

        -> 서버의 io.on("connection", ) 커넥션 이벤트 발생. on() 으로 미리 정의해 뒀다가 해당 이벤트가 발생하면 수신.

        -> 클라이언트의 socket.on("connect", () => { socket.send("Hello!"); });

            클라이언트가 socket을 선언하고 서버 측에서 io.on("connection")이 발생하면 이에 따라 체이닝으로

            클라이언트가 socket.on("connect") 소켓 커넥트 이벤트를 감지하고는 socket.send() 로 메시지를 보내

        -> 서버측에서 미리 선언되어 있던 socket.on("message", (data) => {console.log(data);}); 는,

            클라이언트의 send() 를 감지하여 .on("message", ) 로 수신하고는 해당 콜백 함수를 실행.

    

    즉, socket.on("event", () => {}) 는 해당 "event" 라는 이벤트가 발생했을 때 그 이벤트가 발생하면서 전달한 데이터를

    받아서 콜백 함수 안에서 처리하겠다 라고 사전에 미리 선언해 둔 로직.

 

    socket.send("Hello!"); 는 기본적으로 socket.on("message") 로 send() 를 받아.

    socket.emit("customEventName", "this is custom event data"); 의 경우 커스텀 이벤트 핸들링인데,

    마찬가지로 socket.on("customEventName") 로 데이터를 수신 받아서 콜백 함수로 로직을 처리할 수 있지.

    */

    

    console.log("새로운 소켓이 연결됐어요!");

  

    socket.on("message", (data) => {

      console.log(data);

    });

        /*

        html 에서 

        socket.on("connect", () => {

            socket.send("Hello!");

        });

        즉, connect 가 되었을 때(브라우저가 서버에 접속했을 때) socket.send() 로 메세지를 서버에 보낸다는 뜻.

        서버에서는 socket.on("message") 함수가 send() 메소드의 호출을 받아서 "message" 이벤트를 발생시킨 것.

        */

    

    socket.emit("customEventName", "this is custom event data");

});

——

 

 

 

 

 

 

 

 

__________________________

 

알고 넘어가자!!!!!!!

****

처음 서버를 실행시켰을 때 html은 한 번 새로고침을 해서 socket.io 를 받아와야 해.

 

 

 

*****

on() 은 수동적이다

send() 는 능동적이다

emit() 은 능동적이다

 

수동과 능동의 연관 관계를 잘 파악해보자.

 

 

 

 

 

 

 

 

 

__________________________________________________

 

1-6  쇼핑몰 실시간 구매 알림 기능 구현 준비

 

=>  < 3.2 Socket.io 04 >

3.2 Socket.io : Socket에 대해 이해하고, socket.io 라이브러리를 이용해 express 서버를 구현한다.

 

 

구현에 무엇이 필요한가.

=> socket.io로 클라이언트와 서버가 소켓 연결을 해야 해.

 

클라이언트에서 사용자가 구매 버튼을 누른 경우 서버로 "구매했어요"와 같은 데이터를 보내줘야만 접속중인 사용자들에게 알릴 수 있어.

 

다른 사용자가 구매를 한 경우 서버에서 모든 클라이언트에게 "누군가 구매를 했어요!"와 같은 

데이터를 보내줘야 실시간 구매 알림을 띄울수 있어.

=> 즉, socket.io 를 통해서 모든 접속자들에게 broadcast 를 해주는 거야.

 

 

 

 

폴더 : kimminsoo -> sparta -> node_js -> learning -> third_step -> shop-project-for-socket

 

 

 

 

<참고>

=> 해당 프로젝트에서 사용할 mongoDB 는 내 로컬에 깔려 있는 몽고DB.

=> 기본적인 프로젝트 파일들은 모두 교재가 제공해주는 파일들.

 

 

'내일배움캠프_개발일지 > Node.js 기초' 카테고리의 다른 글

Node.js 심화 - 4  (1) 2022.12.29
Node.js 심화 - 3  (0) 2022.12.29
Node.js 심화-1  (0) 2022.12.26
Node.js 숙련 -8  (0) 2022.12.23
Node.js 숙련 - 7  (0) 2022.12.23