К вопросу создания сетевых графических приложений.

Осмыслить положение дел в сфере разработки клиент-серверных систем заставили задачи, которые потребовали иного подхода, нежели имеющиеся сейчас на рынке информационных технологий.

Хорошо известна история развития сетевых приложений. От ранних терминальных станций эволюция привела к файл-серверным решениям, а затем, с появлением серверов баз данных, к классическим клиент-серверным системам, состоящим из 2х звеньев, Серверa Баз данных и "Клиента". Классическая схема и сейчас пользуется заслуженной популярностью и природа этой популярности в технологической простоте реализации архитектуры "клиент-сервер". Средства доступа к базам данных открывали разработчику возможности манипулировать данными, маскируя механизм обмена информацией между клиентом и сервером. Задачей программиста стала реализация удобного интерфейса пользователя и разработка эффективных SQL запросов. Однако на другой чаше весов лежат недостатки 2-х звенной модели. Прежде всего, это необходимость создавать клиентскую программу, которая должна полностью реализовать презентационную логику, а, иной раз, и логику самой задачи. В случае тяжеловесных систем величина такого полновесного клиента могла быть значительной. Такую схему стали называть связкой "толстого клиента" с сервером баз данных.

Разумеется, в случае изменений в логике системы или ее интерфейсной части возникает необходимость обновить клиентскую программу на всех рабочих местах пользователей. Это обстоятельство осложняет процесс сопровождения таких систем, заставляя разработчиков применять методы автоматического поддержания клиентской программы в актуальном состоянии, подкачки необходимых измененных модулей. Сторонники 2-х звенного подхода из мира Java, пользуясь преимуществами своей платформы с легкостью обновляют клиентские программы ставя себе это в зачет и набирая очки в дискуссиях. Несмотря на развитые методы обновления программного обеспечения, сама необходимость актуализации клиентского приложения остается.

Вторая проблема этой модели заключается в необходимости публиковать сервер баз данных в сети. Если в локальном решении такой подход вполне допустим и оправдан, то в случае если “задача” вырастает и начинает жить на бескрайних просторах Internet-а, публикация сервера баз в большой сети становится серьезной головной болью для администраторов системы. Встроенные средства защиты, аутентификации, шифрации каналов связи не дают 100% гарантии безопасности.

И наконец, третья сложность 2-х звенной архитектуры – возможная требовательность к пропускной способности каналов связи. В большой, развивающейся системе далеко не всегда удается контролировать эффективность и разумность SQL запросов. Зачастую запросы, а главное, принимаемые со стороны сервера кортежи данных весьма велики и способны значительно снизить скорость обмена данными между сервером и клиентом, увеличить время реакции на запросы, что сразу отразится на комфорте пользователя. Это обстоятельства были хорошо понятны и способствовали эволюции в сторону 3-х звенных архитектур.

Под фразой "3-х звенная архитектура" люди понимают разное. Многие относят к 3-к звенной архитектуре и терминальные решения. Но справедливо ли такое понимание вещей?Можно ли отнести к 3-х звенной архитектуре терминальное решение?

IT специалисты стали использовать терминальные решения для адаптации 2-х звенных систем в 3-х звенные с "тонким клиентом". Терминальный средств довольно много. Это и решения с использование Х11 протокола, Windows Terminal Service, Citrix, NoMachine. Но могут ли эти средства использоваться и быть приемлемыми в промышленной эксплуатации? Если присмотреться, то видно что сама архитектура задачи, работающая в терминальной среде, как правило, написана как 2-х звенная и посредством терминальных средств мы фактически камуфлируем узкие места 2-х звенной модели. Подобные решения весьма ресурсоемки, как в плане использования памяти, так и сетевого ресурса. В самом деле, стартуя приложение на стороне сервера Вы расходуете память крайне непродуктивно каждый раз волоча за собой груз графических объектов и презентационной логики. Нужны весьма солидные серверные машины, чтобы обеспечить нормальную работу хотя бы 30 клиентских сессий. Впрочем, это зависит от ресурсоемкости задачи. Снижение скорости связи клиента с сервером незамедлительно скажется на комфорте пользователя. Либо ухудшается качество изображения, либо возникают утомительные задержки. Защитники терминальных решений всегда говорят об относительной скромности в потреблении телекоммуникационного ресурса терминальным клиентом, забывая сказать о серверном подключении. А пропускная способность серверного подключения – ресурс ограниченный. Нетрудно посчитать сколько одновременных подключений способен обслужить терминальный сервер, соединенный с миром на скорости 2Мбит. Разумеется, терминальные решения хороши, могут и будут иметь место в качестве инструмента системного администратора или привилегированного пользователя, однако если серверу надо обслужить не 30-40 а 300-400 активно работающих соединений, вряд ли можно рассматривать терминальную схему как допустимую, разумную, а главное возможную. И напрасно адепты "терминальных школ" думают что в малом и среднем бизнесе нет задач для которых не подходил бы терминальный сервис. К примеру в Информационная системе среднего и малого склада может функционировать более 40 рабочих мест. Торговые компании предоставляют своим партнерам доступ к информационному ресурсу. Даже малые торговые площадки могут иметь значительное число клиентов (торговых агентов). Таким образом понятно, что для сколько-нибудь масштабного решения терминальные средства совершенно не подходят. Однако именно терминальный подход, в паре с традиционной 2-х звенной моделью разработки, остается наиболее популярным и востребованным. В чем же причина такой популярности? Почему же столь затратные и ресурсоемкие способы решения проблем так привлекают разработчиков. Причина все в той же простоте реализаций. По прежнему программисту не надо думать о "клиентах" и "серверах", он лишь пишет программу используя библиотеки пользовательского интерфейса и доступа к базам данных. Простота – ключ к популярности. Именно этой простотой и не отличаются подходы, о которых пойдет речь далее.

