Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Плещёв ВУМИП 2012-07-06.doc
Скачиваний:
66
Добавлен:
13.05.2015
Размер:
9.35 Mб
Скачать

4.10.5. Связь с сервером приложений по протоколуHttp

ТехнологииDCOMиTCP/IPтребуют установки прямой связи между клиен­том и сервером, что в перегруженных сетях может вызвать большие за­держки в установке такой связи. В таких случаях лучше использовать компонентWebConnectionс панелиMidas, который организует связь с сер­ве­ром по протоколу передачи гипертекстаHTTPв Интернете со средс­т­ва­ми защиты данных. При отсутствии реальногоWeb‑сервера мо­ж­но создать для отладки собственныйWeb‑сервер на локальном ком­пь­ютере. Для этого нужно присвоить уникальное сетевое имя компьютеру:

  1. Выполним команду Пуск/Настройка/Панель управле­ния/Сеть.

  2. На странице Кон­­­фи­гура­циявыберем протоколTCP/IP и нажмем кнопкуСвойства.

  3. На странице Конфигурация DNSустановим флажокВключить DNS. В полеИмя компьютераустановим, например,MyHost, а в полеДомен‑MyDomain.ru. Перегрузим компьютер.

Изменим в клиентском приложении (п. 4.10.2) ус­та­­нов­ку связи с сервером по протоколу DCOMна прото­колHTTP.

  1. Разместим компонент WebConnection. В свойствеServerGUIDэтого компонента указывается иденти­фи­ка­цион­ный номерGUIDсервера прило­жений (п. 4.10.1). Ско­пи­руем его одноименное свойство ком­понентаDCOMConnection1через бу­фер, предварительно указав для него свойствоConnected=False. После это­го свойствуServerNameприсвоится имя сервераProject1.IStroiki.

  2. Запустим Web‑сервер, если он еще не запущен. Скопируем библиотекуDelphi5\Bin\httpsrvr.dll в виртуальный каталогWeb‑сервера, допускающий вызов серверных приложений, например:Cgi-Bin. В свойствеURLкомпонентаWebConnection1 укажем полный адрес этой библиотеки, например,http://myhost/cgi-bin/httpsrvr.dllиConnected=True. Произойдет за­пуск сервера приложений.

  3. Для компонента ClientDataSet1установим свойстваRemote­Ser­ver=Web­Connection1 иActive=Trueи выполним клиентское приложение.

4.10.6. Основы разработки приложений Internet

Предполагается, что пользователь имеет базовые понятия об языке раз­метки гипертекстa HTML [8] (этот пункт подготовлен А. Кочетовым).

Протокол HTTP, язык HTML и универсальный локатор ресурса URL составляют основу WWW[4]. HTTP (HyperText Transfer Protocol) - протокол передачи гипертекста, основанный на идее «ссылки», реали­зо­ванной в универсальном идентификаторе ресурса (URL) и уни­вер­сальном имени ресурса (URN). Второй основной частью протокола HTTP является идея запроса-ответа.

Динамически формируемые Web‑документы создаются сервером в процессе обработки клиентского запроса. Серверные программы, выполняющие эту функцию, подразделяются на два типа: Web-сервер может вызывать исполняемую программу или поручить это дело вызываемой процедуре из библиотеки динамической загрузки (DLL). Delphi поддерживает все четыре интерфейса приложений, выполняемых на сервере и позволяющих создавать динамические документы HTML: ISAPI и NSAPI (использует .DLL), CGI и Win-CGI (использует .EXE). Исходный текст для всех интерфейсов может быть один. Различия лишь при создании «проекта», т.е. имея исходный код приложения CGI, вы можете получить приложение интерфейса ISAPI, лишь создав таковое (File/New/Web Server application/ISAPI) и перенеся код. Никаких изменений не требуется.

Примерсоздания Web-приложения типа CGI вывода текущего времени (рис. 4.10.6.1):

Рис. 4.10.6.1. Окно приложения

1. Выберите пункт меню File/New/Web Server application/CGI. Мастер создаст для вас приложение иWebModule, который является потомкомTDataModuleи наследует его свойства, и если вы имели проект по работе с базами данных с использованиемTDataModule, то вы можете произвести публикацию данных в Internet, лишь добавив вDataModuleкомпонентWebDispatcher. Он же и встроен вTWebModule.

