-
1. Data: 2020-06-05 22:57:50
Temat: Embedded HTTP Server
Od: Maciej Sobczak <s...@g...com>
Z przyjemnością informuję o narodzinach wersji 1.0 nowego pakietu:
http://www.inspirel.com/httpserver/
Jest to bardzo prosta biblioteka w C++11, dla systemów Linux, Mac OS X oraz Windows,
pozwalająca progamowi w C++ wyświetlić swoje GUI na przeglądarce webowej.
Idea jest również opisana tutaj:
https://en.wikipedia.org/wiki/Embedded_HTTP_server
i wbrew nazwie nie ma bezpośredniego związku z systemami wbudowanymi (chociaż na
RaspberryPi i podobnych można by było z satysfakcją domknąć tą definicję).
Wszelkie komentarze mile widziane.
--
Maciej Sobczak * http://www.inspirel.com
-
2. Data: 2020-06-06 12:44:20
Temat: Re: Embedded HTTP Server
Od: Wojciech Muła <w...@g...com>
On Friday, June 5, 2020 at 10:57:51 PM UTC+2, Maciej Sobczak wrote:
> Z przyjemnością informuję o narodzinach wersji 1.0 nowego pakietu:
>
> http://www.inspirel.com/httpserver/
>
> Jest to bardzo prosta biblioteka w C++11, dla systemów Linux, Mac OS X oraz
Windows, pozwalająca progamowi w C++ wyświetlić swoje GUI na przeglądarce webowej.
>
> Idea jest również opisana tutaj:
>
> https://en.wikipedia.org/wiki/Embedded_HTTP_server
>
> i wbrew nazwie nie ma bezpośredniego związku z systemami wbudowanymi (chociaż na
RaspberryPi i podobnych można by było z satysfakcją domknąć tą definicję).
>
> Wszelkie komentarze mile widziane.
file_mime_type("html") zwróci "text/html" zamiast "text/plain"
-
3. Data: 2020-06-06 14:34:45
Temat: Re: Embedded HTTP Server
Od: heby <h...@p...onet.pl>
On 05/06/2020 22:57, Maciej Sobczak wrote:
> Wszelkie komentarze mile widziane.
Jeśli jednak to miało by być embedded SILNIE sugeruje abyś usunął wątki.
Zamiast tego używaj coroutines.
Jeśli ktoś będzie chciał wątki to sobie dorobi albo mu dasz na bazie
tych coroutines.
W drugą stronę nie ma jak.
Wiele systemów embedded dysponuje tylko cooperative multitaskingiem.
Wątki powinny być następną, opcjonalną warstwą nad coroutines.
Tak, zdaje sobie sprawę że to absurdalna prośba, jak bibliteka jest już
gotowa. Ale pytałeś o wszelkie komentarze ...
-
4. Data: 2020-06-06 19:10:13
Temat: Re: Embedded HTTP Server
Od: Wojciech Muła <w...@g...com>
On Friday, June 5, 2020 at 10:57:51 PM UTC+2, Maciej Sobczak wrote:
> Z przyjemnością informuję o narodzinach wersji 1.0 nowego pakietu:
>
> http://www.inspirel.com/httpserver/
>
> Jest to bardzo prosta biblioteka w C++11, dla systemów Linux, Mac OS X oraz
Windows, pozwalająca progamowi w C++ wyświetlić swoje GUI na przeglądarce webowej.
>
> Idea jest również opisana tutaj:
>
> https://en.wikipedia.org/wiki/Embedded_HTTP_server
>
> i wbrew nazwie nie ma bezpośredniego związku z systemami wbudowanymi (chociaż na
RaspberryPi i podobnych można by było z satysfakcją domknąć tą definicję).
>
> Wszelkie komentarze mile widziane.
Po pierwsze, to aż się prosi, żeby ten serwer był zwykłą klasą. Czemu ktoś nie miałby
sobie stworzyć 5 serwisów WWW działających na różnych portach?
Po drugie, nie ma sposobu na zamknięcie serwera, poza zabiciem procesu. Chyba, że ja
czegoś nie widzę.
Mówiąc o API: 6 wariantów register_{generic,html,text}_{post,get}_action można by
sprowadzić do 2. register_action(const char* name, {post_action_type,
get_action_type} callback, const char* mime_type). Zresztą, może lepiej byłoby
przyjmować jako argument mapę akcji - czyli to co masz teraz w
get_actions/post_actions. Niech user sobie przygotuje takie mapy w sposób, jaki mu
pasuje, a ty pozbędziesz się potrzeby blokowania tych struktur.
Czasem funkcje przyjmują const char*, czase std::string& co jest niespójne.
W ogóle nie walidujesz, czy wskaźniki są niepuste. Tak samo z std::function.
Zero testów. Serio? :)
w.
-
5. Data: 2020-06-06 20:34:09
Temat: Re: Embedded HTTP Server
Od: Maciej Sobczak <s...@g...com>
> file_mime_type("html") zwróci "text/html" zamiast "text/plain"
To dobrze? Źle? Jak powinno być i dlaczego?
--
Maciej Sobczak * http://www.inspirel.com
-
6. Data: 2020-06-06 20:42:06
Temat: Re: Embedded HTTP Server
Od: Maciej Sobczak <s...@g...com>
> Jeśli jednak to miało by być embedded SILNIE sugeruje abyś usunął wątki.
> Wiele systemów embedded dysponuje tylko cooperative multitaskingiem.
> Wątki powinny być następną, opcjonalną warstwą nad coroutines.
Jak do tej pory częściej widziałem sensownie działające wątki (takie prawdziwe), niż
sensownie działający stos TCP. I nie chodzi o bugi, tylko o dostępne API albo metodę
obsługi. Więc priorytety są inne.
> Tak, zdaje sobie sprawę że to absurdalna prośba, jak bibliteka jest już
> gotowa. Ale pytałeś o wszelkie komentarze ...
Nie jest absurdalna, bo wersja ver > 1.0 nie jest jeszcze gotowa. :-)
--
Maciej Sobczak * http://www.inspirel.com
-
7. Data: 2020-06-06 21:00:05
Temat: Re: Embedded HTTP Server
Od: Maciej Sobczak <s...@g...com>
> Po pierwsze, to aż się prosi, żeby ten serwer był zwykłą klasą. Czemu ktoś nie
miałby sobie stworzyć 5 serwisów WWW działających na różnych portach?
No właśnie. I tu poruszamy ważną kwestię. Bo piszesz, że aż się prosi, ale potem
okazuje się, że nikt nie prosi, tylko czemu ktoś by miał nie prosić.
A mi chodziło o to, żeby pakiet 1.0 przekroczył próg używalności a nie o to, żeby
rozwiązać problemy typu "czemy ktoś nie miałby".
Natomiast, nic nie stoi na przeszkodzie, żeby sobie zawołać funkcję server_start() 5
razy z różnymi portami, z 5 różnych wątków, bo ta funkcja i tak nie ma stanu
globalnego. Nie trzeba mieć do tego klasy.
> Po drugie, nie ma sposobu na zamknięcie serwera, poza zabiciem procesu. Chyba, że
ja czegoś nie widzę.
Tak. Funkcja server_stop() już istniała, ale ją usunąłem. To nie jest oczywiste, jak
zamknąć serwer, który ma callbacki, niektóre zapewne w trakcie pracy.
Wszystkie problemy da się rozwiązać, ale nie o to chodziło w wersji 1.0.
> Mówiąc o API: 6 wariantów register_{generic,html,text}_{post,get}_action można by
sprowadzić do 2. register_action(const char* name, {post_action_type,
get_action_type} callback, const char* mime_type).
Nie, bo po pierwsze generic i html różnią się obsługą a po drugie nie chciałem
przeciążać funkcji register, bo bardziej naturalne wydaje mi się przeciążenie funkcji
akcji dla get i post:
void my_action(to-co-trzeba-dla-get) { ... }
void my_action(to-co-trzeba-dla-post) { ... }
I wtedy nie dałoby rady:
register(my_action);
> Zresztą, może lepiej byłoby przyjmować jako argument mapę akcji - czyli to co masz
teraz w get_actions/post_actions. Niech user sobie przygotuje takie mapy w sposób,
jaki mu pasuje, a ty pozbędziesz się potrzeby blokowania tych struktur.
Ale teraz obsługa jest prostsza, właśnie dlatego, że user nie musi robić takich map.
Można by było pomyśleć o akcji catch-all. Tam user dostawałby wszystko (co nie było
obsłużone) i mógłby sobie tam zrobić takie mapy, jakie zechce.
> Czasem funkcje przyjmują const char*, czase std::string& co jest niespójne.
Bo chodziło o przewidywane użycie. Tam gdzie przewidywałem literał, jest const char*.
> W ogóle nie walidujesz, czy wskaźniki są niepuste. Tak samo z std::function.
A po co? Bez przesady z tą walidacją. Walidować należy input z zewnątrz (i nawet
opisałem to w przykładzie 3, z parametrami) a nie własne literały.
> Zero testów. Serio? :)
Są testy. W katalogu, który dla zmylenia przeciwnika nazywa się examples. :-)
A jakieś inne testy byś chciał?
--
Maciej Sobczak * http://www.inspirel.com
-
8. Data: 2020-06-06 22:22:58
Temat: Re: Embedded HTTP Server
Od: heby <h...@p...onet.pl>
On 06/06/2020 20:42, Maciej Sobczak wrote:
> Jak do tej pory częściej widziałem sensownie działające wątki (takie prawdziwe),
niż sensownie działający stos TCP. I nie chodzi o bugi, tylko o dostępne API albo
metodę obsługi. Więc priorytety są inne.
OK, zwróć jednak uwagę na to że taki FreeRTOS może być kompilowany jako
preemptive i cooperative.
Ogólnie abstrakcja na wątki była by też przydatna, w końcu może ktoś
będzie chciał zmienić bibliotekę wątków na inną, tak jak właśnie w
FreeRTOS gdzie to nie jest ani win ani posix.
Dodatkowo coroutines pozwalają na implementację czegoś z okolic
"stackless" albo czegoś z okolic "event driven". Oba mają pewne zalety w
embedded, ale maja też zalety w dużym programowaniu.
Nak w trybie narzekania: brakuje bibliotek w logiką na cooroutines,
nawet jesli te coroutines sa robione ręcznie, z maszyną stanów w środku
i zwykłym return. Zazwyczaj wszelakie biblioteki starają się
samodzielnie robić wątki albo wręcz robią while(foo) bar(); uważając że
jak je ktoś wbudował to są najważniejsze ;)
-
9. Data: 2020-06-07 00:02:47
Temat: Re: Embedded HTTP Server
Od: Maciej Sobczak <s...@g...com>
> Ogólnie abstrakcja na wątki była by też przydatna, w końcu może ktoś
> będzie chciał zmienić bibliotekę wątków na inną, tak jak właśnie w
> FreeRTOS gdzie to nie jest ani win ani posix.
Szkoda prądu. Przecież to jest open-source. Jak ktoś bedzie chciał wymienić
standardowe wątki na jakieś inne, to zmienia dosłownie w jednym miejscu to:
std::thread th(connection_thread, sock);
na co tam potrzebuje, no i może jeszcze sygnaturę wołanej funkcji. Robienie
abstrakcji na coś, co jest w jednej linijce, jest po prostu niepotrzebne. Łatwiej
zmienić tą jedną linijkę.
A jeszcze łatwiej zauważyć, że std::thread już jest tą abstrakcją - właśnie
abstrakcją czegoś natywnego, bez narzucania konkretnego rozwiązania. I dokładnie taki
jest sens istnienia tej klasy w std::. Więc jest też opcja podstawienia innej
implementacji tejże standardowej klasy.
Znowu - prawdziwy cyrk to stos TCP. To tam są smoki. Przerobienie tego serwera na
inne wątki to pikuś, ale przestawienie go na inny stos - i to tak, żeby zachować
abstrakcję IOStreams (które są z założenia *blokujące*), to już zupełnie inna zabawa.
> brakuje bibliotek w logiką na cooroutines,
To jest ciekawa uwaga. Pytanie, czy takie podejście ma swoją niszę rynkową, w której
mieści się taki przykładowy serwer HTTP.
Bo ja nie jestem przekonany, czy zawsze cały program trzeba robić jedną metodą. Może
raczej jest tak, że np. komunikację z urządzeniami fizycznymi można zrobić na
coroutinach, ale interfejsu użytkownika już nie warto.
--
Maciej Sobczak * http://www.inspirel.com
-
10. Data: 2020-06-07 00:36:28
Temat: Re: Embedded HTTP Server
Od: heby <h...@p...onet.pl>
On 07/06/2020 00:02, Maciej Sobczak wrote:
> Szkoda prądu. Przecież to jest open-source. Jak ktoś bedzie chciał wymienić
standardowe wątki na jakieś inne, to zmienia dosłownie w jednym miejscu to:
> std::thread th(connection_thread, sock);
> na co tam potrzebuje, no i może jeszcze sygnaturę wołanej funkcji. Robienie
abstrakcji na coś, co jest w jednej linijce, jest po prostu niepotrzebne. Łatwiej
zmienić tą jedną linijkę.
Niby tak, ale już cooperative tak nie obskoczysz.
Ponadto praktyka pozkauje że zmiana "jednej linijki" w biblitece nie
jest prawidłową metodą dopasowania się do czegoś bo za chwile tej
linijki nie będzie w wersji 0.9.3.
> A jeszcze łatwiej zauważyć, że std::thread już jest tą abstrakcją - właśnie
abstrakcją czegoś natywnego, bez narzucania konkretnego rozwiązania. I dokładnie taki
jest sens istnienia tej klasy w std::. Więc jest też opcja podstawienia innej
implementacji tejże standardowej klasy.
To tylko łatwo w teorii, w normalnych systemach "podmienianie"
std::whatever to jest *gruby* hacking...
> Znowu - prawdziwy cyrk to stos TCP. To tam są smoki. Przerobienie tego serwera na
inne wątki to pikuś, ale przestawienie go na inny stos - i to tak, żeby zachować
abstrakcję IOStreams (które są z założenia *blokujące*), to już zupełnie inna zabawa.
Niby tak, ale znowu: co dziwnego w tym że robisz własną abstrakcję do
"ich" abstrakcji?
Tworzysz własny ITcpStream i jakiś adapter do istniejącego/ych. Jak
IOStreams masz blokujace to masz adapter z wątkami. Jak się da robić
pooling, to masz inny adapter bez wątków albo z wątkami. Co kto potrzebuje.
Piszesz rdzeń HTTP w oderwaniu kompletnym od tego jaki stos TCP używasz.
Definiujesz jakieś ITCP, ISTream, IConnection i potem martwisz się w
napisanie kilku adapterów do tego albo do siamtego rozwiązania.
I przy okazji unit testy wychodzą za friko.
>> brakuje bibliotek w logiką na cooroutines,
> To jest ciekawa uwaga. Pytanie, czy takie podejście ma swoją niszę rynkową, w
której mieści się taki przykładowy serwer HTTP.
Owszem, takie event-based są. To nie dokładnie to co coroutines, ale blisko.
> Bo ja nie jestem przekonany, czy zawsze cały program trzeba robić jedną metodą.
Dlatego sugeruje nie zmuszać ludzi do preemptive wątków. Wątki narzucają
pewne rozwiązania logiki w kodzie w sposób intruzywny, np. bez wątków w
jakiejś biblitece nie musisz synchronizować danych, ale np. ponieważ
ktoś w jakiejś biblitece użył wątków to nagle w zupełnie niewątkowym
kodzie masz race conditions bo się jakiś callback wywołał.
> Może raczej jest tak, że np. komunikację z urządzeniami fizycznymi można zrobić na
coroutinach
Tam własnie nie, raczej na przerwaniach które, jak się zamknie jedno
oko, to są takie prawie wątki.
>, ale interfejsu użytkownika już nie warto.
*wszystkie* interfejsy GUI jakie istnieją w sensownym zastosowaniu są
event-based czyli takie coroutines/cooperative.
Chyba że masz na myślie coś innego niż GUI.