Разработчики, которые хотели не суррогатной, но реальной 3-х звенной модели понимали необходимость реализовать как сбалансированный, лишенный графического груза сервер, так и настоящий "тонкий клиент", программу, которая занималась бы исключительно интерфейсом. Разработчики разделились на несколько групп и пошли каждый своим путем. Одна группа вооружилась обычным HTML браузером и стала использовать его в качестве "тонкого клиента". Скупость доступных средств построения пользовательского интерфейса никого не смущала. Впрочем, очень скоро язык гипертекстовой разметки журнальных страниц стал обрастать дополнительными "наворотами". Однако ни DHTML, ни слои и Javascriptы радикально ситуацию не изменили, но сделали ее лишь более запутанной. Браузерная война внесла свою лепту добавив проблем разработчикам, вынуждая их стремиться поддержать максимальное количество браузеров. Качества коду это не прибавляло, но значительно увеличивало размеры страниц. Но даже не размер страниц и не недружественность таких интерфейсов стали вызывать вопросы. Стилистика и подходы к разработке подобных систем отличались от комфорта в котором пребывали программисты старых классических 2-х звенных систем. Необходимость мыслить в категориях "страницы" и "контекста клиента" ломали былую стройность серверного приложения. Разработчик должен сгенерировать либо руками, либо из шаблона, нужную в данный момент интерфейсную страницу. Обогатить ее информационным содержанием, при этом не забыв поместить внутрь ее контрольные цифры. Эти контрольные цифры помогут серверу вспомнить о чем идет речь если вдруг клиенту вздумается нажать на кнопку "А" в интерфейсе "В". Ну и, разумеется, надо принимать строки от клиентского браузера, их разбирать, и по этим самым контрольным, статусным точкам находить в своей памяти образ клиентской сессии, предпринимать некие действия и создавать новую страницу. Довольно сложно.

Естественно программисты стремились упростить процесс разработки делая его подобным тому, классическому. Начали появляться разнообразные решения. Возникли PHP, множество библиотек на разных языках. Особенно богат такими средствами мир Java. Однако это все маскировки архитектуры, стремление сделать процесс серверного программирования более стройным и логичным. В попытках сделать пользовательский интерфейс более удобным, разумным и современным начали появляться специальные "тонкие клиенты", которые работали со специально созданными для них языками описания страниц. Некоторые языки встраивались в браузеры (XUL), однако принципов серверного программирования это не меняло. Разработчику по прежнему не хватает простоты.

Другая группы вооружилась системами объектного брокеринга. RPC, CORBA, COM, DCOM, RMI, SOAP – те инструменты, которые позволяли разработчику изменить подходы к созданию приложений. Весьма заманчивая перспектива удаленно создавать объекты, вызывать методы и процедуры. Правда если "клиент" сам обратится к серверу за удаленными процедурами, он становится "толстым"(rich client) клиентом. Если "клиент" просит у сервера данные для текущей генерации интерфейса, это просто интеллектуальный и сложный браузер. "Тонкий клиент", основанный на CORBA технологии содержит весь набор интерфейсных средств, позволяя "серверу" управлять ими как своим ресурсом. Эдакий удаленный, расположенный на стороне клиента репозиторий графических инструментов. Замечательная идея, но ее усложняет реализация. Программный интерфейс CORBA систем не прост и совсем не лаконичен. Конечно в мире Java эти вопросы решаются несколько проще, но ведь и не все пишут на Java. И потом, что такое создание интерфейса? Это длинная последовательность вызова процедур типа "СоздатьОкно", "ВОкнеПоместитьКнопку", "ВКнопкеНаписатьТекст". Работая с CORBA методами эти последовательности будут выглядеть как большой поток малых по размеру пакетов, которые должны быть подготовлены, отправлены службами CORBA и приняты другой стороной. Последовательность пакетов малой или переменной величины вызывает замедление процесса обработки данных в TCP/IP стеке. Есть мнение, что использовать удаленный вызов процедур надо в случае работы с масштабными вычисления и не так часто. С этим мнением трудно не согласиться.

