Пример серверного приложения

      Комментарии к записи Пример серверного приложения отключены

Лабораторная работа 10

CGI-сценарии

Цель работы

Ознакомиться с организацией исполняемых приложений на web-сервере и изучить технологию программирования CGI-сценариев.

Теоретическая справка

Создание модуля Web

Серверные приложения строятся в C++Builder на основе модуля Web — компонента типа TWebModule.Этот компонент может служить контейнером для ряда других компонентов. Сервер типа TWebModuleотсутствует в палитре компонентов. Чтобы спроектировать его, надо выполнить команду File | New | Other и в диалоговом окне New Items на странице New выбрать пиктограмму Web Server Application. Перед вами откроется окно, в котором вы должны указать тип модуля. Выберите тип CGI Stand-alone executable — выполняемый модуль CGI. После этого C++Builder создаст в Редакторе Кода заготовку соответствующего модуля и вы увидите окно модуля.

Это окно различается в C++ Builder 6 и 5. В C++Builder 6 вы увидите просто пустое окно, в котором можно размещать компоненты, создающие страницы, осуществляющие связи с базами данных и т.п. Поскольку пока все эти компоненты нам не будут нужны, мы можем о нем временно забыть, кроме одного его свойства: из контекстного меню этого окна мы сможем вызвать редактор действий, с которым будем работать. Если вы откроете окно дерева объектов (Object TreeView), то увидите в нем дерево действий, которые будете вводить в модуль (вначале, конечно, вершина Actions в нем будет пустой). Это окно помогает осуществлять навигацию по действиям.

В C++ Builder 5 окно модуля Web отличается только тем, что два указанных выше окна отображаются отдельными панелями одного окна. К тому же там имеется страница Data Diagram, позволяющая строить диаграммы связей между компонентами. В С++ Builder б подобная страница в модуле просто не нужна, так как аналогичная страница имеется в окне Редактора Кода.

В окне Инспектора Объектов вы можете видеть свойства модуля Web (в С++ Builder 5 вы увидите их, если выделите вершину WebModulel). Основное свойство модуля — Actions.Это собрание действий — объектов типа TWebActi-onltem.Заполняется это список специальным редактором действий, вызываемым щелчком на кнопке с многоточием в окне Инспектора Объектов рядом со свойством Actions. То же окно редактора действий откроется, если вы щелкнете в окне модуля (в C++Builder 5 — на вершине WebModulel) правой кнопкой мыши и выберете из контекстного меню раздел Action Editor. В открывшемся окне быстрой кнопкой Add New вы можете добавить новое действие, кнопкой Delete Selected (вторая слева) — удалить выделенное действие, кнопками со стрелками — изменить последовательность действий.

Каждое действие — объект типа TWebActionltemsсо своими свойствами, методами, событиями. Свойства вы можете увидеть в Инспекторе Объектов, выделив одно из действий. Основное свойство действия — Pathlnfo.Чтобы понять его назначение, надо сообщить некоторые дополнительные сведения об URL. В более общем случае URL может выглядеть, например, так:

http://www.myserv.com/pi/servl.exe/actionl?value=5Resp=Yes

Начинается URL с указания протокола (HTTP). Далее следует имя хоста — адрес сервера (в приведенном примере «www.myserv.com»). Затем следует имя серверного приложения и путь к нему (в приведенном примере «/pl/servl.exe»). После этого, начинаясь с последнего символа слэша и вплоть до вопросительного знака записывается необязательная часть URL, именуемая Pathlnfo. В приведенном примере это «/actionl». Эта информация определяет способ обработки информации серверным приложением. Например, может указываться процедура, которая должна обрабатывать данное сообщение. После символа вопросительного знака следует часть URL, называемая Query — запрос. Обычно она состоит из списка, включающего идентификаторы, символы равенства и значения этих идентификаторов. Отдельные элементы списка отделяются друг от друга символами . В приведенном примере введено имя valueсо значением «5» и имя Respсо значением «Yes». Это информация, которая передается процедуре серверного приложения для обработки.

Теперь мы можем вернуться к рассмотрению свойств действия и к главному свойству — Pathlnfo.Это свойство совпадает с элементом Pathlnfo запроса URL. При получении запроса производится поиск действия, в котором Pathlnfoсовпадает с запроса Pathlnfo. Если такое действие найдено и оно имеет обработчик события OnAction,то выполняются операторы, записанные в этом обработчике. Заголовок обработчика имеет вид:

