fpWeb

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

fpWeb

Сообщение S_Gur » 28.02.2022 10:44:11

Доброго времени суток. Мне необходимо написать простенький HTTP-сервер (бэк-энд для небольшого сайта). Прежде с этим никогда не сталкивался. В результате поиска наткнулся на библиотечку fpWeb и немного поигрался с ней. Предварительно решил использовать этот шаблон:

Код: Выделить всё
program webserver;

{$mode objfpc}{$H+}

uses
  {$ifdef UNIX}
    cthreads, cmem,
  {$endif}
  fphttpapp, httpdefs, httproute;

procedure route1(aReq: TRequest; aResp: TResponse);
begin
  aResp.content:='<html><body><h1>Route 1 The Default</h1></body></html>'
end;

procedure route2(aReq: TRequest; aResp: TResponse);
begin
  aResp.content:='<html><body><h1>Route 2</h1></body></html>'
end;

begin
  HTTPRouter.registerRoute('/', @route1, true);
  HTTPRouter.registerRoute('/route2', @route2);
  Application.port := 8080;
  Application.threaded := true;
  Application.initialize;
  Application.run;
end.


В процессе экспериментов никаких особых проблем не заметил, поэтому прошу совета у тех, кто ее использовал: есть ли какие-то подводные камни при использовании этой технологии в промышленной эксплуатации? Есть ли что-то, на что нужно обратить особое внимание? И вообще - стоит ли запускать в пром такой сервер, не имеет ли смысл использовать что-то другое (например, Indy). В общем, буду рад любым советам. Заранее спасибо
S_Gur
постоялец
 
Сообщения: 130
Зарегистрирован: 30.12.2018 22:17:42

Re: fpWeb

Сообщение alexs » 28.02.2022 14:05:48

Он однопоточный.
Если есть вероятность одвременных конектов - то лучше посмотри в сторону fpCGI.
А отлаживать однозначно в виде такого сервера.
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4060
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: fpWeb

Сообщение S_Gur » 28.02.2022 14:26:58

alexs, Application.threaded := true;

Webserver example

This is an example of a simple, cross-platform, multi-threaded web server

Этот пример стопроцентно многопоточный. Именно из-за этого я на нем остановился - насколько я помню, в Indy многопоточность надо реализовывать самому
S_Gur
постоялец
 
Сообщения: 130
Зарегистрирован: 30.12.2018 22:17:42

Re: fpWeb

Сообщение Vadim » 28.02.2022 16:41:24

fpHTTPServer действительно может быть многопоточным. Там у него при установке флага
S_Gur писал(а):.threaded := true;

при попытке законнектится будет создаваться отдельный поток-коннект на основе TThread со своим отдельным сокетом. Насколько он хорошо держит много коннектов - сказать не могу, так как запускал его из чистого любопытства, в промышленных целях никогда не использовал. Два коннекта с одновременной работой (запрос -> отсылка клиенту гигабайтного фала) прогу не завалили. :-)
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: fpWeb

Сообщение alexs » 28.02.2022 17:58:44

S_Gur
Значит я в своё время не дочитал доку. Либо ещё не было.
Сейчас использую этот сервер для отладки cgi. Потом просто пересобираю в режиме cgi и подкладываю на апач.
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4060
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: fpWeb

Сообщение S_Gur » 02.03.2022 12:14:00

Подскажите, пожалуйста, можно ли как-то в данном коде обработать выход из программы? И вообще - какие можно использовать обработчики?
S_Gur
постоялец
 
Сообщения: 130
Зарегистрирован: 30.12.2018 22:17:42

Re: fpWeb

Сообщение Vadim » 02.03.2022 18:34:04

S_Gur
Так Вы класс сделайте, там у Вас будут обработчики, в том числе и на выход...
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: fpWeb

Сообщение S_Gur » 02.03.2022 18:50:35

Vadim, класс породить от THTTPApplication?

P. S. Создал класс от TCustomHTTPApplication. Перекрыл Create - там все нормально. Но перекрытый Destroy не вызывается. Подскажите, пожалуйста, как мне отловить окончание программы
S_Gur
постоялец
 
Сообщения: 130
Зарегистрирован: 30.12.2018 22:17:42

Re: fpWeb

Сообщение Vadim » 06.03.2022 15:26:44

S_Gur
Надеюсь Вы вызываете стандартный метод Free (внутрь которого уже вставлен Destroy)?
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: fpWeb

Сообщение S_Gur » 08.03.2022 09:05:01