2. Дважды щелкните в Инспекторе Объектов на свойстве Actions. Добавьте новую строку в таблицу действий кнопкойAdd New.

3. Дважды щелкните на событии OnAction. Отредактируйте текст обработчика так, как он представлен ниже:

Procedure TWebModule1WebActionItem1Action(Sender:TObject;

Request:TwebRequest; Response:TwebResponse; var Handled:Boolean);

Begin

{ Sender - определяет вызвавший его объект.

Request - содержит запрос пользователя.

Response - содержит ответ сервера.

Handled - флаг, определяющий обработано или нет событие.

}

Response.Content:=’<HTML> <H1> Пример приложения CGI</H1>’+

‘<B> Текущее время: ‘+ TimeToStr(SysUtils.Time) +’</B></HTML>’;

End;

4. Сохраните проект и откомпилируйте (^F9).

5. Поместите EXE-файл приложения в «исполняемый каталог» вашего Web-сервера (Wins2000)

6. Выполните EXE-файл приложения, указав его имя в поле Адреспроводника Интернета.

Одна из популярных задач Internet ‑ это получение каких-либо данных от клиента, обработка на сервере и отправка клиенту документа-ответа. В HTML-документах это обычно решается при помощи формы. Сервер обрабатывает события OnAction, которые, в свою очередь, получают два параметра-объектаResponse иRequest. Если форма использует методPost,то данные помещаются в свойствоContentFields. Если в запросе применяется методGet, то данные запроса будут находиться в свойствеQueryFields.

Рассмотрим общую структуру приложения Web-сервера. Когда при­ло­жение получает от Web-клиента запрос, оно создает объекты Tweb­RequestиTWebResponseдля размещения в них HTTP-запроса и ответа сервера соответственно. Затем эти объекты передаются диспетчеру Web, встроенному в Web-модуль или компонентуTWebDispatcher. Диспетчер поддерживает набор объектов-действий классовTwebActionItem, каждый из которых выполняет обработку различных видов запросов. Этот класс имеет свойствоMethodType, предоставляющее различные варианты обработки запроса:mtGet, mtHead, mtPost, mtPut, mtAny. Запрос считается обработанным, если возвращается значениеtrueчерез параметрHandled; также возможна обработка событийBeforeDispatch, AfterDispatch.

На инструментальной панели Internet имеется три компонента, предназначенные для работы с базами данных в приложениях для Web-серверов:

TqueryTableProducerиспользуется для представления в виде HTML-таблицы результата SQL-запроса к базе данных. Этот объект может получать параметры SQL-запроса из HTTP-запроса. Если запрос использует методPost,то параметры запроса по SQL помещаются в свойствоContentFields. Если в запросе применяется методGet, то данные запроса будут находиться в свойствеQueryFields.

TdataSetTableProducerзанимается аналогичным делом, но исполь­зуя объектTDataSet.

TdataSetPageProducer ‑ заменяет шаблоны в заготовке HTML-документа на значения соответствующих полей базы данных. При этом используются значения полей текущей записи базы данных.

Пример создания Web-приложения просмотра таблицы базы данных (рис. 4.10.6.2):

Рис. 4.10.6.2. Окно просмотра таблицы базы данных

1. Создадим для базы данных алиас средствами Администратора BDE непосредственно на сервере.

2. Создадим новое Web-приложение.

3. Поместим в модуль компонент TTable и подключим его к заранее созданной таблице базы данных (установим свойстваDatabaseиTable­Na­meсоответствующие значения). В свойствеDatabase укажем алиас БД или ее полный путь, а вTableName соответственно имя таблицы.

  1. Добавим на форму компонент TDataSetTableProducer.

  2. Создадим объект-действие со свойствами PathInfo=’’,Enabled=true.

  3. Редактором столбцов компонента TDataSettableProducer про­ве­дем настройку оформления таблицы, заголовков (рис. 4.10.6.3). Изменения видны непосредственно в этом же редакторе.

