4.3. Разработка распределенных приложений
При помощи существующих средств разработки стало возможным создавать WWW-приложения, работающие не только в контексте одной HTML-страницы или одного WWW-клиента, но использующие распределенные ресурсы - и клиента, и сервера, а может быть и большего количества компьютеров. Добиться этого можно несколькими способами: воспользоваться мощностью языка Java в сопряжении с JavaScript, использовать выполнение скриптов на сервере (ASP компании Microsoft или LiveWire компании Netscape)
4.3.1. Взаимодействие апплетов Java и языков сценариев
Механизм LiveConnect (входит в поставку Netscape начиная с версии 3.0) обеспечивает 3 способа взаимодействия JavaScript и Java:
- непосредственное обращение к методам Java,
- управление Java-апплетами,
- управление Java- plug-ins.
Непосредственный доступ к Java
JavaScript имеет доступ к полям и методам в Java-классе в том же синтаксисе, как и в Java-программе. Общий синтаксис такого обращения:
[Packages.]packageName.className.methodName
Например, можно вызвать System.out.println, чтобы напечатать сообщение на Java-консоль.
varSystem = java.lang.System
System.err.println("GreetingsfromJavaScript")
Можно даже использовать Java-конструкторы:
varmydate = newjava.util.Date()
System.out.println(myDate)
Управление Java-апплетами
Можно использовать JavaScript, чтобы управлять поведением Java-апплетов без необходимости понимания внутренней структуры апплета. Все публичные переменные и методы апплета доступны из JavaScript. Например, можно использовать HTML-кнопки, чтобы вызывать или останавливать апплеты.
Каждый апплет виден в JavaScript как document.appletName, где appletName - это значение атрибута NAME тега <APPLET>.
Управление Java- plug-ins
Каждый plug-in в документе доступен в JavaScript как элемент в массиве embeds. Например:
<EMBEDSRC=myavi.aviNAME="myEmbed" WIDTH=320 HEIGHT=200>
Если этот HTML-код определяет первый plugin в документе, он доступен следующими способами:
document.embeds[0]
document.embeds["myEmbed"]
document.myEmbed
Если plug-in написан с помощью Java-класса netscape.plugin.Plugin, доступны его статические переменные и методы.
4.3.2. Подход от Netscape: LiveWire
LiveWire - это среда разработчика для управления Web-узлом и создания приложений клиент-сервер. В ней используется язык JavaScript для изготовления серверных приложений, аналогичных CGI-программам. Однако приложения LiveWire, в отличие от CGI, тесно связаны cHTML-страницей, под управлением которой они работают. Обычный HTML статичен. Фиксированное содержание передается с сервера броузеру. При помощи LiveWire можно создавать динамические HTML-страницы, изменяющиеся в зависимости от изменившихся данных или действий пользователя.
Процесс создания LiveWire-приложения достаточно прост:
- программа содержится в одном или более файлах. Используется JavaScript встроенный в HTML или чистый JavaScript;
- файлы программы компилируются LiveWire компилятором и создается байт-код (файл с расширением .web);
- приложение инсталлируется при помощи LiveWireApplicationManager на сервере;
- при вызове из броузера LiveWire выполняет программу и создает динамическую HTML-страницу;
- при помощи библиотеки объектов LiveWire можно создавать серверные приложения с богатым набором возможностей: от поддержки контроля пользователей и управления сессиями, до создания сложных обращений к базам данных.
4.3.3. Подход от Microsoft: COM и ASP
Компонентная объектная модель COM
Компонентная объектная модель (COM) - это спецификация, описывающая, как создаются объекты, как они взаимодействуют, чтобы выполнить ту или иную функцию в системе. В соответствии с COM каждый объект имеет в своем составе интерфейсы. Интерфейс - это набор методов, т.е. функций, объединенных между собой для достижения какой-либо цели. К примеру, интерфейс IClassFactory служит для создания новых объектов COM и управления ими. Для этого в составе интерфейса IClassFactory имеются два метода: CreateInstance, создающий новый объект заданного класса, и LockServer, предотвращающий выгрузку программы-генератора объектов (сервера) из памяти. Обычно любой COM-объект содержит более одного интерфейса. Если взять, скажем, все тот же сервер для создания объектов, то в нем, кроме интерфейса IClassFactory, содержатся еще несколько интерфейсов, из которых самый важный - IUnknown. Как гласит спецификация компонентной объектной модели, любой объект должен содержать в себе интерфейс IUnknown. Его назначение - поиск других интерфейсов, включенных в объект (метод QueryInterface), и отслеживание счетчика блокировок (методы AddRef и Release). При создании нового объекта ему передается интерфейс IUnknown. Попутно вызывается метод AddRef, увеличивающий счетчик блокировок на единицу. Теперь, чтобы получить какой-нибудь другой интерфейс объекта, можно вызвать QueryInterface, который либо вернет вам требуемый интерфейс, либо код ошибки, говорящей о том, что такого интерфейса в составе объекта нет. Именно поэтому интерфейс IUnknown должен быть в каждом объекте: без него вы просто не сможете получить других требуемых для работы интерфейсов.
Внимательные читатели, владеющие каким-либо объектно-ориентированным языком программирования, обратят внимание на тот факт, что интерфейсы очень похожи на классы. И это правда, за исключением того, что в Си++ интерфейс описывается как структура с соответствующими методами. А вообще-то объекты COM можно создавать на различных языках программирования, главное, чтобы они соответствовали требованиям, описанным в спецификации COM. Хороший пример - пакет BorlandDelphi. Несмотря на то, что в его основе лежит язык ObjectPascal, с его помощью легко создавать COM-объекты.
Активные серверные страницы ASP
Новая технология фирмы Microsoft - активные серверные страницы ActiveServerPages (ASP) - позволяет использовать языки сценариев VBScript и JavaScript для создания динамичного, интерактивного содержимого WorldWideWeb. Применение технологии ASP дает возможность выполнять сценарии на сервере и отображать результат с помощью любого Web-броузера независимо от того, поддерживает он языки сценариев или нет.
До недавнего времени создание динамичного, интерактивного содержимого в Internet/Intranet требовало использования CGI или ISAPI/NSAPI-интерфейсов. В этом случае клиенты посылали HTTP-запросы, которые адресовались не статическим HTML-страницам, а серверным программам, написанным с помощью специальных средств, которые бы обрабатывали параметры и отсылали клиенту результат в виде потока HTML-тегов. Недостатком такого подхода является то, что создание программ такого рода - дело довольно затруднительное, никак не связанное с непосредственным написанием HTML-страниц.
Что предлагает технология ASP? С ее помощью можно создавать сценарии, выполняемые в контексте сервера. Такие программы интегрируются непосредственно в HTML-страницы и не требуют каких-либо дополнительных средств разработки. Самое важное, что создание HTML-страниц и создание серверных программ - это единый процесс.
Следует отметить, что указанная технология базируется на двух проверенных временем решениях: ActiveXScripting - для поддержки языков сценариев на уровне внутрипроцессорных CJM-серверов и OLEAutomation - для выполнения серверных компонентов ActiveX. Существует, однако, некоторое ограничение на тип этих компонентов. Так как они выполняются в контексте сервера, то не должны иметь пользовательский интерфейс.
Активные серверные страницы хранятся на сервере в файлах с расширением ASP. Каждый файл представляет собой ASCII-файл, в котором объединяются текст, отображаемый в клиентском броузере, теги языка HTML, служащие для форматирования текста, и программа на языке сценария. Последняя выделяется с помощью пары специальных тегов:
<%
Здесь располагается сценарий
%>
Обзор объектов и компонентов ASP
Механизм активных серверных страниц включает в себя пять встроенных объектов и ряд серверных компонентов, обеспечивающих серверные страницы всей функциональностью, c возможностью использования в сценариях, выполняемых на сервере. Рассмотрим сначала встроенные объекты. Эти объекты перечислены в таблице.
Объект Application используется для обмена информацией между пользователями данного приложения. Этот объект имеет два метода: Lock и Unlock - и может реагировать на два события - OnStart и OnEnd. Метод Lock блокирует изменения свойства объекта Application, метод Unlock отменяет данный запрет. Объект Application может хранить переменные. Использование объектов OnStart и OnEndтребует размещения соответствующего программного кода в глобальном файле GLOBAL.ASA.
Объект | Назначение |
Application / Приложение | Используется для обмена информацией между пользователями данного приложения. |
Request / Запрос | Используется для получения значений параметров запроса, посланного клиентом. |
Response / Ответ | Используется для посылки информации клиенту. |
Server / Сервер | Обеспечивает доступ к методам и свойствам сервера. |
Session / Сеанс | Используется для хранения информации в течение сеанса. |
Объект Request содержит только один тип атрибутов - коллекция:
Атрибут | Описание |
ClientCertificate | Возвращает значения, хранящиеся в клиентском сертификате, посланном на сервер. |
Cookies | Возвращает cookie-значения , посланные в HTTP-запросе. |
Form | Возвращает значения элементов формы, посланные на сервер. |
QueryString | Возвращает значения строки запроса, посланной в URL на сервер. |
ServerVariables | Возвращает значения серверных переменных. |
Объект Response используется для посылки информации клиенту. Рассмотрим набор атрибутов объекта Response:
Тип атрибута | Атрибут | Описание |
Коллекция | Cookies | Позволяет установить cookie-значения. |
Свойство | Buffer | Показывает, забуферизирована ли выходная HTML-страница. |
Свойство | ContentType | Определяет тип HTTP-содержания для ответа клиенту. |
Свойство | Expires | Определяет временную задержку перед кэшированием страницы после окончания сеанса связи. |
Свойство | ExpiresAbsolute | Определяет дату/время кэширования страницы после окончания сеанса связи. |
Свойство | Status | Значение строки состояния, возвращаемой сервером. |
Метод | AddHeader | Устанавливает HTML-заголовок. |
Метод | AppendToLog | Добавляет строку в конец журнала изменений сервера |
Метод | BinaryWrite | Записывает в выходной поток HTTP без перевода в символы. |
Метод | Clear | Стирает любой выходной буфер HTML. |
Метод | End | Останавливает процесс выполнения ASP и возвращает текущие данные. |
Метод | Flush | Немедленно посылает клиенту данные из выходного буфера. |
Метод | Redirect | Служит для переадресации на другую станцию, заданную в формате URL. |
Метод | Write | Записывает строку данных в выходной поток HTTP. |
Объект Server обеспечивает доступ к методам и свойствам сервера. Он обладает четырьмя методами: CreateObject, HTMLEncode, MapPath и URLEncode. Метод CreateObject служит для создания экземпляров серверных компонентов. Метод HTMLEncode используется для вывода на экран тегов языка HTML. Метод MapPath предназначен для преобразования относительных или виртуальных маршрутов в каталоги на сервере. Метод URLEncodeслужит для преобразования адресов в формате URL.
Объект Session используется для хранения переменных в течение одного сеанса работы с сервером. Данный объект включает следующие атрибуты:
Тип атрибута | Атрибут | Описание |
Свойство | SessionID | Возвращает идентификатор сеанса для пользователя. |
Свойство | Timeout | Определяет период простоя состояния сеанса для приложения (в минутах) |
Метод | Abandon | Уничтожает объект Session и освобождает его источник. |
Событие | Session_onStart | Это событие активизируется в начале сеанса. |
Событие | Session_onEnd | Это событие активизируется в конце сеанса. |
Как было сказано выше, помимо встроенных объектов можно использовать серверные компоненты. Рассмотрим их основные характеристики:
Название компоненты |
Описание |
AdRotator | Используется для замены изображений или видеороликов по заданному сценарию при каждом обращении на сервер. |
BrowserCapabilities | Используется для получения различной информации о клиентском броузере. |
DatabaseAccess | Обеспечивает доступ к базе данных и использует компонент ActiveXDataObjects (ADO). |
ContentLinking | Применяется для управления списком URL-адресов, которые являются ссылками на страницы, расположенные на Web-узле. |
FileAccess | Обеспечивает доступ к хранимым на сервере файлам. |
В рамках активных серверных страниц поддерживаются специальные включаемые файлы - Server-SideIncludes (SSI). Для этого используется специальная директива #INCLUDE, размещаемая в ASP-файле. Обычно она выглядит так:
<!- #INCLUDEVIRTUAL="/scripts/samples/foo.asp" ->
и указывает на то, что к данному ASP-файлу подключается файл foo.asp, который находится в виртуальном каталоге сервера (опция VIRTUAL) /scripts/samples/. Как правило, во включаемых файлах размещается код, общий для всех страниц. Это может быть сборник подпрограмм, выполняемых на большинстве серверных страниц.
Встроенные объекты
Как было сказано выше существует пять встроенных объектов, используемых в программах сценариев: Application, Request, Response, Server иSession.
Объект Application служит для обмена информацией между пользователями данного приложения. Например, можно реализовать простой счетчик обращений к серверу:
<%
Application.Lock
Application ("HitCount") = Application("HitCount") + 1
Application.Unlock
%>
Методы Lock и Unlock используются для блокирования изменений свойств объекта и для отмены этого запрета соответственно. Также объект Application может реагировать на два события - OnStart и OnEnd. Эти методы используются путем написания соответствующего кода в глобальном файле GLOBAL.ASA. Об этом будет рассказано в разделе "Глобальный файл".
Рассмотрим использование объекта Request на примере традиционной задачи - формы, заполняемой пользователем. Для начала необходимо создать форму. В качестве значения атрибута ACTION тега <FORM> нужно указать имя ASP-файла, например, formdemo.asp, и установить метод передачи данных POST. Пусть форма состоит из четырех текстовых полей ввода с именами UserName, UserAddress, UserEMail и UserComm. Пользователь заполняет форму и нажатием кнопки Submit отсылает ее на сервер. Что происходит на сервере? Получая команду SUBMIT, объект Request готов к обработке полей формы, то есть к отображению содержимого полей формы, сохранению их в файле или базе данных. Для отображения полей записи файл formdemo.asp может выглядеть следующим образом:
<HTML>
<BODYBGCOLOR=greenTEXT=white>
<%IfRequest.Form("UserName")= "" Then %>
<H4>
Форма заполнена некорректно.
Для исправления нажмите кнопку Back.
</H4>
<%Else%>
Получена следующая информация:<BR>
<PFONTSIZE=3>
Имя: <% =Request.Form("UserName") %><BR>
Адрес: <% =Request.Form("UserAddress") %><BR>
E-Mail: <% =Request.Form("UserEMail") %><BR>
Комментарии:<% =Request.Form("UserComm") %><BR>
</P>
<%EndIf%>
</BODY>
</HTML>
Существует ряд других методов объекта Request, на которые можно обратить внимание. Например с помощью коллекции ServerVariables можно получать доступ к серверным переменным:
'адрес, с которого пришел запрос
<%Response.WriteRequest.ServerVariables("REMOTE_ADDR")%>
'поддерживаемые клиентом языки
<%Response.WriteRequest.ServerVariables("HTTP_ACCEPT_LANGUAGE")%>
И еще один полезный пример. В нем показано, как можно получить все посланные пользователем значения полей формы:
<% ForEachxInRequest.Form %>
Request.Form(<% =x %> = <% =Request.Form(x) %> <BR>
<% Nextx %>
Объект Responseиспользуется для посылки информации пользователю. Метод Redirect этого объекта служит для переключения на другую страницу, как локальную, так и удаленную, адрес которой задается в формате URL:
<% Response.Redirect ("URL") %>
Метод Write является одним из базовых методов объекта Response. С его помощью информация посылается непосредственно клиенту. Например, если мы хотим вывести текущие дату и время, можно использовать следующий код:
<% Response.Write "Локальное время: <B>" & Now & "</B> %>
Объект Serverимеет четыре метода: CreateObject, HTMLEncode, MapPath и URLEncode. Метод CreateObject служит для создания экземпляров серверных компонентов. Примеры использования рассматриваются ниже. Метод HTMLEncode используется для вывода на экран тегов языка HTML. Например, вызов этого метода:
<%
Response.WriteServer.HTMLEncode("Для выделения текста используются теги <B> и </B>")
%>
приведет к появлению следующего текста в окне броузера:
Для выделения текста используются теги <B> и </B>
При этом, если посмотреть на исходный текст, то можно увидеть, что вместо тегов используются специальные символы:
Для выделения текста используются теги <B> и </Bgt;
Метод MapPath предназначен для преобразования относительных и виртуальных маршрутов в каталоги на сервере. Вот пример использования этого метода:
LogFile=Server.MapPath ("/Login") & "\input\logfile.txt"
SetOutStreamFileObject.CreаteTextFile (Logfile, True, False)
Метод URLEncode предназначен для преобразования адресов в формате URL. Например, вызов этого метода:
<%
Response.WriteServer.URLEncode("www.cpress.ru")
%>
приведет к появлению в окне броузера следующей строчки:
www%2Ecpress%2Eru
С помощью свойства ScriptTimeout объекта Server можно задать время выполнения сценария.
Объект Session используется для хранения переменных в течение одной сессии работы с сервером. Методы для обработки событий OnStart и OnEnd помещаются в глобальный файл GLOBAL.ASA. Соответствующие примеры использования указаны в разделе "Глобальный файл".
Глобальный файл
Глобальный файл GLOBAL.ASA располагается в корневом каталоге сервера (виртуальном корневом каталоге). Отметим, что корневой каталог сервера доступен из всех подкаталогов, и, таким образом, файл GLOBAL.ASA доступен из всех ASP-страниц. При необходимости он располагается и в корневом каталоге приложения, выполняемого на сервере, но этот каталог также должен быть объявлен как виртуальный корневой каталог. Как мы уже говорили, в файле GLOBAL.ASA могут быть использованы два встроенных объекта:Application и Session. С помощью объекта Application можно создавать глобальные переменные для всех ASP-страниц, а с помощью объекта Session можно создавать переменные, "видимые" в рамках одной сессии. В файле GLOBAL.ASA также можно открывать сеансы связи с базами данных.
Например, для использования методов OnStartиOnEnd объекта Application можно написать следующий код:
<SCRIPTLANGUAGE=VBScriptRUNAT=Server>
SubApplication_OnStart
'эта подпрограмма выполняется, когда на узел приходит первый пользователь
ENDSUB
...
SubApplication_OnEnd
'эта подпрограмма выполняется при выключении сервера или изменении содержимого файла global.asa
ENDSUB
</SCRIPT>
Обратите внимание на расширенный синтаксис тега <SCRIPT>. Атрибут RUNAT указывает на то, что данный скрипт выполняется на сервере.
Пример использования тех же методов, но объекта Session выглядит очень похоже:
<SCRIPTLANGUAGE=VBScriptRUNAT=Server>
SubSession_OnStart
'эта подпрограмма выполняется в начале сессии
ENDSUB
...
SubSession_OnEnd
'эта подпрограмма выполняется в конце сессии
ENDSUB
</SCRIPT>
Серверные компоненты
AdRotator, BrowserCapabilities, DatabaseAccess, ContentLinking и FileAccess.
Компонент AdRotator используется для отображения и смены рекламы (изображения и видеороликов) на сервере. Каждый раз, когда пользователь попадает на страницу, на которой используется этот компонент, он видит новую информацию - обновление происходит по сценарию, заданному в специальном файле. Причем каждая реклама имеет свою ссылку на страницу, соответствующую ей. Имеется возможность отслеживать, сколько пользователей обратились к той или иной рекламе. Пример использования компонента AdRotator:
<CENTER>
Добро пожаловать на наш сервер!
<BR>
<% SetAd = ServerCreateObject("MSWC.Adrotator") %>
<% =Ad.GetAdvertisement("advert.txt") %>
</CENTER>
Файл-сценарий (в примере advert.txt) является обычным текстовым файлом, в котором описываются правила обновления графической информации. Содержимое файла-сценария advert.txt, например, может выглядит следующим образом:
width 460
height 60
border 1
*
advert1.gif
http://www.cpress.ru/subscriptions/
Subscribeto "ComputerPress"!
20
advert2.gif
http://www.cpress.ru/books/
Readourbooks
20
advert3.gif
http://www.microsoft.com
UselegalMicrosoftsoftware!
30
В начале файла-сценария указываются размеры области, в которой будет появляться графическая информация. Затем, по порядку дается описание каждого графического элемента, состоящее из четырех пунктов: имя графического файла, URL-адрес страницы, которая будет загружаться при щелчке на изображении, текстовое описание ссылки и вероятность появления данного изображения.
С помощью компонента BrowserCapabilities можно получать различную информацию о клиентском броузере. Приведем несколько примеров использования этого компонента. Например, мы можем узнать тип и версию клиентского броузера:
<% Setbc = Server.CreateObject("MSWC.BrowserType") %>
Приветствуем на сервере пользователя броузера <B><% =bc.Browser %>
версии <% =bc.Version %> </B>!
Затем можно определить, поддерживает ли клиентский броузер фреймы. На сервере может быть два набора страниц - с фреймами и без них. Определив, умеет ли клиентский броузер отображать фреймы или нет, можно загружать соответствующий набор страниц:
<% Setbc = Server.CreadteObject("MSWC.BrowserType" %>
<%
If (bc.Frames = TRUE) Then
Response.Write "Есть поддержка фреймов!"
Else
Response.Write "Нет поддержки фреймов!"
EndIf
%>
Также перед отправкой страницы, содержащей программу на каком-либо скриптовом языке, полезно было бы определить, поддерживает ли броузер этот скриптовый язык. Например, для проверки поддержки языка VBScript можно написать такой код:
<% Setbc = Server.CreateObject("MSWC.BrowserType") %>
<%
If (bc.VBScript = TRUE) Then
Response.Write "Есть поддержка VBScript"
Else
Response.Write "Нет поддержки VBScript"
EndIf
%>
Компонент DatabaseAccess обеспечивает доступ к данным, хранящимся в базах данных. Рассмотрение этого компонента вынесено в отдельный раздел.
Компонент ContentLinking применяется для управления списком URL-адресов, которые являются ссылками на страницы, расположенные на Web-узле. С помощью этого компонента можно создавать таблицы содержания для всего Web-узла, что весьма актуально для онлайновых публикаций и списков статей различных электронных конференций. Кроме того, компонент ContentLinking может использоваться для изменения порядка следования страниц.
Компонент FileAccess использует объекты FileSystemObject и TextStream и обеспечивает доступ к хранимым на сервере файлам. Вот пример использования этого компонента:
<%
'создадим файл
SetFileObject = CreateObject("Scripting.FileSystemObject")
SetFile = FileObject.CreateTextFile("user.txt", True)
'запишем данные в файл
File.Writeline(Now())
File.Writeln(Request.ServerVariables("REMOTE_ADDR"))
File.Writeln(Request.ServerVariables("REMOTE_HOST"))
'закроем файл
File.Close
%>
Назад |
Содержание |
Вперед