- PVSM.RU - https://www.pvsm.ru -

Wt, библиотека C++ для разработки веб-приложений

Всем привет!

Так случилось, что на Хабре не было ни одного упоминания Wt, C++ Web Toolkit [1], кроме одного комментария [2].

Библиотека Wt может заинтересовать тех, кто пишет на C++ и захотел посмотреть в сторону Web, но не хочет изучать и/или использовать HTML, CSS, JavaScript, SQL и дополнительные технологии, связанные с веб-разработкой и работой с БД. В данной статье моей целью было обратить внимание сообщества на Wt, а не освещать все его возможности.

Если Вы жаждете посмотреть, как это работает, вот пример, демонстрирующий различные виджеты: www.webtoolkit.eu/widgets [3]

Обзор возможностей библиотеки на русском языке: www.webtoolkit.eu/wt/ru/features [4]

Возможности Wt

Здесь я приведу некоторые из особенностей, которые мне кажутся наиболее привлекательными.

Wt является кроссплатформенной свободной поддерживаемой C++ библиотекой. Релизы выходят несколько раз в год. Доступна на условиях лицензии GNU GPL 2 или коммерческой лицензии. Напомню, что лицензия GNU GPL 2 не запрещает создавать приложение с закрытым кодом, чтобы пользоваться им лично, в частности для разворачивания на своем сервере.

Программирование с использованием Wt строится вокруг виджетов, подобно Qt. Многие вещи похожи на Qt, что делает Wt простым для изучения для тех, кто знаком с Qt. В отличие от Qt, не происходит кодогенерации — используются сигналы, основанные на boost.signals, которые представляют собой обычный код C++, не требующий генерации. Сигналы виджетов (например, сигнал нажатия на кнопку) можно присоединять к любым функциям C++ (и функциональным объектам). Полностью асинхронный вход/выход (на основе библиотеки boost.asio) управляется событиями. Не происходит постоянного порождения и завершения потоков выполнения. Для каждой сессии на сервере хранится объект WApplication, через который доступно всё дерево виджетов. Доступ к виджетам сессии осуществляется способом, защищенным от «гонок», благодаря чему возможно безопасное взаимодействие сессий между собой и с сервером. Это продемонстрировано в примере чата [5]. В этом же примере показано использование событий, инициируемых сервером (а не клиентом) и возможность включения приложения в другие страницы или сайты в виде загружаемого скрипта (вроде того, как виджет google maps может встраиваться в друге сайты).

Wt-приложения работают в основных браузерах, причем если JavaScript работает, выдается Ajax-версия, а если не работает — аналогичный HTML код, что является уникальной возможностью Wt, по крайней мере среди C++ фреймворков [6]. Это позволяет без дополнительных усилий со стороны разработчика создавать приложение, использующее преимущества таких технологий, как Ajax, Comet [7], WebSocket [8], но в то же время работающее, если они недоступны. Кроме того, есть возможность оптимизации выдачи для поисковых роботов (речь идет не о клоакинге, а об улучшениях вроде отказа от случайных идентификаторов объектов). Wt может использовать такие новшества HTML5, как переписывание URL в браузере (для создания REST-приложений [9]), выбор нескольких файлов, теги video и audio, но если их нет, по возможности используются обходные пути (к примеру, звук и видео через flash вместо тегов video и audio).

Возможно создание веб-приложений, подключаемых через http, fastcgi или ISAPI (последний только для платформ Win32). Какой именно способ соединения будет использоваться, определяется на этапе компоновки, выбором нужной библиотеки. Компонуя свой код с библиотекой встроенного http-сервера, получаем полноценный Веб-сервер, который удобно использовать при отладке, но можно запускать и на production, хотя в последнем случае стоит также рассмотреть возможность использования других способов соединения.

В Wt встроено использование Юникода и локализации.

Низкое потребление ресурсов [10] позволяет запускать приложения на устройствах с ограниченными ресурсами, например, на роутерах.

Библиотеку удобно использовать для создания веб-интерфейсов для существующих программ, написанных на C++.