Анализируя приведенные выше подходы к решению проблем разработки систем "клиент-сервер", автор проекта Glan поставил перед собой задачу создать инструмент, отвечающий следующим требованиям:
Простота
*Программист должен создавать приложение как обыкновенную несетевую графическую программу.
*Программиста нельзя обременять сложными дополнительными программными интерфейсами.
*Программист не должен быть загружен дополнительным знанием о способах организации взаимодействия между клиентом и сервером.
*Программист не должен думать о клиентской стороне.
*Программист не должен думать о сетевой стороне создаваемого решения.
Нетребовательность к телекоммуникационным ресурсам
*Взаимодействие клиента и сервера должно осуществляться на минимальных скоростях.
*"Тонкий клиент" как средство взаимодействия клиента с сервером.
*Клиентская часть тандема должна быть минимальна по размеру и нетребовательна к ресурсам.
*Клиент должен быть кроссплатформенным и работать на основных коммерчески эксплуатируемых платформах.
*Пользователь "тонкого клиента", взаимодействующего с сервером не должен видеть разницу между обычным локальным приложением и приложением сетевым.
Результатом размышлений и попыток создать максимально удобный инструмент разработки сетевых приложений, стало возникновение проекта "Glan (Global Application Network)". Инструмент Glan представляет собой тандем библиотеки разработки серверов и "тонкого клиента". Библиотека предоставляет разработчику возможность не задумываться о всех сложностях создания сетевых приложений, но полностью сконцентрироваться на создании программы. В распоряжение программиста поступает развитый набор средств, которые хорошо знакомы разработчику пользовательского интерфейса. Появляется возможность свободно оперировать такими понятиями как "окно", "фрейм", "меню", "кнопка" и прочими хорошо известными инструментами из арсенала графических библиотек. Кроссплатформенность достигается посредством использования хорошо известной библиотеки Qt, разработчиком которой является компания TrollTech. Именование классов, параметров функций и внутренних структур библиотеки Glan максимально идентично именованию в Qt. Поддерживается механизм сигналов и слотов, ставших отличительной чертой Qt. В этом разработчики Glan усматривают дополнительные преимущества, позволяющие большому пласту программистов, использующих Qt в своей практике, легко адаптироваться в классах Glan. Более того, появляется возможность трансформировать существующие Qt приложения в сетевые. Максимально комфортный способ разработки позволяет полностью перенести нагрузку на сторону сервера, предоставив "клиенту" только интерфейсные функции. За интерфейсной оберткой библиотеки Glan скрывается механизм рационального транспорта информации и данных между клиентом и сервером. Оптимизационным ключом стали алгоритмы сборки запросов в пакеты и передача подготовленных данных в сжатом виде. Получаемый на стороне клиента комфорт от использование сетевой "Glan программы" максимально идентичен комфорту от работы с обычной локальной программой. Пользователь получает интерфейс к которому он привык во всем его функциональном многообразии и не испытывает известного дискомфорта от работы с интерфейсами основанными на HTML браузерах. Результатом работы программиста, пользующегося библиотекой Glan становится серверная программа (демон), полностью готовая к эксплуатации.

На этом примере можно увидеть насколько близка методология создания сетевого приложения Glan к методологии создания приложения в Qt.

GGroupBox *Window::createSecondExclusiveGroup()
{
TransportPacket Packet;
GGroupBox *groupBox = new GGroupBox(tr("E&xclusive Radio Buttons"), this);
groupBox->setCheckable(true);
groupBox->setChecked(false);
GRadioButton *radio1 = new GRadioButton(tr("Rad&io button 1"), this);
GRadioButton *radio2 = new GRadioButton(tr("Radi&o button 2"), this);
GRadioButton *radio3 = new GRadioButton(tr("Radio &button 3"), this);
radio1->setChecked(true);
GCheckBox *checkBox = new GCheckBox(tr("Ind&ependent checkbox"), this);
checkBox->setChecked(true);
GVBoxLayout *vbox = new GVBoxLayout;
vbox->addWidget(radio1);
vbox->addWidget(radio2);
vbox->addWidget(radio3);
vbox->addWidget(checkBox);
vbox->addStretch(1);
groupBox->setLayout(vbox);
return groupBox;
}

Как видно отличия незначительны.
Результат работы программы, фрагмент которой был представлен выше, на стороне клиента выглядит одинаково как для Х11 платформ, так и для MsWindows.
Описанные возможности дают разработчикам основание позиционировать Glan как инструмент создания Интернет-приложений с развитым пользовательским интерфейсом. А простота программирования сервера ( идентичная с принципами программирования обычного графического приложения ) дает разработчику дополнительные возможности создания современных сетевых приложений и подходов к созданию единой корпоративной рспределенной информационной среды.

Олег Шальнев

RSS-материал