- NODE.JS 를 이용해 간단한 서버 구축하기(1)
- NODE.JS 를 이용해 간단한 서버 구축하기(2)
- NODE.JS 를 이용해 간단한 서버 구축하기(3)
- NODE.JS 를 이용해 간단한 서버 구축하기(4)
이번에는 ESP32로부터 데이터를 받아 웹브라우저에 받은 데이터를 보여주는 코드를 구현해 보도록 하겠습니다.
ESP32가 JSON 형태로 데이터를 보내주면 서버에서는 이를 받아 파일로 저장하고 웹브라우저를 통해 사용자가 접속을 하면 저장된 데이터를 불러오는 코드입니다.
우선, HTTP 요청을 통해 들어오는 body를 파싱하기 위해 body-parser라는 모듈을 설치해야 합니다.
npm install body-parser
설치가 완료되면 다음 코드를 작성합니다.
[ index.js ]
var express = require('express') var fs = require('fs') var path = require('path'); var bodyParser = require('body-parser'); var app = express() app.locals.pretty = true app.set('views', './view_file') app.set('view engine', 'pug') app.use(bodyParser.json()) app.listen(3000, () => { console.log("Server has been started") }) var dataFolderPath = path.join(__dirname, '/data') var dataPath = path.join(dataFolderPath, '/data.txt') app.get("/", (req, res) => { res.redirect('/hello') }) // 저장된 데이터가 있으면 데이터 출력 app.get("/hello", (req, res) => { if(!fs.existsSync(dataFolderPath) || !fs.existsSync(dataPath)) { res.render('hello', { title: 'Hello', message: 'Hello World!!!'}) } else { fs.readFile(dataPath, 'utf-8', (err, data)=> { res.render('data', { title: 'Hello', data: data.split('\n')}) }) } }) app.post("/data", (req, res) => { var recvData = req.body.data // 데이터 저장 폴더 및 데이터 저장 파일 생성 if(!fs.existsSync(dataFolderPath)) { fs.mkdir(dataFolderPath) } if(!fs.existsSync(dataPath)) { fs.appendFile(dataPath, recvData+'\n', (error) => { if(error) { res.status(500).json({ 'msg': 'Internal server error' }); } else { res.status(200).json({ 'msg': 'Data registered successfully' }); } }) } else { fs.readFile(dataPath, 'utf-8', (err, data)=> { if(err) { res.status(500).json({ 'msg': 'Internal server error' }); } else { // 10개 이상 데이터 추가 시 10개만 저장 var dataArr = data.split('\n') if(dataArr.length < 10) { fs.appendFile(dataPath, recvData+'\n', (error) => { if(error) { res.status(500).json({ 'msg': 'Internal server error' }); } else { res.status(200).json({ 'msg': 'Data registered successfully' }); } }) } else { dataArr.splice(dataArr.length-1, 1) dataArr.splice(0,dataArr.length - 9) dataArr.push(recvData) var file = fs.createWriteStream(dataPath); file.on('error', (err) => { if(err) console.log(err) }) dataArr.forEach((item) => { file.write(item + '\n') }) file.end(); res.status(200).json({ 'msg': 'Data registered successfully' }); } } }) } })
서버에서는 POST 요청에 의해 들어오는 JSON 형태의 값을 data.txt 파일에 저장하고 웹브라우저에서 http://localhost:3000/ 로 접속을 하면 data.txt 파일을 읽어와 데이터를 보여줍니다.
저장하는 데이터는 최근에 들어온 데이터 10개만 저장하도록 합니다.
[ data.pug ]
html head title= title body if data for val in data h1= val
데이터가 존재할 시 렌더링할 웹페이지를 구현한 pug 파일입니다. data 배열이 전달되면 이를 한 라인씩 화면에 출력합니다.
이로써 서버 쪽 준비는 완료되었습니다.
다음은 ESP32 에서 POST 요청을 하기 위한 코드를 짜 보도록 하겠습니다.
POST 요청 시 전송할 데이터를 JSON 형태로 만들기 위해 ArduinoJson 라이브러리가 필요합니다.
Arduino IDE 상단의 스케치 -> 라이브러리 포함하기 -> 라이브러리 관리에 들어가 ArduinoJson을 검색해 최신 Stable 버전인 5.13.2를 다운로드 받습니다.
그 후 아래와 같이 코드를 작성합니다.
[ HttpClient.ino ]
#include <WiFi.h> #include <HTTPClient.h> #include <ArduinoJson.h> const char* ssid = "your_ssid"; // 와이파이 SSID const char* password = "your_pw"; // 와이파이 비밀번호 void setup() { Serial.begin(115200); delay(10); Serial.println(); Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, password); // 와이파이망에 연결 while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); } void loop() { HTTPClient http; http.begin("http://www.server_addr.com/data"); // 서버 주소 http.addHeader("Content-Type", "application/json"); // 랜덤 번호 생성 esp_random(); String num = String(random(0, 256)); Serial.println("num : " + num); // JSON 데이터 생성 StaticJsonBuffer<300> JSONbuffer; JsonObject& encoder = JSONbuffer.createObject(); encoder["data"] = num; char buffer[300]; encoder.prettyPrintTo(buffer, sizeof(buffer)); // POST 후 결과 받음 int httpResponseCode = http.POST(buffer); if(httpResponseCode>0){ String response = http.getString(); Serial.println(httpResponseCode); Serial.println(response); }else{ Serial.print("Error on sending POST: "); Serial.println(httpResponseCode); } http.end(); // 리소스 해제 delay(10000); }
ESP32에서는 10초마다 한 번씩 0부터 255까지 숫자 중 하나를 랜덤하게 생성해 서버로 JSON 형태의 데이터를 전송합니다.
ESP32에 위의 코드를 업로드 하고 웹브라우저를 통해 결과를 확인하면 다음과 같이 출력됩니다.
- NODE.JS 를 이용해 간단한 서버 구축하기(1)
- NODE.JS 를 이용해 간단한 서버 구축하기(2)
- NODE.JS 를 이용해 간단한 서버 구축하기(3)
- NODE.JS 를 이용해 간단한 서버 구축하기(4)
참고자료
[…] NODE.JS 를 이용해 간단한 서버 구축하기(4) […]
소스는 감사한데 올리실때 한번 run 해보시고 올리셨으면 좋겠어요.
소스 그대로 실행하니 TypeError [ERR_INVALID_CALLBACK]: Callback must be a function. Received undefined
계속 에러 떠서 분명바꾼거 없는데 이상하다 싶어 몇시간 투자해서 디버깅하니
node server 코드에 38행에 fs.mkdir(dataFolderPath) 이 부분이 이셉션 나더라고요.
그래서 검색해보니 mkdir은 callback 인자가 required로 필요하고 해서 여기선 mkdirSync() 로 바꿔야 실행되더라고요.