Библиотека обеспечивает высокий уровень безопасности, в частности защиту от атак XSS или SQL-injection. К примеру, виджет WText, отвечающий за отображение текста, убеждается, что его текст не содержит «опасных» атрибутов и тегов (вроде script), и вычищает их при необходимости. Имеется поддержка HTTPS. Есть защита от DDoS атак.

Библиотека также включает ряд надстроек, полезных при веб-разработке [11], в частности, систему рисования, систему построения диаграмм, ORM (отображение классов C++ на структуры баз данных), систему аутентификации.

Вообще хочется отметить чистоту и высокое качество кода библиотеки: легко читается не только документация, но при необходимости и код реализации. Сделано общо и гибко. Нигде (даже при компиляции кода, связанного с БД) не происходит кодогенерации. Часть библиотеки, ответственная за работу с БД, может быть использована (или куплена лицензия) отдельно от остальных компонентов. Эта часть библиотеки заслуживает отдельной статьи.

Для Wt доступны версии на Java и других языках [12], но тут я ограничусь рассмотрением C++ версии. Версия 1.0.0 была опубликована в 2005 году, так что по своей «зрелости» Wt может соперничать с Django и Ruby on Rails. Стоит отметить, что на C++ существует ещё как минимум два активных проекта: CppCMS [13] и Tntnet [14]. Сравнение возможностей [6] представлено в википедии. Мой выбор пал на Wt в первую очередь за возможность полного абстрагирования от HTML, CSS, JavaScript в пользу одного языка — C++, а также за автоматическую поддержку как Ajax браузеров, так и браузеров без Ajax.

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

Пример взят отсюда: www.webtoolkit.eu/wt/ru/examples/ [15]

#include <Wt/WApplication>
#include <Wt/WBreak>
#include <Wt/WContainerWidget>
#include <Wt/WLineEdit>
#include <Wt/WPushButton>
#include <Wt/WText>

using namespace Wt;

/*
 * A simple hello world application class which demonstrates
 * how to react to events, read input, and give feed-back.
 */
class HelloApplication : public WApplication
{
public:
  HelloApplication(const WEnvironment& env);

private:
  WLineEdit *nameEdit_;
  WText *greeting_;

  void greet();
};

/*
 * The env argument contains information about the new session, and
 * the initial request. It must be passed to the WApplication
 * constructor so it is typically also an argument for your custom
 * application constructor.
*/
HelloApplication::HelloApplication(const WEnvironment& env)
  : WApplication(env)
{
  setTitle("Hello world");                               // application title

  root()->addWidget(new WText("Your name, please ? "));  // show some text
  nameEdit_ = new WLineEdit(root());                     // allow text input
  nameEdit_->setFocus();                                 // give focus

  WPushButton *button
    = new WPushButton("Greet me.", root());              // create a button
  button->setMargin(5, Left);                            // add 5 pixels margin

  root()->addWidget(new WBreak());                       // insert a line break

  greeting_ = new WText(root());                         // empty text

  /*
   * Connect signals with slots
   *
   * - simple Wt-way
   */
  button->clicked().connect(this, &HelloApplication::greet);

  /*
   * using an arbitrary function object
   * (binding values with boost::bind())
   */
  nameEdit_->enterPressed().connect
    (boost::bind(&HelloApplication::greet, this));
}

void HelloApplication::greet()
{
  /*
   * Update the text, using text input into the nameEdit_ field.
   */
  greeting_->setText("Hello there, " + nameEdit_->text());
}

WApplication *createApplication(const WEnvironment& env)
{
  /*
   * You could read information from the environment to decide whether
   * the user has permission to start a new application
   */
  return new HelloApplication(env);
}

int main(int argc, char **argv)
{
  /*
   * Your main method may set up some shared resources, but should then
   * start the server application (FastCGI or httpd) that starts listening
   * for requests, and handles all of the application life cycles.
   *
   * The last argument to WRun specifies the function that will instantiate
   * new application objects. That function is executed when a new user surfs
   * to the Wt application, and after the library has negotiated browser
   * support. The function should return a newly instantiated application
   * object.
   */
  return WRun(argc, argv, &createApplication);
}