void __fastcall TWebModulel::WebModulelWebActionItemlAction(

TObject *Sender, TWebRequest *Request, TWebResponse *Response, bool SHandled)

Параметр Requestопределяет объект запроса типа TWebRequest.Основное свойство этого объекта Query— строка типа string, представляющая часть Query запроса URL. В приведенном выше примере URL она имеет вид: «value=5Resp=Yes». Другое свойство объекта запроса — QueryFieldsтипа TStrings.Это свойство представляет Query запроса URL в виде списка строк. В приведенном примере он будет содержать две строки: «value=5» и «Resp=Yes». Таким образом, через объект QueryFieldsобработчик события получает доступ к содержащейся в запросе информации. Обращаться к значениям параметров запроса удобно с помощью метода Уа1иев[имя].Например, в приведенном примере выражение Request—Query-Fields—Values[Resp]вернет строку «Yes».

Параметр Responseопределяет объект ответа типа TWebResponse.Основное свойство этого объекта Content— ответ пользователю типа stringв виде текста HTML, имени файла HTML и некоторых других видов.

Параметр Handledопределяет, завершен ли ответ, или объект Responseдолжен дополнительно формироваться другими действиями. Если требуется, чтобы формирование Responseзавершили другие действия, следует в обработчике задать значение Handledравным false.Тогда, если ответом займется другое действие, ему будет передан объект Response,в котором свойство Contentсодержит текст, занесенный предыдущими действиями.

Мы рассмотрели свойство Pathlnfoобъекта действия и обработчик события OnAction.У объекта действия имеется также свойство Default.Если оно в одном из действий установлено в true,то это действие является действием по умолчанию. Если в модуле не нашлось действия, в котором Pathlnfoсовпадает с запросом, то наступает событие OnActionдействия по умолчанию. Свойство Enabledобъекта действия определяет его доступность.

У самого сервера типа TWebModule,содержащего собрание действий, имеются два события, которые нередко используются для управления сервером. Это события BeforeDispatch и AfterDispatch,наступающие в начале и в конце обработки запроса. Их заголовки подобны приведенному выше для события OnAction.Прежде всего, при получении запроса наступает событие BeforeDispatch.В его обработчике можно проанализировать запрос и дать на него ответ или произвести настройку сервера, например, сделать с помощью свойств Enabledдоступными или недоступными отдельные действия. Затем наступают события действий. В конце наступает событие AfterDispatch.В его обработчике можно проанализировать ответ, сформированный действиями, и что-то в нем изменить.

Пример серверного приложения

Попробуем посмотреть, как применить на практике все, изложенное в разд. 1. Построим простое серверное приложение, в котором был бы обмен информацией между клиентом и программой. Пусть наше приложение задаст клиенту вопрос, сколько будет дважды два, и предоставит ему выбор из двух ответов: 4 или 5. Получив ответ клиента, приложение должно сообщить ему результаты этого сложного тестирования.

Закройте все открытые проекты, если они у вас имеются, и создайте модуль сервера (команда File | New | Other, пиктограмма Web Server Application). Откройте редактор действий и занесите в него два действия. Первое действие будет формировать ответ на выбор пользователя.

Его свойство Pathlnfoзадайте равным «/1». Второе действие будет действием по умолчанию. Его назначение — задать пользователю вопрос. Установите свойство Defaultэтого действия в true.

Осталось написать обработчики событий OnActionэтих действий. Для действия по умолчанию обработчик может иметь вид:

void __fastcall TWebModulel::WebModulelWebActionItem2Action (

TObject *Sender, TWebRequest *Request, TWebResponse *Response, bool SHandled){

Response-Content =Знаете ли вы дважды два?Сколько будет 2×2 ?

4 или5 ?, ; Handled = true; }

Этот код возвращает документ HTML. Пользователю предоставляются на выбор две ссылки с текстами «4» и «5». В обеих ссылках Pathlnfo равняется «/1». Таким образом, обе ссылки направляют запрос первому действию, у которого задано это значение Pathlnfo.Но запрос Query в этих двух ссылках разный: «4» и «5». Так что по значению запроса в первом действии можно распознать, какую из ссылок выбрал пользователь. Обработчик события OnActionпервого действия может иметь вид:

void __fastcall TWebModulel::WebModulelWebActionItemlAction(

TObject *Sender, TWebRequest *Request, TWebResponse *Response, bool SHandled) { if(Request-Query == 4)

Response-Content = Ответ 4. Вы прекрасный математик!; else Response-Content =

Ответ 5. Вы немного забыли таблицу умножения.; Handled = true; }

Этот обработчик формирует разные ответы в зависимости от значения свойства Request.Query.

Сохраните свой проект под именем TwiceTwo.Скомпилируйте его и созданный модуль TwiccTwo.exeпоместите в выполняемый каталог вашего сервера. С помощью любого браузера выполните ваше приложение.

Приведенный пример демонстрирует модуль сервера с несколькими действиями. Но тот же самый пример можно реализовать проще. Вместо формирования исходного документа в действии по умолчанию, что не очень удобно, можно было бы сформировать с помощью любого редактора HTML документ, задающий пользователю сакраментальный вопрос о дважды два. В простейшем случае документ, воспроизводящий приведенный ранее вид вопроса, мог бы иметь вид:

3naeTe ли вы дважды nBa

Знаете ли вы дважды два?

Сколько будет 2×2 ?

4

или

5 ?

Основное отличие от ответа, формировавшегося ранее сервером, заключается в том, что ранее ссылки на выполняемый файл содержали только имя файла «TwiceTwo.exe», а в приведенном тексте ссылки полные: «http://mycomputer/cgi-bin/ TwoTwo.exe». Это необходимо, если файл HTML с данным текстом и выполняемый файл TwoTwo.exe, который вы сейчас создадите, расположены в разных местах. В предыдущем примере такого быть не могло, так как работа велась с одним файлом — TwiceTwo.exe.

Сохраните созданный документ в файле TwoTwo.html. Теперь спроектируйте сервер TwoTwo, который будет воспринимать ответ пользователя. Делается это так же, как в рассмотренном ранее примере. Только в данном случае нужно предусмотреть всего одно действие с Pathlnfo = \1 обработчик которого ничем не отличается от рассмотренного ранее. Так что вы просто можете взять тот же модуль и удалить из него второе действие. Сохраните модуль этого нового сервера под именем «TwoTwo» и nepeHecnfe его выполняемый файл в выполняемый каталог сервера. Откройте любым браузером подготовленный ранее документ TwoTwo.html и убедитесь, что все работает так же, как в предыдущем примере.

Обработка данных из форм

Разберем пример простейшей формы. Как делать формы можно узнать в большинстве учебников по HTML. Особое внимание обратим на передачу параметров.

После заполнения формы и нажатия кнопки «Запрос» серверному приложению будет передан список всех параметров формы в не слишком хитро зашифрованном виде:

http://server/my/project2.exe?textfield=%D2%E5%F1%F2Submit=%C7%E0%EF%F0%EE%F1

Нетрудно догадаться, что список параметров идет после знака вопроса в виде «Имя параметра»=«Значение параметра». Параметры отделены друг от друга амперсандом. Если используется местная кодировка, то после процента следует код символа.

Подобную строчку можно увидеть на экране своего браузера, заменив метод передачи параметров с post на get. Мы же будем использовать метод post. Именно этот метод позволяет использовать все возможности библиотеки VCL.

Теперь приведем текст не менее простой программы-сценария.

void __fastcall TWebModule1::WebModule1WebActionItem1Action(

TObject *Sender, TWebRequest *Request, TWebResponse *Response,

bool Handled)

{

AnsiString A=Request-ContentFields-Values[textfield];

AnsiString R=\n\n;

TDateTime D;

D=D.CurrentTime();

R+=D.TimeString() +;

Response-Content=R;

}

Интерес предоставляют формальные параметры Request и Pesponse. В первом передаются параметры формы, а в Response-Content заключается текст ответа в формате HTML.

Чтобы не писать самому программу разбора строки параметров запроса, можно воспользоваться возможностями библиотеки VCL:

Request-ContentFields-Values[textfield]

Логика программирования серверной части заключается в формировании строки-ответа Response-Content. По окончании работы программы эта строка передается клиенту:

13:50:07

Статьи к прочтению:

Построение клиент-серверного приложения на .Net. Использование WCF-сервисов


Похожие статьи: