이 블로그는 임베디드 컴퓨터를 이용한 장치(시스템) 개발과 원격제어에 필요한 지식을 공유 하기 위한 블로그 입니다.
실제 개발과 프로그램 예를 위하여 Microchip 사의 ATmega128를 사용한 보드와 Arduino Mega 보드(ATmega2560), Raspberry Pi, Raspberry Pi Pico, WiFi 모듈을 사용 합니다.

node-js

Node.js
  Node.js



  • Node.js 개요
    • JavaScript 기반으로 구성된 서버 사이드 서비스를 JavaScript로 구현할 수 있게 하는 런타임 환경(Runtime Environment: 컴퓨터가 실행되는 동안 프로세스나 프로그램을 위한 소프트웨어 서비스를 제공하는 가상 머신 환경) 이다.
    • Node.js는 Server 측에서 JavaScript를 실행 할수 있게 한다.
    • Node Package Manager(npm)를 이용하여 다양한 node.js 기반의 모듈을 설치 할 수 있고 이를 이용하여 용이하게 Server Side program을 개발 할 수 있다.
    • Event driven programming 과 Callback function
      • 기존의 프로그램 언어(C, C++ 등)는 코드가 순차적으로 실행되면서 함수를 호출(Procedural programming model) 하는 방식으로 프로그램이 실행 된다.

        Node.js는 Event driven 방식(특정 이벤트가 발생되면 미리 이벤트에 맵핑된 함수가 실행된다.)으로 프로그램이 실행 되기 때문에 Node.js 환경의 프로그램을 이해 하기 위하여는 Event driven programming 과 Callback function에 대한 이해가 필요 하다.

        Node.js는 Event-driven, Non-blocking I/O model을 지원 하기 때문에 프로그램 실행 속도가 빠르고 효과 적이다.

      • JavaScript에서 일반 Function의 실행
        • JavaScript 코드는 기본적으로는 동기식(Synchronous)으로 실행된다. 프로그램 코드는 한 라인씩 순차적으로 실행된다.
        • 동기식(Synchronous) JavaScript 프로그램의 실행 예
        • 아래 코드는 문자열을 함수에 매개변수로 전달하여 출력하는 예로 함수가 호출되는 순서에 때라 함수의 실행 결과가 출력된다.

          위 JavaScript 코드의 실행 결과(Output)는 함수가 순차적으로 실행되어 아래와 같이 출력된다.

          주: 아래 "Node.js와 NPM 설치 하기"를 참고하여 Node.js를 설치하고 위 프로그램을 복사하여 test.js로 저장하고 실험한다.

      • JavaScript CallBack Function
        • JavaScript에서는 함수(함수의 포인터)를 함수의 인수로 전달할 수도 있다. 다른 함수에 인수로 전달되어 실행되는 함수를 CallBack Function라고 한다.
        • CallBack Function 예
        • 아래 코드에서는 greet() 함수를 호출하며 문자열과 함수(callMe() 함수의 포인터)를 매개 변수로 전달하여 greet() 함수내에서 callMe() 함수가 실행된다. 이 경우 callMe() 함수를 CallBack 함수라고 한다.

          위 JavaScript 코드의 실행 결과(Output)는 greet() 함수가 실행되고 callMe() 함수가 실행되어 아래와 같이 출력된다.

        • CallBack Function의 특징
          • CallBack 함수를 사용하면 먼저 호출된 함수의 실행 결과를 기다린 후 CallBack 함수를 실행할 수 있다.
          • 속도가 느린 입출력 또는 통신 장치를 제어하는 프로그램에서 CallBack 함수를 사용하면 속도가 느린 입출력 또는 통신 프로그램의 실행 결과를 CallBack 함수에서 바로 사용할 수 있게 된다.
          • Node.js 와 같이 비동기식(Asynchronously) 프로그램 실행을 지원하는 경우(Event-driven, Non-blocking I/O model을 지원하는 경우) CallBack 함수를 사용하면 실행 속도가 빠르고 효과적인 프로그램 실행이 가능하다.
          • Callback function이 호출된 함수(속도가 느린 입출력 또는 통신 장치를 제어하는 프로그램)의 실행 결과를 기다리는 동안 다른 실행 가능한 Module이 실행되기 때문에 전체적으로 실행 속도가 빠르고 효과적인 프로그램 실행이 가능하다.
          • Web 프로그램 작성 시, Client에서 Web server에 Web page 또는 필요한 데이터를 요구(Require)하고, 결과(Response)를 기다린 후 Callback function에서 Server의 응답(Response)를 사용하여 Web page를 Update 하는 것이 가능하다. 이 경우 Server의 응답을 기다리는 동안 실행 가능한 다른 코드를 비동기(Asynchronously)로 실행할 수 있기 때문에 효과적인 프로그램 실행이 가능하다.
      • JavaScript callback function 예: setTimeout() 함수
        • JavaScript callback function은 비동기 함수(Asynchronous function) 이다.
        • JavaScript callback function는 주어진 작업이 완료 될 때 호출 된다.
        • setTimeout() 함수를 사용하는 예

          위 JavaScript 코드의 실행 결과(Output)는 setTimeout() 함수가 종료되기 전에 mesgOut() 함수가 실행되어 'Hello world' 가 출력되고 약 2초 후에 'Hi, Kim' 이 아래와 같이 출력된다.

      • JavaScript callback function 예: File I/O Programming
        • File I/O Programming 예

        • D: 에 node_js 폴더를 만들고 cd 명령으로 node_js 폴더로 이동 한다.
        • 아래와 같은 내용의 Text File을 만들어 input_file.txt에 저장 한다.
        • 아래와 같은 callback-test.js File을 만들어 저장 한다.
        • DOS COmmand Window에서 다음 명령을 실행 한다. D:\node_js에 callback-test.js File이 있는 경우의 예.
          • D:\node_js>node callback-test.js
        • 실행 결과는 아래와 같다.
        • 윗 예에서 주어진 작업(File Read 동작: 컴퓨터의 실행 속도에 비교 하여 매우 느리게 진행 됨)이 진행 되는 동안
        • Callback function ( function (err, data) { - - - } )은 특정한 Even (이 경우 File Read 동작이 종료 되면 발생 하는 Event)를 기다리고 있는 상태가 된다.
        • Callback function이 Event를 기다리는 동안 다른 실행 가능한 Module (이 예에서는 Console에 메세지를 출력 하는 명령) 다른 Module이 실행( 결과로 "Program Ended" 메세지가 먼저 출력 된다.) 된다.
        • File Read 동작이 종료 되고 Event 가 발생 하면 Callback function이 실행 (Read 된 File의 내용이 Console에 출력) 된다.
        • 이와 같이 Node는 Event에 의하여 실행되는 Callback function을 이용 하여 속도가 느린 I/O 장치의 동작이 종료 되는 것을 기다리지 않고 비 동기적(Asynchronous)으로 I/O 동작을 처리 하여 프로그램의 실행 속도와 효율을 높일 수 있다.

  • Node.js와 NPM 설치 하기(Windows OS를 사용 하는 컴퓨터에 Node.js 설치)
      • nodejs.org에서 최신 버전을 다운받아 설치한다.
      • Node.js는 Chrome's V8 JavaScript Engine을 기반으로 하기 때문에 Goole Chrome V8 이상의 버전이 설치 되어 있어야 한다.
      • NPM는 Node.js 설치시 함께 설치 된다.
      • Node.js는 Visual Studio build tools 과 Python을 필요로 한다. Node.js 설치 시 필요한 Tool이 설치되지 않은 경우 자동으로 설치 여부를 질의하는 창이 열린다. 이 경우 이들 Tool를 함께 설치하는 것을 권장한다.
      • Windows OS를 사용 하는 컴퓨터에서 Node.js Update
        • Node.js 최신 버전을 다운로드 받아 Windows Installer를 사용하여 현재 설치되어 있는 폴더에 설치하면 자동으로 Update 된다.
        • 설치 후 DOS 명령창에서 "node -v" 명령으로 버전을 확인할 수 있다.

  • Node.js 테스트 하기
    • 설치가 완료되었으면 DOS 명령창을 열고 다음 명령을 실행 한여 본다.
      • D: 에 node_js 폴더를 만들고 cd 명령으로 node_js 폴더로 이동 한다.
      • D:\node_js>node -v : 정상적으로 설치 되었으면 v14.12.0 과 같이 현재 설치된 버전이 표시 된다. D:\node_js> 는 DOS 명령을 기다리는 Prompt 상태이고 node -v 가 사용자가 명령 이다.
      • D:\node_js>npm -v : 현재 설치된 npm 버전이 6.14.8과 같이 표시 된다.
    • DOS 명령창에서 JavaScript 코드를 입력하여 실행 하기.
      • "D:\node_js>node" 명령을 실행하면 node 가 실행되고 node 명령을 실행 할 준비(REPL Terminal에서 Node Prompt 상태)가 된다.
      • >   var a = 'Node';      // 변수 a에 Node 문자열이 저장 된다. 다음 줄에 표시 되는 undifined 메세지는 무시 한다. > 문자는 node 명령을 기다리는 Prompt 문자임.
      • >   a                          // `Node` 문자열이 출력 된다.
      • >   var b = 'test';       // 변수 b에 test 문자열이 저장 된다. 다음 줄에 표시 되는 undifined 메세지는 무시 한다.
      • >   b                        // `test` 문자열이 출력 된다.
      • >   console.log(a + ' ' + b);   //enter 'Node test' 문자열이 출력 된다.
      • Ctrl C를 두번 누르면 Node 실행이 중단 되고 Dos Command Prompt 상태가 된다.
      • DOS command 실행 예

    • JavaScript 파일을 만들고 해당 파일을 실행 하기.
      • Text Editor를 사용 하여 js-test.js File을 아래와 같이 만들고 저장(예: D:\node_js 폴더에 저장) 한다.
      • D:\node_js>node js-test.js 명령으로 node 환경에서 js-test.js를 실행 하면 아래와 같이 결과가 출력 된다.
      • node 환경에서 js-test.js를 실행한 예

        주: JavaScript를 실행하기 위하여는 JavaScript engine이 필요하다. 대부분의 Web browser는 JavaScript engine을 포함하고 있기 때문에 HTML 문서 내에 <script> Tag를 이용하여 JavaScript code를 작성하고 Browser에서 실행할 수 있다. 또한 Node.js 도 JavaScript engine를 포함하고 있기 때문에 Node.js 환경에서 JavaScript를 실행할 수 있다. Node.js 환경에서 JavaScript를 실행 예는 이 폐이지 "Node.js 테스트 하기"를 참고 바람.


  • NPM 테스트 하기
    • npm는 Node Package Manager이기 때문에 node.js를 설치하면 같이 설치된다.

      npm을 이용 하여 node.js 환경에서 이용 할 수 있는 모듈을 다운로드 받아 이용 할 수 있기 때문에 Web 개발을 쉽게 할 수 있다.

    • NodeTest 폴더에서 npm init -y 명령을 실행 한다.
    • 위 명령에 의하여 package.json파일이 생성된 것을 볼 수 있다.

  • Package.json 파일
    • package.json파일은 프로젝트에 대한 명세이다. 해당 프로젝트의 이름, 버전, 사용되는 모듈 등의 정보를 포함하고 있다. 이 package.json을 통해 모듈 의존성을 관리 할 수 있다. 만약 어떤 오픈 소스를 다운 받을 때 package.json이 있으면 해당 오픈 소스가 의존하고 있는 모듈이 어떤 것인지 관리 하고, 그 모듈들을 한 번에 설치할 수 있다.
    • Node serialport를 설치한 package.json파일 예

      Node express, jquery, serialport를 설치한 package.json파일 예. multer는 모듈 의존성에 따라 자동으로 설치 되었음.


  • Node.js를 이용한 Web server
    • Node.js는 Built-in HTTP Module을 포함하고 있다.

      HTTP 모듈을 이용하여 HTTP 서버를 생성할 수 있고, 생성된 서버는 서버 포트를 이용하여 Client의 요구(Require)를 수신하고 Client에 응답(Response)을 전송할 수 있다.

    • HTTP Module을 이용한 Web Server 예
      • HTTP Module을 이용한 Web Server 예
        • 아래 예는 HTTP server를 생성하고, Client의 요구에 응답하여 'Hello World! 메세지를 전송하는 예 이다.

        • HTTP Module을 이용한 Web Server 실험
          • 위 Code를 복사하여 hello-http.js 파일로 저장(예: D:\node_js\hello-http.js)한다.
          • D:\node_js>node hello-http.js 명령을 실행 한다.
          • Web browser를 열고 http://localhost:8080/ 으로 접속 하면 Browser에 "Hello World!" 메세지가 출력 된다.

      • HTTP Module을 이용한 Web Server에서 Query String 읽기
        • 아래 예는 HTTP server를 생성하고, Client에서 전송된 url(Query String)를 읽고 확인하는 코드 예 이다. Client에서 전송된 url 종점(Endpoint)을 읽어 다시 Client에 전송하고, DOS command 창(Console)에 출력한다.

        • Web Server에서 Query String 읽기 실험
          • 위 Code를 복사하여 http-url.js 파일로 저장(예: D:\node_js\http-url.js)한다.
          • D:\node_js>node http-url.js 명령을 실행 한다.
          • Web browser를 열고 http://localhost:8080/url-test 으로 접속 하면 Browser에 "/url-test" 가 출력 된다.
          • DOS command 창(Console)에 'req.url: /url-test' 가 출력되었는지 확인한다.

      • HTTP Module을 이용한 Web Server에서 Query String을 Split 하기
        • 아래 예는 HTTP server를 생성하고, Client에서 전송된 Query String을 Split 하여 확인하고, Client에서 전송하는 예 이다.

        • Web Server에서 Query String 읽기 실험
          • 위 Code를 복사하여 http-querystring.js 파일로 저장(예: D:\node_js\http-querystring.js)한다.
          • D:\node_js>node http-querystring.js 명령을 실행 한다.
          • Web browser를 열고 http://localhost:8080/?year=2024&month=May 으로 접속 하면 Browser에 "2024 May" 가 출력 된다.
          • DOS command 창에서 Query string이 아래와 같이 출력되었는지 확인한다.
          • Query string: 2024 May


      • Node.js 파일 시스템 모듈을 사용한 파일 작업
        • Node.js File system module을 사용하면 컴퓨터의 파일 시스템의 파일 작업(Read, Create, Update, Delete, Rename)을 할 수 있다.
        • 아래 예는 Client의 요구에 응답하여 서버에 저장된 파일을 읽어 Client에 전송하는 예 이다.
        • Node.js 파일 시스템 모듈을 사용한 파일 작업 실험
          • 위 Code를 복사하여 file-read.js 파일로 저장(예: D:\node_js\file-read.js)한다.
          • 아래 Code를 복사하여 file-read.js 파일이 있는 '/' 폴더에 file-read.html 로 저장한다.
          • DOS command 창을 열고 file-read.js 파일이 있는 폴더(예: D:\node_js)로 이동한다.
          • D:\node_js>node file-read.js 명령을 실행 한다.
          • Web browser를 열고 http://localhost:8080/ 으로 접속 하면 Browser에 "file-read.html" 이 출력 된다.
        • 참고자료: File Create, Update, Delete, Rename은 Node.js File System Module 을 참고할 것.

      • Node.js URL Module
        • URL Module을 사용하면 용이하게 웹 주소를 의미있는 부분으로 분리할 수 있다.
        • 아래 예는 웹 주소를 의미 있는 부분으로 나누어 DOS command 창(Console)에 출력하는 예 이다.
        • Node.js URL Module 실험
          • 위 Code를 복사하여 url-module.js 파일로 저장(예: D:\node_js\url-module.js)한다.
          • D:\node_js>node url-module.js 명령을 실행 한다.
          • DOS command 창에 웹 주소의 Parsing 결과가 아래와 같이 출력되었는지 확인한다.
          • host: localhost:8080

            pathname: /index.html

            search: ?year=2024&month=May

            month: May


      • Node.js를 이용한 File(Web) Server
        • 아래 예는 url 종점(Endpoint)이 'server-red.html' 인 경우 "server-red.html" 파일을 Client에 전송하고, 종점(Endpoint)이 '/server-green.html' 인 경우 "server-green.html" 파일을 Client에 전송하는 예 이다.
        • Node.js File(Web) Server 실험
          • 위 Code를 복사하여 file-server.js 파일로 저장(예: D:\node_js\file-server.js)한다.
          • 아래 Code를 복사하여 file-server.js 파일이 있는 폴더에 server-red.html 로 저장한다.

            아래 Code를 복사하여 file-server.js 파일이 있는 폴더에 server-green.html 로 저장한다.

          • DOS command 창을 열고 file-server.js 파일이 있는 폴더(예: D:\node_js)로 이동한다.
          • D:\node_js>node file-server.js 명령를 실행 한다.
          • Web browser를 열고 http://localhost:8080/server-red.html 으로 접속 하면 Browser에 "Red page"가 출력된다.
          • Web browser를 열고 http://localhost:8080/server-green.html 으로 접속 하면 Browser에 "Green page"가 출력된다.
          • File read error 가 발생하면 "404 Not Found" 메세지를 Browser에 출력한다.

        주: 위 예와 같이 Node.js 기능만을 사용하여 웹 애플리케이션을 개발하는 것이 가능하다. 그러나 HTTP 요청 및 응답과 같이 낮은 수준 기능을 애플리케이션 작성자가 처리되어야 한다. 그러므로, Express을 사용하여 HTTP 요청 및 응답과 같은 낮은 수준의 일반적인 작업을 Express 가 처리하도록 하면 개발자는 자신이 개발하고자 하는 애플리케이션에 보다 더 집중할 수 있다.

        참고자료: Node.js - Express, Web 서버 개발 시 대부분의 개발자는 "Node.js - Express"를 이용한다.