Vadim, там проблема была не в этом - я разобрался. Дело в том, что закрытие окна программы (в том числе и нажатием на крестик в правом верхнем углу окна) является для THTTPApplication аварийным выходом и до Free, как я понимаю, в этом случае там просто уже не доходит. Я просто скопировал модуль fphttpapp, создал свой класс от TCustomHTTPApplication и расширил до необходимого функционала процедуры InitHTTP и DoneHTTP. Я перехватил и смог обработать все события аварийного закрытия приложения, но так и не смог понять, как погасить информацию о том, что закрытие было аварийным. В принципе, моя проблема решена, хотя, конечно, красивее было бы при аварийном закрытии окна добиться штатного закрытия приложения. Потому как при штатном закрытии можно просто поместить нужный код в файл проекта после Application.Run, а при аварийном закрытии до этого кода дело не доходит
S_Gur
постоялец
 
Сообщения: 130
Зарегистрирован: 30.12.2018 22:17:42

Re: fpWeb

Сообщение Vadim » 08.03.2022 11:49:12

S_Gur
Ага, это уже немного другая информация... :-) Если Вы используете окно (форму), то у формы есть стандартное свойство и даже два, которые происходят при закрытии окна крестиком - OnClose и OnCloseQuery. Чисто теоретически, при закрытии окна должны правильно закрываться и все входящие в его состав компоненты. Возможно (я этот вопрос особо не исследовал) с визуальными компонентами так и происходит. А вот с невизуальными (в Вашем случае это компонент THTTPApplication) этого то и не происходит и для них закрытие окна будет аварийным, нестандартным завершением. Именно поэтому в свойство OnClose (или OnCloseQuery) нужно записать код праильного завершения\уничтожения этих невизуальных компонентов. Т.е. должно быть что-то вроде этого:
Код: Выделить всё
procesure Form1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
    HTTPApplication.Free;
end;

и теперь, при закрытии окна крестиком, у нас будет в принудительном порядке вызываться стандартная процедура уничтожения объекта HTTPApplication, при котором отрабатывает и заданный Вами Destroy.
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: fpWeb

Сообщение S_Gur » 08.03.2022 13:09:49

Vadim, я не использую никаких форм. При запуске THTTPApplication открывается окно консольного приложения. Его тоже можно закрыть крестиком. Я так понимаю, у вас сложилось впечатление, что я новичок в программировании. Это не так. На дельфях я работаю с первой версии, с Лазарусом сталкиваюсь реже, но обработать закрытие главной формы пока могу... :D Другое дело, что я никогда не писал веб-приложений, и сейчас разбираюсь с тонкостями именно этого направления. К вам никоим образом никаких претензий, просто чтобы ни вы ни я не теряли время на обсуждение обработки событий типа OnClose или OnCloseQuery
S_Gur
постоялец
 
Сообщения: 130
Зарегистрирован: 30.12.2018 22:17:42

Re: fpWeb

Сообщение vk_barnaul » 08.03.2022 14:28:08

del
vk_barnaul
незнакомец
 
Сообщения: 5
Зарегистрирован: 19.09.2015 04:48:21

Re: fpWeb

Сообщение Vadim » 08.03.2022 16:32:30

S_Gur писал(а):Я так понимаю, у вас сложилось впечатление, что я новичок в программировании. Это не так.

Видите ли, я могу складывать свои впечатления исключительно на основе Ваших слов, никаких других источников информации у меня нет. ;-) Правда хочу сказать, что держать консольное окно только ради Web-сервера, которому такое окно ни разу не нужно - это несколько странно. :-) Впрочем, это уже неважно. Если Вы не новичок, тогда можете спокойно посылать своему серверу команды через тот протокол, который используете и тогда с помощью команды, определённой как закрытие сервера, у Вас метод обработки этой команды должен вызывать метод Free и приложение будет закрываться правильно.
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: fpWeb

Сообщение S_Gur » 08.03.2022 16:38:07

Vadim, что значит "держать консольное окно"? Я тестировал конкретный код, который привел в первом посте. Там нет выбора - держать его или не держать. При запуске приложения открывается консольное окно - чтобы его не держать, надо просто писать другое приложение и - сильно подозреваю - не на основе THTTPApplication. А главная проблема в том, что сервера, на которых размещаются веб-приложения, имеют обыкновение перезагружаться или выключаться независимо от пользователя. В этот момент они посылают всем запущенным приложениям сообщение о закрытии. И это сообщение нужно отловить и обработать, чтобы корректно закрыть программу. Я-то как раз без проблем могу корректно и неаварийно закрыть приложение
S_Gur
постоялец
 
Сообщения: 130
Зарегистрирован: 30.12.2018 22:17:42

След.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 9

Рейтинг@Mail.ru