이 블로그는 Web 환경을 이용한 원격 제어 기술에 필요한 지식을 공유 하기 위한 블로그 입니다.
실제 개발과 프로그램 예를 위하여 Raspberry Pi와 Raspberry Pi Pico, ATmega128 보드, Arduino Mega 보드(ATmega2560), WiFi 모듈을 사용 합니다.

node-js-web-server

Node.js - Express
  Node.js - Express



  • Express 개요와 설치하기
    • Express 개요
      • Express.js는 Node.js를 사용하여 쉽게 Web 서버를 구현할 수 있게 하는 클래스와 라이브러리의 집합체(Web framework) 이다. 그러므로, Express.js를 이용하면 효과적으로 Web 서버를 구축할 수 있다.
      • Express.js는 Node.js 생태계에서 가장 인기 있는 웹 프레임워크 중 하나로, Express.js는 템플릿 작성, 정적 파일 처리, SQL 및 NoSQL 데이터베이스와의 연결과 같은 최신 웹 프레임워크의 모든 기능을 제공한다.
      • Express.js는 Node.js API의 핵심 모듈 중 하나인 http를 기반으로 하는 connect 미들웨어 위에 구축되었다.
      • Express.js는 빠르고 강력하며 확장 가능한 웹 애플리케이션을 용이하게 작성할 수있게 하는 유틸리티 세트이다.
      • Express의 유용성
        • Node.js에는 웹 서버가 내장되어 있기 때문에 http 모듈의 createServer() 메서드를 사용하여 비동기 http 서버를 시작할 수 있다.
        • 그러므로, Node.js 기능만을 사용하여 웹 애플리케이션을 개발하는 것이 가능하다. 그러나 HTTP 요청 및 응답과 같이 낮은 수준 기능을 애플리케이션 작성자가 처리되어야 한다.
        • Express은 HTTP 요청 및 응답과 같은 낮은 수준의 일반적인 작업을 처리하므로 개발자는 자신이 개발하고자 하는 애플리케이션에 보다 더 집중할 수 있다.
      • Express의 중요 기능
        • HTTP 요청에 응답하도록 미들웨어를 설정할 수 있다.
        • HTTP 메소드 및 URL을 기반으로 다양한 작업을 수행하는 데 사용되는 라우팅 테이블을 정의한다.
        • 템플릿에 전달된 인수를 기반으로 HTML 페이지를 동적으로 렌더링할 수 있습니다.
    • Express 설치하기
      • 아래와 같이 npm을 사용 하여 express와 body-parser를 설치 한다.

      • Express 설치하기
        • 아래 명령으로 npm을 사용 하여 express를 설치 한다.

          npm install express --save

            주: --save 옵션은 package.json의 dependency 항목에 모듈을 추가한다는 의미이다. 그러나 npm5 부터는 --save 옵션을 기본 옵션으로 적용하기 때문에 --save를 사용하지 않아도 dependencies에 항목이 자동으로 추가된다.

      • body-parser 설치하기
        • 아래 명령으로 npm을 사용 하여 body-parser를 설치 한다.

          npm install body-parser

      • 다음 명령으로 Express module 설치 정보를 package.json파일에서 확인 한다.
      • cat package.json

      • 참고자료: expressjs.com Home
      • 참고자료: npm: body-parser
      • 참고자료: Node.js - Express Framework
      • 참고자료: MDS web docs (Express web framework)

    • Express를 이용한 Web server
      • Express를 이용한 Web server 예: Hello world
        • 다음 명령으로 Node.js web file(html)를 저장할 Directory(node-web)를 만든다.
        • mkdir node-web

        • 다음 명령으로 node-web Directory로 이동 한다.
        • cd node-web

        • 실험을 위한 폴더에 아래 프로그램을 복사하여파일 이름 "hello-express.js"로 저장(예: /node-web/hello-express.js) 한다.
        • 주: Windows PC에서 Notepad++ 편집기, PuTTY, WinSCP를 개발환경으로 사용하는 "원격 컴퓨터에서 PuTTY(SSH 프로토콜 이용)를 사용한 개발 환경"을 사용하면 용이하게 프로그램을 작성할 수 있다.

        • PuTTY 실행 창에서 "hello-express.js" 명령을 실행 한다.
        • Web browser를 열고 http://Raspberry Pi의 IP 주소:2880/ 으로 접속 하면 Browser에 "Hello World!" 메세지가 출력 된다.
        • 주: 공유기의 포트포워드 설정에서 Raspberry Pi의 설정을 외부포트: 2880 , 내부포트: 2880 으로 설정하여야 한다. 포트 번호는 본인의 편의에 따라 다른 번호를 사용할 수 있다.


      • Express를 이용한 Web server 예: GET method
        • Express Object Routing
          • 위 예(hello-express.js)의 app object는 HTTP requests(GET, POST, PUT 및 DELETE)를 app.get(), app.post(), app.put() 및 app.delete() 메서드를 사용하여 각각 처리할 수 있다.
          • 각 메소드의 첫 번째 매개변수는 URL의 종점(Endpoint)을 나타내는 문자열(예: '/')이다.
          • 두 번째 매개변수는 NodeJS 서버에서 제공되는 HTTP request 및 HTTP response 객체(이 객체는 Callback function에 전달되어 이용됨)이다.
          • 이러한 메서드는 비동기식이며 Callback function에 Request 및 Response 개체를 전달한다.
          • 주: 여기서는 자주 사용하는 app.get()와 app.post() 메소드를 이용한 Web server에 대하여만 설명한다.

        • GET method를 사용하는 Web server 예: 1번
          • 아래 Code를 복사하여 /node-web 폴더에 express-get.js 파일로 저장한다.
          • 위 예는 Client 가 '/' 종점(Endpoint)를 방문할 때 GET 요청을 처리하는 예 이다. 윗 예에서,

            • Request Object(req)는 HTTP Request는 request query string, parameters, body, HTTP headers 등에 대한 속성을 저장하고 있다. Callback function에서 이 속성을 이용할 수 있다.
            • Response Object(res)는 Express 앱이 HTTP Request를 받고 Client에 전송할 응답(Response)을 저장한다. Callback function에서 이 Object에 Client에 전송할 응답을 설정하고, 이 Object의 send() 메서드를 사용하여 서버의 응답을 Client에 전송한다.
            • 쿠키, 세션, URL 등 HTTP Request 와 Response 관련된 정보를 제공하는 Request 와 Response 개체를 Callback function에서 출력하여 확인 또는 이용 할 수 있다.
            • Response Object의 sendFile() 메서드를 이용하여 지정된 파일을 응답으로 보낼 수 있다.
          • GET method 실험
            • 다음 명령으로 /node-web/ 폴더에 Web file(html)를 저장할 Directory(html)를 만든다. 디렉토리 계층 구조는 /node-web/html/ 과 같다. node-web 디렉토리에는 .js 파일을 저장하고 html 디렉토리에는 .html 파일을 저장한다.
            • mkdir html

            • 다음 명령으로 html Directory로 이동 한다.
            • cd html

              아래 Code를 복사하여 /node-web/html/ 폴더에 index-get.html 로 저장한다.

            • PuTTY 실행 창에서 express-get.js 파일이 있는 폴더로 이동한다.
            • PuTTY 실행 창에서 "node express-get.js" 명령를 실행 한다.
            • Web browser를 열고 http://Raspberry Pi의 IP 주소:2880/ 으로 접속 하면 Browser에 "Hello World!" 메세지가 출력 된다.
            • PuTTY 실행 창에 출력된 url을 확인한다. 아래 예는 Host address: Raspberry Pi의 IP 주소, port 번호: 2880, url 종점(Endpoint): '/' 인 경우이다.
            • req get url: http://Raspberry Pi의 IP 주소:2880/

              주: "Raspberry Pi의 IP 주소"는 네트워크 상에서 Raspberry Pi의 주소(자신의 공유기에서 확인 가능)이다.

        • GET method를 사용하는 Web server 예: 2번
          • 이 예는 HTML Form-data를 GET method를 이용하여 서버에 전송하는 예 이다.

          • 아래 예는 url 종점(Endpoint)이 '/' 인 경우 "form-get.html" 파일을 Client에 전송하고, 종점(Endpoint)이 '/get_data' 일 경우 GET method로 수신한 req 객체의 first_name 과 last_name을 JSON Format으로 Client에 전송하는 예 이다.
          • Form-data를 GET method를 이용하여 서버에 전송하는 실험
            • 위 Code를 복사하여 /node-web/ 폴더에 express-form-get.js 파일로 저장한다.
            • 아래 Code를 복사하여 /node-web/html/ 폴더에 form-get.html 로 저장한다.

            • PuTTY 실행 창을 열고 express-form-get.js 파일이 있는 폴더로 이동한다.
            • PuTTY 실행 창에서 "node express-form-get.js" 명령를 실행 한다.
            • Web browser를 열고 http://Raspberry Pi의 IP 주소:2880/ 으로 접속 하면 Browser에 "HTML Forms"이 출력된다.
            • Browser에 "HTML Forms"에 Data를 입력하고 "Get Submit" button을 클릭하면 web 서버에 Get method로 data가 전송된다.
            • PuTTY 실행 창에서 url이 아래와 같이 출력되었는지 확인한다. 아래 예는 Host address: Raspberry Pi의 IP 주소, port 번호: 2880, url 종점(Endpoint): '/get_data', Get method로 전송된 Data: first_name=YoungSu&last_name=Kim 인 경우이다.
            • req get url: http://Raspberry Pi의 IP 주소:2880/get_data?first_name=YoungSu&last_name=Kim

            • PuTTY 실행 창에서 Get method로 수신한 Data 가 아래와 같이 출력되었는지 확인한다. 아래 예는 first_name 이 YoungSu 이고 last_name 이 Kim 인 경우이다.
            • {"first_name":"YoungSu","last_name":"Kim"}

            • 새 Web browser에 서버로 부터 전송된 first_name 과 last_name이 아래와 같이 JSON Format으로 출력된다.
            • {"first_name":"YoungSu","last_name":"Kim"}


      • Express를 이용한 Web server 예: POST method
        • 이 예는 HTML Form-data를 POST method를 이용하여 서버에 전송하는 예 이다.

        • 아래 예는 url 종점(Endpoint)이 '/' 인 경우 "form-post.html" 파일을 Client에 전송하고, POST method로 수신한 req 객체의 first_name 과 last_name을 JSON Format으로 Client에 전송하는 예 이다.
        • Form-data를 POST method를 이용하여 서버에 전송하는 실험
          • 위 Code를 복사하여 /node-web/ 폴더에 express-form-post.js 파일로 저장한다.
          • 아래 Code를 복사하여 /node-web/html/ 폴더에 form-post.html 로 저장한다.

          • PuTTY 실행 창을 열고 express-form-post.js 파일이 있는 폴더로 이동한다.
          • PuTTY 실행 창에서 "node express-form-post.js" 명령를 실행 한다.
          • Web browser를 열고 http://Raspberry Pi의 IP 주소:2880/ 으로 접속 하면 Browser에 "HTML Forms"이 출력된다.
          • Browser에 "HTML Forms"에 Data를 입력하고 "Post Submit" button을 클릭하면 web 서버에 Post method로 data가 전송된다.
          • PuTTY 실행 창에서 Post method로 전송된 Data(req.body) 가 아래와 같이 출력되었는지 확인한다.
          • req post data: {"first_name":"YoungSu","last_name":"Kim"}

            data first_name: YoungSu

            data last_name: Kim

            {"first_name":"YoungSu","last_name":"Kim"}

          • 새 Web browser에 서버로 부터 전송된 first_name 과 last_name이 아래와 같이 JSON Format으로 출력된다.
          • {"first_name":"YoungSu","last_name":"Kim"}


      • Express를 이용한 Web server 예: Static Files
        • Express는 내장된 미들웨어 express.static을 이용하여 이미지, CSS, JavaScript 등과 같은 정적 파일을 Client에 제공할 수 있다.

          정적 자산을 보관하는 디렉터리의 이름을 express.static 미들웨어에 전달하는 것 만으로 Client에서 파일 사용할 수 있다. 예를 들어, 이미지, CSS 및 JavaScript 파일을 public이라는 디렉토리에 보관한 경우 다음과 같이 파일을 전송할 수 있다.

        • 정적 파일(Static Files)을 이용하는 예
          • 위 Code를 복사하여 /node-web/ 폴더에 express-static.js 로 저장한다.
          • /node-web/ 폴더에 /public/ 폴더을 만들고 /public/ 폴더에 /images/ 폴더(예: /node-web/public/images/)를 만든다. 그리고 /images/ 폴더에 Image 파일 logo.png를 저장한다.
          • PuTTY 실행 창을 열고 express-static.js 파일이 있는 폴더로 이동한다.
          • PuTTY 실행 창에서 "node express-static.js" 명령를 실행 한다.
          • Web browser를 열고 http://Raspberry Pi의 IP 주소:2880/images/logo.png 으로 접속 하면 Browser에 "logo.png" 이미지가 출력된다.
      • 참고자료: ExpressJS - Serving static files

    • Web checkbox을 이용한 LED 제어
      • 실험에 사용하는 회로는 "Raspberry Pi GPIO(General Purpose Input Output)" 페이지의 Raspberry Pi LED 제어하기를 참고 할 것.

      • 아래 파일을 복사하여 /node-web/ Directory에 ras-checkbox-led.js File을 만들고 아래와 같이 편집 한다.

      • 아래 파일을 복사하여 node-web/html/ Directory에 ras-checkbox-led.html 로 저장한다.
      • ras-checkbox-led.html을 실행한 Web page 예

      • 다음 명령으로 ras-checkbox-led.js를 실행 한다.
      • node ras-checkbox-led.js

      • Web browser를 열고 http://Raspberry Pi의 IP 주소:2880/ 으로 접속 하면 Browser에 "ras-checkbox-led.html" 이 출력된다.
      • ras-checkbox-led.htm 페이지에서 LED0 Checkbox를 On, Off 한다. "LED On/Off 제어" 버튼을 클릭하고, 결과(Web page에 출력되는 메세지)를 확인 한다.
      • PuTTY 실행 창에 LED0 Checkbox의 Check 상태에 따라 "reqData: {"LED":"1"} 또는 {"LED":"0"} 이 바르게 출력되었는지 확인한다.
      • PuTTY 실행 창에 LED0 Checkbox의 Check 상태에 따라 "LED: 1" 또는 "LED: 0" 이 바르게 출력되었는지 확인한다.
      • Raspberry Pi 에 연결된 LED의 상태(On, Off)를 확인한다.

    • Raspberry Pi 시작 시 자동으로 프로그램 시작 하도록 하기
      • Raspberry Pi 시작 시 자동으로 프로그램이 시작 하도록 하기 위한 설정
        • /etc/rc.local File에 Editor를 사용하여 다음 명령을 삽입 한다.
          • sudo node (path)/(run flie name)
          • 예: sudo node /home/pi/node-web/ras-checkbox-led.js &
          • & 문자는 프로그램이 Background에서 실행 되도록 함. 소유자: root
      • Background에서 실행 중인 Process를 확인 하고 정지 하기
        • 다음 명령으로 Background 에서 실행 중인 Process PID를 확인 한다. 윗 예에서 실행 프로그램 이름은 ras-checkbox-led.js 이지만 실행 Process 이름은 node 임.
        • ps -A | grep (Process name)

          예: ps -A | grep node

        • 다음 명령으로 실행 중인 node Process를 정지 한다.
        • sudo kill pid 또는 sudo kill -9 pid (pid는 ps 명령으로 확인한 node process의 pid 번호 임.)