06.01(14주차) Web Server - rlarlqor0513/smart-device GitHub Wiki

동기 서버와 비동기 서버

image

동기 서버 (Synchronous Server):

  1. 동기 서버는 클라이언트 요청을 순차적으로 처리합니다.
  2. 요청이 도착하면 해당 요청을 처리하는 동안 다른 요청은 차단됩니다.
  3. 요청에 대한 응답을 완료하기 전까지는 다음 요청을 처리할 수 없습니다.
  4. 간단하고 직관적인 코드 작성이 가능하며, 동기적인 특성으로 인해 로직의 순서와 흐름을 이해하기 쉽습니다.
  5. 단일 쓰레드나 제한된 쓰레드 풀을 사용하여 동작하므로, 동시에 처리할 수 있는 요청 수가 제한적일 수 있습니다.
  6. 입출력 작업이 많거나 처리 시간이 긴 작업이 있을 경우, 다른 요청들이 블록되어 성능 저하가 발생할 수 있습니다.

비동기 서버 (Asynchronous Server):

  1. 비동기 서버는 클라이언트 요청을 차단하지 않고 비동기적으로 처리합니다. 요청이 도착하면 해당 요청을 처리하는 동안 다른 요청을 계속해서 처리할 수 있습니다.
  2. 요청에 대한 응답을 기다리지 않고 다음 요청을 처리하기 때문에, 여러 요청을 동시에 처리할 수 있습니다.
  3. 비동기적인 특성으로 인해 비동기 코드의 작성이 복잡할 수 있으며, 로직의 순서와 흐름을 파악하기 어려울 수 있습니다.
  4. 다중 쓰레드 또는 이벤트 기반의 비동기 I/O 모델을 사용하여 동작하므로, 동시에 처리할 수 있는 요청 수가 많아집니다.
  5. 입출력 작업이 많거나 처리 시간이 긴 작업을 비동기적으로 처리할 수 있어서, 다른 작업을 블록하지 않고 성능을 향상시킬 수 있습니다.

라이브러리 설치

https://github.com/me-no-dev/ESPAsyncWebServer
https://github.com/me-no-dev/AsyncTCP

위 깃허브에서 각각 코드를 다운로드 해주고 아두이노 라이브러리에 설치해준다.

image

코드 업로드

#include <Wire.h>
#include "DHT.h"
#include <WiFi.h>
#include "ESPAsyncWebServer.h"

// Replace with your network credentials
const char* ssid = "Enter Your WiFi Name";
const char* password = "Enter your WiFi Password";

// Uncomment one of the lines below for whatever DHT sensor type you're using!
//#define DHTTYPE DHT11 // DHT 11
//#define DHTTYPE DHT21 // DHT 21 (AM2301)
#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
//DHT Sensor;
uint8_t DHTPin = 4;
DHT dht(DHTPin, DHTTYPE);

float temperature_Celsius;
float temperature_Fahrenheit;
float Humidity;

AsyncWebServer server(80);
AsyncEventSource events("/events");

unsigned long lastTime = 0;  
unsigned long timerDelay = 30000;  // send readings timer

void getDHTReadings(){
 
   Humidity = dht.readHumidity();
  // Read temperature as Celsius (the default)
  temperature_Celsius = dht.readTemperature();
  // Read temperature as Fahrenheit (isFahrenheit = true)
  temperature_Fahrenheit= dht.readTemperature(true);
}

String processor(const String& var){
  getDHTReadings();
  //Serial.println(var);
  if(var == "TEMPERATURE_C"){
    return String(temperature_Celsius);
  }
  else if(var == "TEMPERATURE_F"){
    return String(temperature_Fahrenheit);
  }
   else if(var == "HUMIDITY"){
    return String(Humidity);
  }
}

