Веб сервер

Тема в разделе "ESP8266, ESP32", создана пользователем TebEnkov2222, 14 июн 2018.

  1. TebEnkov2222

    TebEnkov2222 Нерд

    Господа, добрый день.. У меня такой вопрос: можно ли сделать веб сервер на esp-32. Обычный веб сервер я знаю как сделать. Но с оформлением большие проблемы.. И у меня нету модуля sd карты.. Можно ли как то поместить сайт в саму память esp-32?
     
  2. DIYMan

    DIYMan Гуру

    Вопрос: чем отличается обычный веб-сервер от необычного? Ориентацией?

    Ещё вопрос: уверен, что знаешь, как сделать? Чтобы в соответствии с RFC по HTTP всё было, да? Точно уверен? Точно знаешь? Или просто сдёрнешь из куцых примеров, что в поставке? Так вот: в примерах - там НИГДЕ нету имплементации худо-бедненького веб-сервера - там нищебродство, и половину заголовков просто не обрабатываются. Так, заимплементили кой-чего - не более, но это точно не тянет на гордое звание "веб-сервер" ;)

    Так точно знаешь, как сделать веб-сервер? Если точно знаешь - расскажи, плз, как у тебя имплементированы обработчики запроса и ответа Content-Disposition, например.
     
    Andrey12 нравится это.
  3. TebEnkov2222

    TebEnkov2222 Нерд

    Да, точно знаю.. т. к. на уне я уже делал (псевдо) сервер. Выводилась температура, влажность (с DHT11), время.. И можно было управлять 2 реле..
    Вот код..
    Код (C++):

    #include <Wire.h>             // Подключаем бибилиотеку для работы с I2C устройствами
    #include <DS3231.h>           // Подключаем библиотеку для работы с RTC DS3231

    #include "dht.h"

    #include <SPI.h>             //библиотека для работы с SPI
    #include <Ethernet.h>

    #define dht_apin A0

    dht DHT;

    DS3231 clock;
    RTCDateTime DateTime;         // Определяем сущность структуры RTCDateTime (описанной в библиотеке DS3231) для хранения считанных с часов даты и времени
    RTCAlarmTime Alarm1;          // Определяем сущность структуры RTCAlarmTime (описанной в библиотеке DS3231) для хранения считанных с первого будильника настроек даты и времени

           byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDA, 0x02 };    
    //MAC адрес вашего Ethernet-модуля, если его у вас нет, введите любой
    //или оставьте тот, что в примере

          //указываем IP адрес
          //будьте внимательны! IP адрес указывается тот, который вы получили запустив пример DhcpAdressPrinter
          IPAddress ip(192,168,1,103);    //пример МОЕГО IP адреса, вы вводите сюда СВОЙ

      //инифиализация библиотеки Ethernet server library
    EthernetServer server(80);

    boolean newInfo = 0;  
    boolean reley_1 = 0;
    boolean reley_2 = 0;
    boolean isAlarm = false;      // Логическая переменная для обработки сигнала о срабатывании будильника
    boolean alarmState = false;   // Логическая переменная для обработки индикации при срабатывании будильника
    int alarmLED = 4;             // Пин, к которому подключаем индикатор срабатывания будильника (светодиод)

    void alarmFunction()                                  // Функция, вызываемая при срабатывании будильника
    {
      isAlarm = true;                                     // Присваиваем значение "истина" переменной для обработки срабатывания будильника
    }

    void setup(){
      Serial.begin(9600);
         clock.begin();                    // Инициализируем работу с объектом библиотеки DS3231
         clock.enableOutput(false);        // Определяем назначение вывода SQW (INT) для генерации прерываний при сработке будильников
         clock.setDateTime(__DATE__, __TIME__);                  // Устанавливаем время на часах, основываясь на времени компиляции скетча)
         clock.setAlarm1(0, 0, 0, 10, DS3231_MATCH_S);           // Устанавливаем первый будильник на срабатывание в 10 сек. каждой минуты. Режим DS3231_MATCH_S сообщает о том, что ориентироваться надо на секунды.
         pinMode(alarmLED, OUTPUT);                              // Определяем пин подключения питания светодиода, как исходящий
         attachInterrupt(0, alarmFunction, FALLING);             // Задаем функцию для обработки прерывания 0 (на пине 2)
      pinMode(6, OUTPUT);
      pinMode(7, OUTPUT);
                       
      //запускаем сервер с указанными ранее MAC и вашим IP
      Ethernet.begin(mac, ip);
      server.begin();

    }

    void loop()
    {

      DHT.read11(dht_apin);

      {
      DateTime = clock.getDateTime();                                                 // Считываем c часов текущие значения даты и времени в сущность DateTime
      Alarm1 = clock.getAlarm1();                                                     // Считываем c первого будильника текущие настройки даты и времени в сущность Alarm1
      Serial.println(clock.dateFormat("d.m.Y H:i:s - l   ", DateTime));               // Определяем формат вывода даты и выводим на монитор серийного порта
      Serial.println("Temperature: " + String(clock.readTemperature()));              // Выводим значения температуры
      Serial.println("Alarm: " + String(clock.dateFormat("__ __:__:s", Alarm1)));     // Выводим настройки будильника                              
      Serial.println();                                                               // Перевод строки
      delay(1000);                                                                    // Задержка в 1 секунду
    }

      //принимаем данные, посылаемые клиентом
      EthernetClient client = server.available();
      if(client){                                       //если запрос оканчивается пустой строкой
      boolean currentLineIsBlank = true;                //ставим метку об окончании запроса (дословно: текущая линия чиста)
      while (client.connected()) {                      //пока есть соединение с клиентом
        if (client.available()) {                       //если клиент активен
          char c = client.read();                       //считываем посылаемую информацию в переменную "с"
                                                     
          if(newInfo && c == ' '){                      //если переменная новой информации = 1 и "с", в которой записан запрос, равен пустой строке
            newInfo = 0;                                //то обнуляем переменную поступления новой информации
          }
         
          if(c == '$'){                                 //если переменная "с", несущая отправленный нам запрос, содержит символ $
                                                        //(все новые запросы) - "$" подразумевает разделение получаемой информации (символов)
            newInfo = 1;                                //то пришла новая информация, ставим метку новой информации в 1
          }
         
          /************************************************************************************************
          Примечание:
          Символ $ используется как обычный символ, который разделяет 1 от 2
          На практике применяют символ &, который разделяет новые переменные от последующих
          Это использьуется, например, в GET-запросах, которые выглядят подобным образом:
          client.print("GET /controlbar/wp-content/data.php?uid=" + ID + "&type=" + type + "&value=" + value);
          как видите, знак & разделяет значение переменной - ID и переменную type    
          ***************************************************************************************************/

         
                                                         //Проверяем содержание URL - присутствует $1 или $2
          if(newInfo == 1){                              //если есть новая информация
              Serial.println(c);
              if(c == '1'&&reley_1==0){                              //и "с" содержит 1
              Serial.println("ON");
              digitalWrite(6, HIGH);                    //то зажигаем светодиод
              reley_1=1;
              }
             
              if(c == '2'&&reley_1==1){                              //если "с" содержит 2
              Serial.println("OFF");
              digitalWrite(6, LOW);                     //гасим светодиод
              reley_1=0;
              }  
             
              if(c == '3'&&reley_2==0){                              //и "с" содержит 1
              Serial.println("ON");
              digitalWrite(7, HIGH);  
              reley_2=1;
              }
             
              if(c == '4'&&reley_2==1){                              //если "с" содержит 2
              Serial.println("OFF");
              digitalWrite(7, LOW);                     //гасим светодиод
              reley_2=0;
              }  
          }
         
         
          if (c == '\n') {                              //если "с" равен символу новой строки
            currentLineIsBlank = true;                  //то начинаем новую строку
          }
          else if (c != '\r') {                         //иначе, если "с" не равен символу возврата курсора на начало строки
            currentLineIsBlank = false;                 //то получаем символ на текущей строке
          }
       
          if (c == '\n' && currentLineIsBlank) {        //выводим HTML страницу
            client.println("HTTP/1.1 200 OK");          //заголовочная информация
            client.println("Content-Type: text/html");
            client.println("Connection: close");
            client.println("Refresh: 30");              //автоматическое обновление каждые 30 сек
            client.println();
            client.println("<!DOCTYPE HTML>");          //HTML тип документа
            client.println("<html>");                   //открытие тега HTML
            client.println("<head>");
            client.print("<title>My web Server</title>");                  //название страницы
            client.println("</head>");
            client.println("<body>");
            client.print("<H1>My web Server</H1>");                        //заголовк на странице
            client.print("<a>Current humidity = </a>");
            client.print(DHT.humidity,1);
            client.print("<a>%</a>");
            client.println("<br />");
            client.print("<a>temperature = </a>");
            client.print(DHT.temperature,1);
            client.print("<a>C</a>");
            client.println("<br />");
            client.print("<H2>Reley_1</H2>");
            client.print("<a href=\"/$1\"><button>Off</button></a>");       //кнопка включить
            client.print("<a href=\"/$2\"><button>On</button></a>");      //кнопка выключить
            client.println("<br />");
            client.print("<H2>Reley_2</H2>");
            client.print("<a href=\"/$3\"><button>Off</button></a>");       //кнопка включить
            client.print("<a href=\"/$4\"><button>On</button></a>");      //кнопка выключить
            client.println("<br />");
            client.println("</body>");    
            client.println("</html>");                  //закрываем тег HTML
            break;                                      //выход
          }
       
        }
       
      }
      delay(1);                                          //время на получение новых данных
      client.stop();                                     //закрываем соеднение

    }
    }
    не знаю, правильно ли я делал.. Но я делал так..
    И (псевдо) сайты тоже умею делать.. (только html и css)
     
  4. TebEnkov2222

    TebEnkov2222 Нерд

    Можно было использовать JS или JQeri.. Но тогда я их не знал..
     
  5. TebEnkov2222

    TebEnkov2222 Нерд

    И не знаю.. Можно ли их туды впихнуть (не пробовал)..)
     
  6. TebEnkov2222

    TebEnkov2222 Нерд

    Ну я имел в виду: тот что в примерах(чистый html), и То что ты хочешь получить в конечном итоге (Красивый, с оформлением, со всякими там датчиками, шпунтиками и всем всем всем...) =)
     
  7. DIYMan

    DIYMan Гуру

    Где там в коде имплементация веб-сервера - ткните плз пальцем. Не надо подменять понятия: тот код, что вы продемонстрировали, не имеет никакого отношения к веб-серверу. Вывод: вы таки не знаете, что такое веб-сервер.
     
  8. DIYMan

    DIYMan Гуру

    Какое ко всему этому имеет отношение, ВНИМАНИЕ, веб-сервер? Вижу только одно совпадение - буква H в аббревиатуре HTML - да, протокол HTTP тоже имеет такую букву в аббревиатуре, и даже с таким же значением. Однако, совпадение понятия hypertext не делает веб-сервер хоть в какой-то степени причастным к языку разметки, коим является, по определению, HTML. Да и HTTP уже давно вырос из первоначального определения HyperText Transfer Protocol, строго говоря - взять хотя бы тот факт, что файл стилей (*.css) - по определению гипертекстом не является, хотя и может передаваться посредством протокола HTTP.

    Вам точно нужен именно веб-сервер? Или вы хотите просто красивые странички? Что такое веб-сервер, по определению: https://ru.wikipedia.org/wiki/Веб-сервер
     
  9. TebEnkov2222

    TebEnkov2222 Нерд

    Извиняюсь.. Не много не до понял...
    Ладно, разобрался.. По идее нужен то Веб Сервер.. (удаленноё управление котлом). Так как лок. сеть не подойдет. Но и красиво то тоже нужно.. Противно будет смотреть на полупустой белый лист... Но мне хотя бы просто веб сервер разобрать..
     
  10. DIYMan

    DIYMan Гуру

    Сложность задачи зависит от того, насколько полной вы хотите сделать имплементацию HTTP. В простейшем случае (возможно, вас это устроит) - достаточно реализовать обработку методов GET и POST (что касается POST - то там достаточно обработки multipart-form-data - это то же самое, что в GET в параметрах, грубо говоря), URI decode и encode (чтобы корректно работать с escape-последовательностями), обработку некоторых заголовков и выдачу нескольких типов статусов ответа. Будет куцый такой, но уже веб-серверок.