Это пример простого приложения, спрашивающего имя пользователя. Когда пользователь вводит имя и нажимает Enter или кнопку «Greet me.», приложение привествует его: «Hello there, %USERNAME%». Думаю, разбирать код подробно смысла нет, тем более в нем есть комментарии.

Посмотреть запущенный пример можно тут: www.webtoolkit.eu/wt/examples/hello/hello.wt [16]

Чтобы скомпилировать этот пример, нам потребуется компилятор C++ и установленная библиотека Wt. Везучие пользователи Debian и Ubuntu могут просто установить пакет witty-dev.

В линуксе команда компиляции выглядит так:

g++ -lwt -lwthttp -lboost_signals hello.cpp -o hello

Команда запуска:

./hello --docroot . --http-address 127.0.0.1 --http-port 8000

После чего приложени можно будет открыть в браузере по адресу 127.0.0.1:8000

Ссылки

Сайт проекта: www.webtoolkit.eu/ [17]
Блог: www.webtoolkit.eu/wt/blog [18]
Введение: www.webtoolkit.eu/wt/doc/tutorial/wt.html [19]
Примеры: www.webtoolkit.eu/wt/examples/ [20]
Скачать: www.webtoolkit.eu/wt/download [21]
Документация: www.webtoolkit.eu/wt/documentation [22]
Система отслеживания ошибок: redmine.emweb.be/ [23]
Проект также представлен на гитхабе github.com/kdeforche/wt [24]

Автор: starius


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/c-3/6020

Ссылки в тексте:

[1] Wt, C++ Web Toolkit: http://webtoolkit.eu

[2] одного комментария: http://habrahabr.ru/post/111403/#comment_3566653

[3] www.webtoolkit.eu/widgets: http://www.webtoolkit.eu/widgets

[4] www.webtoolkit.eu/wt/ru/features: http://www.webtoolkit.eu/wt/ru/features

[5] примере чата: http://www.webtoolkit.eu/wt/ru/examples/chat

[6] C++ фреймворков: http://en.wikipedia.org/wiki/Comparison_of_web_application_frameworks#C.2B.2B_2

[7] Comet: http://en.wikipedia.org/wiki/Comet_(programming)

[8] WebSocket: http://en.wikipedia.org/wiki/WebSocket

[9] создания REST-приложений: http://www.webtoolkit.eu/wt/ru/blog/2011/02/15/urls__pretty_is_good__restful_is_a_liability

[10] Низкое потребление ресурсов: http://redmine.webtoolkit.eu/projects/wt/wiki/Wt_embedded#ARM926EJ-S

[11] надстроек, полезных при веб-разработке: http://www.webtoolkit.eu/wt/doc/reference/html/modules.html

[12] Java и других языках: http://www.webtoolkit.eu/wt/other_language

[13] CppCMS: http://cppcms.com/

[14] Tntnet: http://www.tntnet.org/

[15] www.webtoolkit.eu/wt/ru/examples/: http://www.webtoolkit.eu/wt/ru/examples/

[16] www.webtoolkit.eu/wt/examples/hello/hello.wt: http://www.webtoolkit.eu/wt/examples/hello/hello.wt

[17] www.webtoolkit.eu/: http://www.webtoolkit.eu/

[18] www.webtoolkit.eu/wt/blog: http://www.webtoolkit.eu/wt/blog

[19] www.webtoolkit.eu/wt/doc/tutorial/wt.html: http://www.webtoolkit.eu/wt/doc/tutorial/wt.html

[20] www.webtoolkit.eu/wt/examples/: http://www.webtoolkit.eu/wt/examples/

[21] www.webtoolkit.eu/wt/download: http://www.webtoolkit.eu/wt/download

[22] www.webtoolkit.eu/wt/documentation: http://www.webtoolkit.eu/wt/documentation

[23] redmine.emweb.be/: http://redmine.emweb.be/

[24] github.com/kdeforche/wt: https://github.com/kdeforche/wt