TIL(미사용)

5월 11일 - Node.js 겅부

얏얏이 2020. 5. 11. 19:14

방에서 공부하면 왜 눈이 침침하냐...

 

Node.js

서버 환경에서 작동하는 JS

V8 엔진 적에 빨라짐, 하지만 아무리 빨라도 C, C++로 개발된 서버 앱보단 느림

Node.js에는 브라우저 JS에는 없는 process 객체를 지원한다. (브라우저에서는 window 라는 최상위 객체를 제공 함)

 

기존 서버와 Node.js와의 차이점

- 기존: 스레드를 기반으로 하는 *동기 방식

- Node.js: 이벤트를 기반으로 하는 **비동기 방식

 

* 동기 방식: 작업 요청이 있을 때마다 스레드를 여러 개 만드는 방식 -> 메모리 사용량이 증가

** 비동기 방식: 이벤트가 발생하면 처리하는 방식, 스레드가 하나라서 스레드에 문제가 생기면 프로그램 전체에 영향

 

스레드

장점

- 사용자의 응답성을 향상

- 동시에 작업을 완료

 

단점

- 많은 스레드로 코드 실행을 제어하면 복잡함

- 스레드를 삭제하려면 삭제할 때 발생할 수 있는 문제, 처리 방법을 알아야 함

 

사용하는 경우

- 네트워크 웹 서버 또는 DB 통신

- 시간이 오래 걸리는 작업

 

모듈

기능을 쉽게 사용하고자 메서드와 속성을 미리 정의해 모아 놓은 것

모듈을 생성할 때 export 객체를 사용

모듈을 가져올 때 require 객체를 사용

 

이벤트

- on(): 이벤트를 연결하는 메서드

- onec(): 이벤트를 한 번만 연결하는 메서드

- emit(): 이벤트를 발생시키는 메서드

 

한 이벤트에 대해 이벤트 리스너는 최대 등록 가능한 수가 10개이며, 그 이상 등록할 경우 경고가 발생 함

setMaxListener(number) 함수를 통해 리스너 한계를 조정할 수 있다.

 

HTTP

HTTP는 TCP/IP를 기반으로 둔 프로토콜이다.

HTLM 페이지를 전달하는 데 사용하는 프로토콜이지만, 다른 파일을 전송할 때도 사용한다.

 

GET, POST

GET: url에 매개변수 형식으로 노출시켜 데이터를 전달

POST: 클라이언트에서 form, input element를 사용해 url에 노출시키지 않고 서버로 요청하는 방식

 

기타

LTS: Long Time Support - 30개월의 장기적인 지원을 약속받은 버전

Current: 변화가 일어나는 상태의 버전, 비교적 덜 안정적임

요청: 웹 페이지에 접속하려고 하는 어떤 요청

응답: 요청을 받아 이를 처리하는 작업

쿠키: 키와 값이 들어있는 데이터(이름, 값, 파기 날짜 등)(서버와 클라이언트 모두 저장, 사용할 수 있다.)

 

한 코드 요약

var http = require("http");
var fs = require("fs");
// require을 사용해서 모듈을 가져온다.

http
  .createServer(function(req, res) {
    // createServer: 서버를 생성하는 메서드
    // req: request 객체, 클라이언트의 요청과 관련된 객체
    // res: response 객체, 서버의 응답과 관련된 객체

    process.on("exit", function() {
      console.log("서버를 종료합니다. ");
    });
    // process.on(): 이벤트를 등록할 때 사용하는 메서드
    // 첫 번째 매개변수 exit: 이벤트 이름
    // 두 번째 매개변수 함수: 첫 번째 매개변수로 넣은 이벤트가 발생하면 실행할 함수이며 이벤트 핸들러라고 부른다.
    // 즉 exit 이벤트가 일어날 때 '서버를 종료합니다.' 라는 텍스트가 뜨도록 이벤트를 등록

    process.emit("exit");
    // 실제로 exit가 이벤트가 일어난 것은 아니지만 exit 이벤트에 등록한 이벤트 핸들러를 발생시킴
    // 여기서 프로그램이 종료되지는 않고 아래서 process.exit(0)을 통해서 프로그램이 종료 됨

    console.log("req.url: " + req.url);
    // req.url: 클라이언트가 들어온 url

    if (req.method === "GET") {
    // req.method: 요청 방식 들어있는 속성

      fs.readFile("./text.html", function(error, data) {
        // fs.readFile: 비동기 방식으로 파일을 읽는다.
        // 첫 번째 매개변수: 이 경로에 있는 파일을 읽어온다.
        // 두 번째 매개변수 함수의 첫 번째 매개변수: 에러가 발생했을 때 error는 undefined이 아니게 됨
        // 두 번째 매개변수 함수의 두 번째 매개변수: 읽어온 파일

        res.writeHead(200, { "Content-Type": "text/html" });
        // writeHead: 클라이언트에게 응답할 데이터 헤더를 설정하는 것
        // 첫 번째 매개변수: 숫자는 status를 의미함, 200은 정상, 302는 리다이렉션 등등... 
        // 두 번째 매개변수: 각종 옵션을 넣을 수 있음, 응답할 데이터의 바디가 text/html이라는 것을 명시

        res.end(data);
        // 데이터 바디에 읽어온 파일을 넣음
      });
    } else if (req.method === "POST") {
      req.on("data", function(data) {
        // POST 방식은 먼저 요청이 들어오고, 후에 data 이벤트를 통해서 관련된 데이터르 보내 준다.
        // data 이벤트가 발생하면(=POST 방식으로 데이터르 보내면) 아래의 로직이 돌도록 한다.
        // 두 번째 함수의 매개변수로 data로 날라온? 데이터가 들어오는 듯
        if (Math.random() < 0.5) {
          res.writeHead(302, {
            "Content-Type": "text/html",
            Location: "https://naver.com"
          });
          // 억지로 넣은 로직
          // Location을 이용하면 다른 페이지로 강제로 이동시킬 수 있다.

          res.end();
        } else {
          res.writeHead(200, {
            "Content-Type": "text/html",
            "Set-Cookie": [`key=value;Expires:${new Date().toUTCString}`]
          });
          // Set-Cooke: 쿠키 값을 세팅하는 속성
          
          res.end(`<h1>${data}</h1>`);
          process.exit(0);
        }
      });
    }
  })
  .listen(50000, function() {
    console.log("server on");
  });