Библиотека консорциума W3, libwwwПопулярный нынче термин "веб-программирование" обычно подразумевает под собой программирование, в лучшем случае, на perl, в худшем --- на PHP, в совсем тяжелом --- на JavaScript. Ничуть не пытаюсь обидеть людей, которые этим занимаются, просто смешно выделять "программирование на Perl" в отдельную нишу, прежде всего потому что специфика его использования отнюдь не в "веб-программировании". Кроме того, мне вообще тяжело понять, чем принципиально отличается создание CGI-программ от "просто программ", кроме использования специализированного интерфейса для получения данных. Тем не менее, "веб-программирование" действительно существует. Заключается оно не в генерации на лету HTML-страничек по шаблонам на основании информации из базы данных, потому что это относится именно к использованию БД. "Веб-программирование" это работа с сетевыми протоколами передачи данных, да и сетями вообще. Более точно, это "программирование для сетей, основанных на TCP/IP". А подобное программирование подразумевает прежде всего передачу данных, а не их обработку --- скажите мне, что и куда передает CGI-программа по сети? Данные передает веб-сервер, а CGI используется как метод расширения возможностей сервера. Настоящее веб-программирование это программирование веб-серверов и веб-клиентов. Т.е., написать Apache, Internet Explorer или lynx --- это веб-программирование. Некоторые могут сказать, что я тут слишком строго подошел к программированию CGI-приложений и, если копать дальше, то веб-программирование в том смысле, в котором я его определил только что, является всего-навсего обработкой устройств ввода-вывода (к коим относится в одинаковой степени и сетевая карта, и клавиатура). Ну... да, это будет законный упрек. Только я не собираюсь так далеко заходить, мне просто хочется точнее определить термин "веб-программирование". Все дело в том, что генерация страниц "на лету" подразумевает то, что они будут отдаваться по сети, но это совершенно не обязательно. Неужели что-то принципиальным образом изменится в CGI-приложении, если его результаты будут сохраняться на жесткий диск? А внутри того, что подсовывется на вход PHP-интерпретатору? Ничего не изменится. Вообще. Для них главным является корректная установка нужных переменных среды окружения, а тот факт, подключен компьютер к сети, или нет, их не волнует. Проблему передачи или получения данных через TCP, конечно же, тоже можно аналогичным образом развернуть и сказать, что с появлением интерфейса сокетов (BSD sockets) передача данных на расстояние ничем принципиально не отличается от работы с файлами на локальном диске. В принципе это так. Потому что, если откинуть использование функций, связанных с инициализацией сокетов, в остальном с ними можно общаться как с традиционными файловыми дескрипторами. Все это хорошо, но до некоторой поры. Все дело в том, что два компьютера могут находится рядом и быть соединены всего-лишь одним кабелем, а могут отстоять друг от друга на тысячи километров. И хотя скорость передачи данных в пределах одного кабеля очень большая, то при использовании различных устройств для соединения кабелей друг с другом, происходит замедление передачи данных и чем "умнее" будет устройство, тем медленее через него будут передаваться данные. Это первое отличие. При работе с файловой системой программист никогда не думает о том, с какой скоростью у него считается файл или запишется (точнее, думает, но реже ;) ), буферизацая обычно уже реализована на уровне операционной системы или библиотеки языка программирования, а при работе с сетью задержки могут быть очень велики и в это время программа будет ожидать прихода новых данных, вместо того, что бы сделать что-либо полезное. Таким образом приходит необходимость разбивать программу на совокупность потоков и программирование превращается в ад, потому что ничего хорошего это не принесет, только лишние проблемы. Связано это с тем, что разделение программы на несколько одновременно выполняющихся потоков требует очень большой внимательности и поэтому чревато серьезными обшибками. А перевод существующей однопоточной программы в многопоточную, вообще занятие неблагодарное. Второе отличие, в принципе, вытекает из первого, но стоит несколько отдельно, потому что это требование более жесткое. Все дело в том, что передача данных обычно не ограничивается одним файлом или одним соединением. Обычно сервер обслуживает одновременно несколько клиентов или клиент одновременно пытается получить доступ одновременно к нескольким ресурсам (они так выкачиваются быстрее, чем по-одиночке). Тем самым приходиться открывать одновременно несколько сокетов и пытаться одновременно обработать их все.
Для подобной работы, в принципе, не требуется реальная многопоточность,
существует такой вызов (или подобный ему в других операционных системах),
называемый Третье отличие, по сути, относится к серверным приложениям и выражается в повышенных требованиях к производительности. Все дело в том, что когда один и тот же интернет-ресурс запрашивается большим количеством пользователей одновременно, то становится очень важна скорость реакции на него. В принципе, тут, если использовать CGI-приложения, на них тоже будет распространяться это требование, но в таких ситуациях обычно вставляют нужные обработчики непосредственно в сервер для повышения производительности. В качестве примера могу привести такой, относительно мало известный web-сервер как thttpd, который сам по себе достаточно прост и не имеет такого количества возможностей как apache, но на сегодняшний день является одним из самых быстрых веб-серверов. А теперь, собственно, возвращаясь к теме заметки. Для облегчения написания веб-приложений (именно веб-приложений!) на языках C и C++ была написана библиотека libwww. Она реализует псевдопотоковую событийную модель программы.
Под псевдопотоками понимаетя как раз использование Приложение в этом случае управляется поступающими или инициированными запросами. Кроме этого псевдопараллельного "фетчера" (от слова fetch), в libwww присутствует большое количество готовых обработчиков, которые помогают решать типовые задачи, появляющиеся вместе с "веб-программированием". Например, существует набор "переводчиков", которые позволяют, например, из потока "text/html" сделать поток "text/present" (это в терминологии libwww, "present" означает вид, который будет представлен пользователю). Для этого используется собственный html-парсер (основанный на sgml-парсере с html dtd). Таким образом, типичное веб-приложение, написанное при помощи libwww, выглядит как набор подпрограмм, обрабатывающие различные сообщения. Это позволяет написать как клиентские, так и серверные программы. В качестве примера использования libwww, можно вспомнить текстовый браузер lynx, который написан при помощи этой библиотеки. Впрочем, не буду распространяться долго об архитектуре libwww, желающие могут посмотреть документацию. Теперь мне хотелось бы пройтись по недостаткам. libwww со временем становится все сложнее и сложнее по причине увеличивающегося набора стандартных обработчиков. Зачастую, достаточно простая задача, но которая не предусмотрена изначально как типовая, может потребовать нескольких часов изучения документации в поисках того, какие обработчики и где должны для этого присутствовать. Не спорю, доскональное знание libwww, вполне вероятно, решит эти проблемы, но откуда же эти знания взять? ;) Документация на библиотеку не отличается подробностью и, как следствие, понятностью; она сводится к двум-трем строкам комментариев к программным вызовам, при этом местами документация просто устарела. Мой вам совет: если вы используете libwww, то обязательно смотрите исходный текст, по нему станет многое понятно. В качестве примера, могу привести такую веселую вещь. Для того, что бы отследить контекст разбора HTML, вводится специальный объект типа HText, который используется в обработчиках событий от парсера в качестве "внешней памяти". Это как указатель this в C++, т.е. реализация объектов на языке C. Тип HText целиком предоставляется пользователем, вместе с callback-функциями создания и удаления. Прежде чем его использовать, надо зарегистрировать эти функции (причем обязательно парой, т.е. надо обязательно указать и функцию создания объекта, и функцию разрушения), которые, если следовать документации, будут вызваны, соответственно, для создания и удаления объекта при начале и конце разбора соответственно. Это все пока что "хорошо". "Плохо" --- функция разрушения не вызывается никогда. В частности, в документации этого нет, но видно по исходному тексту, где в том месте, где должен был находится вызов удаляющей функции, находится комментарий, в котором написано что забота об удалени ложится на плечи приложения, а не библиотеки libwww. Кто при этом мешает вызвать переданную функцию, я не понял. Кстати сказать, примеры использования объекта HText в поставляемых с libwww приложениях из каталога Examples, рассчитаны на то, что функция удаления будет вызвана. И это не единственное забавное место в библиотеке. Все это решаемо, конечно, но лучше если вы будете сразу же смотреть исходный текст libwww, по нему значительно больше можно понять, чем по предоставленной документации. РезюмеИспользование libwww позволяет быстро написать типичное web-приложение, например, "робота", который выкачивает определенные документы и каким-то образом их анализирует. Тем не менее, использовать libwww в своих программах не всегда просто из-за проблем с документацией на нее.
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
© 2000-2008, Andrey L. Kalinin mailto:andrey@kalinin.ru |
|