Рис. 4.10.6.3. Окно редактора столбцов таблицы базы данных

7. Свяжем объекты DataSetTableProducer1 и Table1. Для этого укажем имяTable1в свойствеDataSetпоставщика данных. В свойствахFooterиHeaderзадаются необходимые заголовочные и заключительные теги, чтобы получить корректный HTML-документ, понятный броузеру Web. В нашем случае можно использовать следующий фрагмент:

Для Header:

<!DOCTYPEHTMLPUBLIC«-//W3C//DTDHTML3.2//EN»>

<HTML> <HEAD><TITLE> Пример 2 </TITLE> </HEAD> <BODY>

Для Footer:

</BODY> </HTML>

8. Затем щелкнем на свойстве Columns. Отбираем нужные поля для вывода в таблицу. Кроме этого можно дать имена для выводимых колонок и настроить цвет и обрамление. Заметим, что компонентTqueryTable­Pro­ducerработает и настраивается аналогично.

9. Введем следующий код в обработчик созданного ранее события:

procedure TwebModule1WebActionItem1Action(Sender:TObject;

Request:TwebRequest; Response:TwebResponse; var Handled:Boolean);

Begin

Response.Content:=DataSetTableProducer1.Content;

{Содержимому ответа сервера присваивается содержимое компонента типа TDataSetTableProducer}

Response.SendResponse; //отправляет ответ пользователю

End;

В этом примере клиент может отправить запрос к базе данных на наш сервер и получить всю информацию базы данных в окне броузера.

