Ajax
Programming
API
C
Comments 25
0
За абстрактный пример — 5 (как мера абстрактности), за содержание — 2.
Если вы сами работали с этой библиотекой, можете сделать другой абстрактный пример, например, как будет выглядеть код для Ардуины Уно и любым wifi модулем на ваш вкус, в режиме сервера, чтобы контроллер получил запрос GET, отпарсил его, нашел запрашиваемый ресурс на SD-карте и отдал клиенту.
Дополнительно сразу хотелось бы уточнить, как будет реализовываться многопоточность (на выбраном wifi модуле), потому как фавиконку клиент запросит сразу же, до окончания передачи тела index.htm.
0
По поводу ардуины ничего не могу сказать, к сожалению — никакого опыта с ней нет :(
0
Ок, может кто из сообщества поделится опытом?
Ниже дал ссылку на подобный Ардуино-форк Монгуза, но старый и на питоне…
Кто-нибудь пытался реализовать подобное?
ArduinoMegaServer не предлагать, там свои тараканы и никак не ребята не отвяжутся от конкретных wifi чипов.
0
Я поясню, на всякий случай, вопрос.
Вот здесь представлен один дипломный проект, где разработчику удалось уместить всё в 2КБ оперативки Ардуины Уно. Но тут накручен питон и… и не раскрутить.
https://github.com/hdlj/Mongoose

Может с тех пор что-то поменялось в библиотеке, но пока Атмеги среди чипов на сайте разработчика нет.
+3
Огромной ложкой дегтя остается лицензия – GPLv2, а ценник на коммерческую лицензию для небольших проектов кусается.


Вроде как для тех, кого это не устраивает, есть civetweb, который является форком Mongoose от 2013-го года (когда Mongoose сменил лицензию).

Но меня вот какой вопрос интересует: если при обработке события MG_EV_HTTP_REQUEST не выставить флаг MG_F_SEND_AND_CLOSE, а передать запрос на обработку куда-то еще, то как отдать результат обработки в соединение когда этот результат будет таки получен (например, спустя 10 секунд после вызова обработчика)?
0
Нужно сохранить conn, и туда выдать ответ, когда он будет готов.
Я для этого делал очереди запросов. Также нужно мониторить соединения, чтобы если оно закрылось — отбраковать все запросы из очереди, которые связаны с данным соединением.
0
Это нужно делать на той же самой нити, где дергаются обработчики? Или можно с другой?
0
Я полагаю, что на той же.
Работать с одним соединением в разных потоках — плохая идея.
Тут весь плюс именно в асинхронной работе в один поток. Т.е. все что делает основной поток — это сетевой ввод-вывод, без диска, без сложной обработки.
+1
Так запрос к базе у вас ведь идет в другом потоке?
поправьте плиз свой пример — чтобы было понятно когда нужно отдать ответ в сохраненный conn

0
Тогда нужно добавить очередь запросов и мониторинг соединений. Это значительно увеличит код.
Хорошо, чуть позже добавлю.
Запрос к базе может идти в том же потоке, если API базы позволяет. Если не позволяет — да, делаем отдельный поток и городим огород с синхронизацией. Но тогда это значительно нивелирует преимущества данного подхода.
+1
Это не пугает — синхронизация не проблема. у меня и так там много ниток для других целей.
подскажите в какой момент вчитывается очередь ответов и в каком обработчике MG_EV_* нужно слать сообщение клиенту — это ведь нужно делать в нитке мангуста, а не в дочерней?
0
Я в комменте ниже описал.
А слать данные можно непосредственно когда их обнаружили в очереди, вне обработчика. Главное в том же потоке мангуста.
0
Ну так как раз в этом и вопрос: как из другого рабочего потока сказать Mongoose, что у меня есть данные на отправку, чтобы на своем потоке Mongoose дернул нужный коллбэк с нужным событием?
0
Тут без коллбэка. Вы просто в потоке мангуста помимо mg_mgr_poll() делаете еще поиск в очереди. Но тогда возникает проблема — mg_mgr_poll() придется делать с нулевым или очень маленьким таймаутом, т.е. чтобы не ждал новых событий. И тогда вы будете выжирать много CPU. Это и есть последствия того, что совмещаем два разных подхода — многопоточность и асинхронность. Возможно можно как-то обойти, но сейчас в голову пока ничего не идет.
0
Очевидно, что делать эти трюки внутри цикла вызовов mg_mgr_poll() — это ерунда. Интересует есть ли возможность зашедулить Mongoose какое-то пользовательское событие из другой рабочей нити. Чтобы Mongoose сам внутри mg_mgr_poll дернул callback с нужным флагом.
0
Ну первое что приходит на ум — слать ему какой-нибудь пакет TCP или UDP из потока с базой. Ну или HTTP-запрос, но это дороговато мне кажется.
0
Пользуюсь с 2014 года — все хорошо.
Сервер принимает запросы от десктопных клиентов в виде сжатого json по http
после обращения к БД возвращает результат так-же в виде json.

Под мангустом лежит sqlite база размером 17 гиг + levelDB 5 гиг

Можно подробнее про асинхронный запрос к БД
как вы его реализовали и в какой момент возвращаете результат?

у меня к бд коннект один но зовется она синхронно и
это оказывается узким местом в результате чего эта связка сносно работает только на VPS с SSD дисками.

Нагрузка у меня очень мелкая 10-20 запросов в секунду.
в каждом запросе пачки по 5-20 ключей размером 39 байт

т.е. в секунду идет 50-400 запросов
0
Насчет sqlite не подскажу, для PostgreSQL libpq позволяет делать асинхронные запросы.
Любое соединение с БД — это тоже сокет так или иначе. Так что если API СУБД позволяет асинхрон — вы в дамках :)
Спасибо за отзыв, интересно!
0
У sqlite нет сокета она так-же как и мангуст встраиваемая и состоит из одного файла на С
но я могу шарить соединение и делать запросы к базе в дочерних нитках.
как сделать очередь запросов представляю — пока не понял в какой момент отдавать назад результат клиенту.

