История изменений
Исправление
Moisha_Liberman,
(текущая версия)
:
Ну, положим, как бы я решал эту задачу.
По железу. Во-первых и сразу я бы оставил роутер в покое. Роутит и файерволлит, вот и пусть себе спокойно роутит и файерволлит без дерготни. Иначе это называется «Чем мы занимаемся? Да седьмую шапку шьём…» (Поговорка, распространённая в ряде дружественных контор по мотивам одной древней побасёнки.
Лучше бы «контроллер» вынести на отдельную малинку, как уже посоветовали в треде неоднократно. Если этого не сделать, то формально ничего плохого не случится, но… зачем? Ресурсов вычислительной системы всегда может не хватить и всё откажется работать в самый неприятный момент. К тому же, в ядре Linux совсем не зря есть параметр IP_ADVANCED_ROUTER, который имеет смысл включать именно на «роутере», на «хосте» незачем. Там ещё от него ряд параметров ядра зависит, но нафиг нам на «сервере» таблица маршрутизации (routing table), например?
В общем, я могу написать как было бы на мой взгляд лучше, но считайте что я Вас предупредил – лучше бы отдельную малинку прикрутить и не париться. Хотя, в принципе, предлагаемый мною вариант может и на малинке и на роутере пойти.
По решению. Во-вторых, я бы вспомнил о такой незаслуженно забытой технологии как CGI. Веб-сервер отдаёт клиенту html, css, javascript в самом простейшем виде. От клиента он получает http(s) запрос к CGI (common gateway interface) вида
http://.../cgi-bin/test.cgi?имя=значение&имя1=значение1&...
Ваша задача – получить веб-сервером строку от браузера и передать её на вход «скрипта» CGI. Исторически такие «скрипты» писались на perl, C, хотя ни кто не запрещает хоть на bash писать. Например:
#!/bin/bash
echo "Content-type: text/html"
echo ""
echo '<html>'
echo '<head>'
echo '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
echo '<title>Environment Variables</title>'
echo '</head>'
echo '<body>'
echo 'Environment Variables:'
echo '<pre>'
/usr/bin/env
echo '</pre>'
echo '</body>'
echo '</html>'
exit 0
Этот скрипт выдаст в документ html все нужные переменные окружения. Важным моментом является то, что от веб-сервера скрипт их получает через эти самые environment variables, дальше он парсит нужное (QUERY_STRING, методы GET/POST/PUT), делает какую-то магию и возвращает результат бразеру. Браузер уже отображает что там вернулось. По сути дела, эти «скрипты» это не более чем стандартные unix-процессы со своими stdin, stdout, stderr каждый. И, отсюда, следует вторая проблема с ними – каждый процесс при каждом обращении запускается заново. Если у Вас есть логин в некую БД, то всё может оказаться очень печально. Нет, ни php, ни python, ни ruby с рельсами ничего нового, к сожалению, не привнесли в дело обработки запросов. FastCGI не в счёт, но об этом ниже.
Но как вариант для встраиваемок этот вариант вполне пойдёт. Например, если я хочу сделать для такого же роутера как у Вас, это называется CPE или Customer Premises Equipment, конфигурационную панель, то неужели Вы думаете что я поволоку туда всю инфраструктуру php? Ну Вы же не серьёзно! =))) Именно на cgiшках и делают… Я Вам это гарантирую. =)))
По серверам. Из существующих серверов напрямую и без проблем CGI поддерживаются lighttpd, apache, thttpd (на последний я бы обратил внимание особо, т.к. это сервер для кофемашин и газонокосилок.
Таким образом, у Вас получается две части проекта – опрос данных с устройств и складирование в какую-нибудь базу и отображение данных в веб-интерфейсе, котрые вытягиваются из базу по запросу. CGI позволяет отдавать любой формат – json, xml, html, кроче, что угодно. Отображать в браузере Вы можете тоже как угодно – хоть single page web-appication создать.
Если нужно обрабатывать большое число запросов или база на back end тяжёлая, то имеет смысл задуматься о применении FastCGI. По сути, это почти те же CGI, но стартующие уже при загрузке системы и общающиеся по сокету, т.е., их можно размещать на удалённой машине и запросы от веб-сервера будут передаваться через сокет. Т.е., все те же переменные окружения будут пересылаться на удалённую машину (можно и на локальную, само собой) и тут же парситься, обрабатываться, через веб-сервер клиенту в браузер будет возвращаться ответ. Несомненный плюс – приложение будет отрабатывать запросы пока жив хост, на котором оно работает. Есил есть СУБД, то раз залогинились при старте и дальше этого делать не нужно. Тот fastcgi что есть в php так и работает, кстати. Хотя, в том что CGI запускается при каждом запросе и завершается после отработки запроса, есть и плюс – не будет фрагментации памяти, проблемы, которая по временам здорово подбешивает, особенно при «длинных» запросах и на скромных ресурсах системы. Система сама должна зачистить использованные ресурсы после завершения процесса. С FastCGI можно нарваться на неприятности. В особенности если памяти немного. FastCGI офигенно поддерживается тем же nginx, хотя по размерам он и больше thttpd.
Почему я рекомендую не драть мозг, а использовать «стандартный» веб-сервер? Потому что в принципе можно взять ту же libevent (чтобы не париться с парсингом http-запросов и получить всё и сразу) и написать с её помощью некий веб-сервер (дадада, в 40 строк, ага). Но я бы предпочёл взять мелкий сервер типа thttpd и сконцентрироваться на логике приложения и веб-интерфейса (тот же ajax там реализовать или ещё что, чтобы приложение было бы более-менее современным, технологии это позволяют). Кроме того, использование сервера позволяет не сильно заниматься реализацией поддержки SSL/TLS и аутентификации. Сомневаюсь чтобы Вы хотели поделиться содержимым Вашего умного дома с соседями, ну, например, home video с камер видеонаблюдения. Так что, эти вопросы либо самостоятельно решать, либо пусть ими сервер занимается.
По языкам. Я бы рекомендовал воспользоваться С, благо дело тема эта проработанная годами и существует море библиотек. Например, https://github.com/rafaelsteil/libcgi для построения самих по себе CGI и FastCGI (разница в коде буквально на пяток строк). И https://github.com/ac000/libctemplate если нужны templates для веб-страничек. Хотя, можно и без них, если понимаете что делаете. В результате сторона чтения из СУБД и отображения этой информации в веб-интерфейсе будет плёвая по запрашиваемым ресурсам. Сторона сбора информации и размещения её в СУБД по идее, тоже, если опять же на С. =) Т.е., проект должен получиться максимально лёгким в части требуемых ресурсов. Счёт идёт на килобайты, даже не на сотни килобайт. Да, даже на роутере такое можно сгородить и даже будет работать, но… смысл?
В принципе, конечно, на python тоже можно поднять веб-сервер с поддержкой CGI, но чего-то не втыкает меня вся инфраструктура питона (сам питон, да ещё потом гуано всякого потребуется вагон и маленькая тележка).
По СУБД. Рекомендовали sqlite3. Можно, конечно, но я бы рекомендовал посмотреть в сторону Berkeley DB (теперь это Oracle Embedded). Это именно что встраиваемая СУБД. SQL там нет (точнее, есть, но считайте что нет, он там через зад). В код на С/С++ она добавляется именно как бибилотека, позволяет хранить данные в виде key-value, в общем, если загуглите, то с лёгкостью найдёте. Душевно рекомендую.
Ну вот, как-то вот так, в общем и целом.
P.S. И да, в зависимости от того, что именно Вы хотите, возможно что я бы даже и не стал бы городить огород со всем этим, а просто снимал бы данные с устройств и обрабатывал бы их посредством MQTT (гуглите mosquitto) на телефоне/планшете. Если там планируется сбор телеметрии и только (типа, показания счётчиков, температура, простейшие действия типа открыть-закрыть шторы), то в принципе, этого должно хватить. В каком-нибудь там IoTManager. Тогда вообще всё просто. Должно быть приложение (пусть будет номер 1), читающее данные с устройств и/или записывающее команды на устройства, должен быть «сервер» mosquitto, где для устройств созданы топики, с которыми работает приложение номер 1 (как публикует там данные, так и получает публикации), ну и IoTManagerом мы читаем-пишем данные на пользовательском устройстве. В разы проще. Ну и см. libmosquitto (хоть там и С, да).
Исходная версия
Moisha_Liberman,
:
Посмотерл на требования, сказал про себя "ого"... =)))
Ну, положим, как бы я решал эту задачу.
По железу. Во-первых и сразу я бы оставил роутер в покое. Роутит и файерволлит, вот и пусть себе спокойно роутит и файерволлит без дерготни. Иначе это называется «Чем мы занимаемся? Да седьмую шапку шьём…» (Поговорка, распространённая в ряде дружественных контор по мотивам одной древней побасёнки.
Лучше бы «контроллер» вынести на отдельную малинку, как уже посоветовали в треде неоднократно. Если этого не сделать, то формально ничего плохого не случится, но… зачем? Ресурсов вычислительной системы всегда может не хватить и всё откажется работать в самый неприятный момент. К тому же, в ядре Linux совсем не зря есть параметр IP_ADVANCED_ROUTER, который имеет смысл включать именно на «роутере», на «хосте» незачем. Там ещё от него ряд параметров ядра зависит, но нафиг нам на «сервере» таблица маршрутизации (routing table), например?
В общем, я могу написать как было бы на мой взгляд лучше, но считайте что я Вас предупредил – лучше бы отдельную малинку прикрутить и не париться. Хотя, в принципе, предлагаемый мною вариант может и на малинке и на роутере пойти.
По решению. Во-вторых, я бы вспомнил о такой незаслуженно забытой технологии как CGI. Веб-сервер отдаёт клиенту html, css, javascript в самом простейшем виде. От клиента он получает http(s) запрос к CGI (common gateway interface) вида
http://.../cgi-bin/test.cgi?имя=значение&имя1=значение1&...
Ваша задача – получить веб-сервером строку от браузера и передать её на вход «скрипта» CGI. Исторически такие «скрипты» писались на perl, C, хотя ни кто не запрещает хоть на bash писать. Например:
#!/bin/bash
echo "Content-type: text/html"
echo ""
echo '<html>'
echo '<head>'
echo '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
echo '<title>Environment Variables</title>'
echo '</head>'
echo '<body>'
echo 'Environment Variables:'
echo '<pre>'
/usr/bin/env
echo '</pre>'
echo '</body>'
echo '</html>'
exit 0
Этот скрипт выдаст в документ html все нужные переменные окружения. Важным моментом является то, что от веб-сервера скрипт их получает через эти самые environment variables, дальше он парсит нужное (QUERY_STRING, методы GET/POST/PUT), делает какую-то магию и возвращает результат бразеру. Браузер уже отображает что там вернулось. По сути дела, эти «скрипты» это не более чем стандартные unix-процессы со своими stdin, stdout, stderr каждый. И, отсюда, следует вторая проблема с ними – каждый процесс при каждом обращении запускается заново. Если у Вас есть логин в некую БД, то всё может оказаться очень печально. Нет, ни php, ни python, ни ruby с рельсами ничего нового, к сожалению, не привнесли в дело обработки запросов. FastCGI не в счёт, но об этом ниже.
Но как вариант для встраиваемок этот вариант вполне пойдёт. Например, если я хочу сделать для такого же роутера как у Вас, это называется CPE или Customer Premises Equipment, конфигурационную панель, то неужели Вы думаете что я поволоку туда всю инфраструктуру php? Ну Вы же не серьёзно! =))) Именно на cgiшках и делают… Я Вам это гарантирую. =)))
По серверам. Из существующих серверов напрямую и без проблем CGI поддерживаются lighttpd, apache, thttpd (на последний я бы обратил внимание особо, т.к. это сервер для кофемашин и газонокосилок.
Таким образом, у Вас получается две части проекта – опрос данных с устройств и складирование в какую-нибудь базу и отображение данных в веб-интерфейсе, котрые вытягиваются из базу по запросу. CGI позволяет отдавать любой формат – json, xml, html, кроче, что угодно. Отображать в браузере Вы можете тоже как угодно – хоть single page web-appication создать.
Если нужно обрабатывать большое число запросов или база на back end тяжёлая, то имеет смысл задуматься о применении FastCGI. По сути, это почти те же CGI, но стартующие уже при загрузке системы и общающиеся по сокету, т.е., их можно размещать на удалённой машине и запросы от веб-сервера будут передаваться через сокет. Т.е., все те же переменные окружения будут пересылаться на удалённую машину (можно и на локальную, само собой) и тут же парситься, обрабатываться, через веб-сервер клиенту в браузер будет возвращаться ответ. Несомненный плюс – приложение будет отрабатывать запросы пока жив хост, на котором оно работает. Есил есть СУБД, то раз залогинились при старте и дальше этого делать не нужно. Тот fastcgi что есть в php так и работает, кстати. Хотя, в том что CGI запускается при каждом запросе и завершается после отработки запроса, есть и плюс – не будет фрагментации памяти, проблемы, которая по временам здорово подбешивает, особенно при «длинных» запросах и на скромных ресурсах системы. Система сама должна зачистить использованные ресурсы после завершения процесса. С FastCGI можно нарваться на неприятности. В особенности если памяти немного. FastCGI офигенно поддерживается тем же nginx, хотя по размерам он и больше thttpd.
Почему я рекомендую не драть мозг, а использовать «стандартный» веб-сервер? Потому что в принципе можно взять ту же libevent (чтобы не париться с парсингом http-запросов и получить всё и сразу) и написать с её помощью некий веб-сервер (дадада, в 40 строк, ага). Но я бы предпочёл взять мелкий сервер типа thttpd и сконцентрироваться на логике приложения и веб-интерфейса (тот же ajax там реализовать или ещё что, чтобы приложение было бы более-менее современным, технологии это позволяют). Кроме того, использование сервера позволяет не сильно заниматься реализацией поддержки SSL/TLS и аутентификации. Сомневаюсь чтобы Вы хотели поделиться содержимым Вашего умного дома с соседями, ну, например, home video с камер видеонаблюдения. Так что, эти вопросы либо самостоятельно решать, либо пусть ими сервер занимается.
По языкам. Я бы рекомендовал воспользоваться С, благо дело тема эта проработанная годами и существует море библиотек. Например, https://github.com/rafaelsteil/libcgi для построения самих по себе CGI и FastCGI (разница в коде буквально на пяток строк). И https://github.com/ac000/libctemplate если нужны templates для веб-страничек. Хотя, можно и без них, если понимаете что делаете. В результате сторона чтения из СУБД и отображения этой информации в веб-интерфейсе будет плёвая по запрашиваемым ресурсам. Сторона сбора информации и размещения её в СУБД по идее, тоже, если опять же на С. =) Т.е., проект должен получиться максимально лёгким в части требуемых ресурсов. Счёт идёт на килобайты, даже не на сотни килобайт. Да, даже на роутере такое можно сгородить и даже будет работать, но… смысл?
В принципе, конечно, на python тоже можно поднять веб-сервер с поддержкой CGI, но чего-то не втыкает меня вся инфраструктура питона (сам питон, да ещё потом гуано всякого потребуется вагон и маленькая тележка).
По СУБД. Рекомендовали sqlite3. Можно, конечно, но я бы рекомендовал посмотреть в сторону Berkeley DB (теперь это Oracle Embedded). Это именно что встраиваемая СУБД. SQL там нет (точнее, есть, но считайте что нет, он там через зад). В код на С/С++ она добавляется именно как бибилотека, позволяет хранить данные в виде key-value, в общем, если загуглите, то с лёгкостью найдёте. Душевно рекомендую.
Ну вот, как-то вот так, в общем и целом.