Однако наше приложение посылает всегда одно и то же и никакого диалога с пользователем не ведет. Это можно исправить, используя публи­кацию данных в стиле навигатора: пользователь сможет перемещаться по таблице, используя ссылки «вперед», «назад» и т.д. Все это и многое дру­гое мы можем реализовать при помощи компонента TdataSet­PageProducer. Этот компонент работает с компонентамиTDataSet и имеет свойствоHTMLDoc форматаTstrings. Он заполняется текстом вашего документа, а также шаблонами (<#шаблон>), которые, если и имеют одинаковые имена с полями таблицы/запроса, указанные в свойствеDataSet, то они за­ме­ня­ют­ся на значение соответствующего поля текущей записи источника данных или чем-либо иным при условии, что вы это запрограммировали в обработчике событияOnHTMLTag.

Примерсоздания Web-приложения типа CGI просмотра таблицы базы данных (рис. 4.10.6.4):

Рис. 4.10.6.4. Окно просмотра таблицы базы данных

1. Помещаем в WebModuleобъектTTable.

2. Создадим объекты-действия с именем first, next, previousи с соответствующими значениямиPathInfoи свойствомEnabled=true, также объект-действиеinitial с пустым значениемPathInfo.

3. Свяжем объекты DataSetPageProducer1 и Table1. Для этого укажем свойствоDataSet=Table1.

4. Теперь сформируем вышеупомянутое свойство HTMLDoc.

<HTML>

<BODY>

<TABLE WIDTH="50%" BORDER=1 BGCOLOR="SILVER">

<TR><TH ALIGN="RIGHT">Код</TH><TH ALIGN="LEFT"><#KOD>

<TR><TH ALIGN="RIGHT">Наименование</TH>

<TH ALIGN="LEFT"><#NAIM>

<TR><TD ALIGN="CENTER">

<A href= "http://wins2000.usue.ru\pleshev\ваше приложение\first">

первая </A> </TD>

<TD><#CCC>предыдущая</A> </TD>

<TD><#BBB>следующая</A> </TD></TR>

</TABLE>

</BODY>

</HTML>

Шаблоны <#CCC> и <#BBB> используются, чтобы динами­чес­ки указать ссылку на приложение с указанием пути и информации о текущей записи отображаемой базы данных.

5. Далее для объектов initialиfirst создаем обработчик:

procedure TWebModule1.WebModule1firstAction (Sender: TObject;

Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);

Begin Table1.First; //переходит на первую запись таблицы,

//соответствующей компоненту Table1

Response.Content:=DataSetPageProducer1.Content;

Response.SendResponse; //отправляется ответ сервера

end;

procedure TWebModule1.WebModule1initialAction(Sender: TObject;

Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);

Begin

Table1.First;

Response.Content:=DataSetPageProducer1.Content;

Response.SendResponse;

end;

6. С объектом first, конечно, все понятно. Но как быть сnext и pre­­­vious? Необходимо дать знать серверу значение текущего поля. Тут‑то мы и используем событие OnHTMLTag и шаблоны. Обратите внимание на шаблоны, определенные в свойстве HTMLDoc <#BBB> и <#CCC>. Они‑то нам и понадобятся. Добавим обработчик события OnHTMLTag (будем считать, что поле KOD является первичным ключом):

procedure TWebModule1.DataSetPageProducer1HTMLTag(Sender: TObject;

Tag: TTag; const TagString: String; TagParams: TStrings;

var ReplaceText: String);

{ Обработчик содержит 4 параметра, определяющие текущий HTML тег.

TagString типа string содержит строковое представление тега. ReplaceText

также типа string используется при замене тега динамически}

var s:string; //строка содержащая текущее значение поля KOD

begin

s:=IntToStr(Table1.FieldValues['KOD']);

if CompareText(TagString,'BBB')=0 then

Replacetext:='<a href="http://wins2000.usue.ru\pleshev\’+

‘ваше приложение\next?KOD='+s+'">'; //ссылка на ваше приложение с

//информацией о текущей записи

else if CompareText(TagString,'BBB')=0 then

Replacetext:='<a href="http://wins2000.usue.ru\pleshev\’+

‘ваше приложение\previous?KOD='+s+'">'; //ссылка на ваше

//приложение c информацией о текущей записи

end;

7. Теперь приложение формирует законченный HTML документ, и осталось лишь добавить обработчики для next, previous:

procedure TWebModule1.WebModule1nextAction(Sender: TObject;

Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);

var q1:string; opt:TLocateOptions;

begin

q1:=Request.QueryFields.Values['KOD'];

Table1.Locate('KOD',q1,opt);

Table1.Next; //переход на следующую запись

Response.Content:=DataSetPageProducer1.Content;

Response.SendResponse;

end;

procedure TWebModule1.WebModule1previousAction(Sender: TObject;

Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);

var q1:string; opt:TLocateOptions;

begin

q1:=Request.QueryFields.Values['KOD'];

Table1.Locate('KOD',q1,opt);

Table1.Prior; // переход на предыдущую запись

Response.Content:=DataSetPageProducer1.Content;

Response.SendResponse;

end;

Теперь мы имеем законченное CGI приложение публикации данных в форме навигатора.

ВDelphi имеется компонент Web-броузер (TWebBrowser). Работа с ним интуитивна и вполне доступна пользователю Delphi.

Примерсоздания собственного Web‑броузера компонентомTweb­Browser(рис. 4.10.6.4):

1. Создаем обычное приложение Delphi.

2. Помещаем на форму компоненты TEdit, TStatusBar, TWebBrowser.

3. Введем следующий код в обработчик события Edit1.OnKeyDown:

procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;

Shift: TShiftState);

Begin

if Key=13 then WebBrowser1.Navigate(Edit1.Text); //клавиша Enter

end;

Рис. 4.10.6.5. Окно Web‑броузера

4. Добавим Panel кнопкой с троеточием в свойствеPanels и затем кнопкойAdd New. ДляStatusbar1 укажемWidth=150 иText=‘Status: ‘.

5. Добавим следующий код в обработчик события Web­Brow­ser1.On­TitleChange:

procedure TForm1.WebBrowser1TitleChange(Sender: TObject;

const Text: WideString);

begin

Form1.Caption:='Пример Web Browser''р ['+Text+']';

end;

6. Добавим следующий код в обработчик события WebBrow­ser1.On­ProgressChange:

procedure TForm1.WebBrowser1ProgressChange(Sender: TObject; Progress, ProgressMax: Integer);

begin

if ProgressMax<>0 then

StatusBar1.Panels.Items[0].Text:='Status:'+

IntToStr(Progress*100 div ProgressMax)+'%'

else StatusBar1.Panels.Items[0].Text:='Status: Готово';

end;

7.Теперь осталось откомпилировать, и получим Web‑броузер.