const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
  <title>DHT Web Server</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
  <link rel="icon" href="data:,">
  <style>
    html {font-family: Arial; display: inline-block; text-align: center;}
    p {  font-size: 1.2rem;}
    body {  margin: 0;}
    .topnav { overflow: hidden; background-color: #4B1D3F; color: white; font-size: 1.7rem; }
    .content { padding: 20px; }
    .card { background-color: white; box-shadow: 2px 2px 12px 1px rgba(140,140,140,.5); }
    .cards { max-width: 700px; margin: 0 auto; display: grid; grid-gap: 2rem; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
    .reading { font-size: 2.8rem; }
    .card.temperature { color: #0e7c7b; }
    .card.humidity { color: #17bebb; }
  </style>
</head>
<body>
  <div class="topnav">
    <h3>DHT WEB SERVER</h3>
  </div>
  <div class="content">
    <div class="cards">
      <div class="card temperature">
        <h4><i class="fas fa-thermometer-half"></i> TEMPERATURE</h4><p><span class="reading"><span id="temp_celcius">%TEMPERATURE_C%</span> &deg;C</span></p>
      </div>
      <div class="card temperature">
        <h4><i class="fas fa-thermometer-half"></i> TEMPERATURE</h4><p><span class="reading"><span id="temp_fahrenheit">%TEMPERATURE_F%</span> &deg;F</span></p>
      </div>
      <div class="card humidity">
        <h4><i class="fas fa-tint"></i> HUMIDITY</h4><p><span class="reading"><span id="hum">%HUMIDITY%</span> &percnt;</span></p>
      </div>
    </div>
  </div>
<script>
if (!!window.EventSource) {
 var source = new EventSource('/events');
 
 source.addEventListener('open', function(e) {
  console.log("Events Connected");
 }, false);
 source.addEventListener('error', function(e) {
  if (e.target.readyState != EventSource.OPEN) {
    console.log("Events Disconnected");
  }
 }, false);
 
 source.addEventListener('message', function(e) {
  console.log("message", e.data);
 }, false);
 
 source.addEventListener('temperature_Celsius', function(e) {
  console.log("temperature", e.data);
  document.getElementById("temp_celcius").innerHTML = e.data;
 }, false);
 
 source.addEventListener('temperature_Fahrenheit', function(e) {
  console.log("temperature", e.data);
  document.getElementById("temp_fahrenheit").innerHTML = e.data;
 }, false);
 source.addEventListener('humidity', function(e) {
  console.log("humidity", e.data);
  document.getElementById("hum").innerHTML = e.data;
 }, false);
 
}
</script>
</body>
</html>)rawliteral";
void setup() {
  Serial.begin(115200);
  pinMode(DHTPin, INPUT);
  dht.begin();
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Setting as a Wi-Fi Station..");
  }
  Serial.print("Station IP Address: ");
  Serial.println(WiFi.localIP());
  Serial.println();
  
  // Handle Web Server
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html, processor);
  });
  // Handle Web Server Events
  events.onConnect([](AsyncEventSourceClient *client){
    if(client->lastId()){
      Serial.printf("Client reconnected! Last message ID that it got is: %u\n", client->lastId());
    }
    // send event with message "hello!", id current millis
    // and set reconnect delay to 1 second
    client->send("hello!", NULL, millis(), 10000);
  });
  server.addHandler(&events);
  server.begin();
}
void loop() {
  if ((millis() - lastTime) > timerDelay) {
    
    getDHTReadings();
    Serial.printf("Temperature = %.2f ºC \n", temperature_Celsius);
    Serial.printf("Temperature = %.2f ºF \n", temperature_Fahrenheit);
    Serial.printf("Humidity= %f %\n", Humidity);
    Serial.println();
    // Send Events to the Web Server with the Sensor Readings
    events.send("ping",NULL,millis());
    events.send(String(temperature_Celsius).c_str(),"temperature_Celsius",millis());
    events.send(String(temperature_Fahrenheit).c_str(),"temperature_Fahrenheit",millis());
    events.send(String(Humidity).c_str(),"humidity",millis());
    
    lastTime = millis();
  }
}

IP접속

image

시리얼 모니터에서 IP 확인 후 접속

IP 주소에서 결과값 확인

37

⚠️ **GitHub.com Fallback** ⚠️