0
Тогда самое простое — сделать два потока — один под мангуст, другой под работу с базой.
Сделать очередь запросов расшареной (привет блокировки!).
Поток мангуста:
1. Поступил HTTP-запрос — записали в очередь
2. Ищем в очереди запросы, для которых имеются готовые к выдаче ответы от БД и выдаем их клиентам
поток базы:
1. Ищем в очереди еще необработанные запросы
2. Нашли — запрашиваем у базы, получаем от нее ответ, если нужно обрабатываем (обработку вообще можно отдельным потоком сделать), записываем ответ в тот же элемент очереди.
Это если по-простому с блокировками очереди. Сюда можно присобачить семафоры/мьютексы чтобы не было напрасных sleep-ов.
+1
идут протоптанной дорожкой — Apache/nginx +… А дальше начинается ад, потому что:...

Все-таки, отдельный HTTPD (чаще, конечно, nginx) — это не ад, а скорее удобство, поскольку вам не нужно заморачиваться с обработкой статических ресурсов, security, рутингом между несколькими инстацами, load balancing, всякой тонкой настройкой соединения и т.д. и т.п.


Так что если PHP в качестве backend не устраивает, то лучше (imho) сделать nginx + [ваш любимый C/C++ backend с HTTP (с тем же Mongoose) или *cgi].

0

Проще из ноды взять http_parser и самим сделать, чем от монгуза удовольствие получить. Попутно ускорение будет, нормальная асинхронность и более красивый код

0
Все супер конечно, но в 2016 вручную разбирать и собирать HTTP запросы как-то влом конечно добавляет гибкости, но и багов тоже.
0
Тут такой пиар создателя этой системки на «РБК вдруг появился. Решил посмотреть что это такое. Ну и, простите, чем это отличается от связки, например, FreeRTOS + UIP? Те же яйца, по-моему, только за лицензию никому и ничего платить не надо.
Only those users with full accounts are able to leave comments. , please.