Наша жизнь все больше перемещается в Сеть. Браузер стал главной программой на ПК, а Гугл вовсю штампует ноутбуки с Chrome вместо полноценной ОС. Казалось бы, в этих условиях перспективы обычных, не веб-ориентированных языков программирования крайне сомнительны. И тем не менее нас, старых добрых хардкорных программистов на си приплюснутом, еще рано списывать на свалку истории — мы все еще получаем кучу денег :), потому что без нормального машинного кода до сих пор никто не обходится.

Потребность в запуске нативного кода в браузере появилась не на пустом месте. Как бы ни старались разработчики JavaScript и HTML 5 движков, производительность их творений не выдерживает конкуренции с обычным кодом на C или C++. Если нам нужно показать крутую графику или поразить окружающих высококачественным звуком, то типичными инструментами веб-разработчика подобное реализовать затруднительно. Именно это и стало одной из основных причин для появления технологии Native Client от Google.

 

Что такое Native Client

Ребята из Гугла начали свой нелегкий труд над NaCl в далеком 2008 году. Задачи, которые они ставили перед собой, были сложны и амбициозны. Первым делом надо было обеспечить легкую переносимость legacy кода в NaCl. Это была фактически первопричина всей этой затеи. Если у нас есть куча старого и не очень кода на плюсах, который работал сугубо на десктопах, и мы вдруг решили, что пора осваивать веб, то нам не надо учить новые языки программирования и технологии, а достаточно лишь портировать имеющийся код на Native Client платформу.

Но даже если мы и готовы переписать все с нуля на незнакомых нам языках, не факт, что у нас выйдет то, что мы ожидали. Показывать качественную 2D- и 3D-графику, использовать многопоточность, да и вообще быть ближе к железу у нас ну никак не выйдет. Это была вторая цель, которую преследовала Google. Кроме того, как я уже сказал, никто не отменял относительно низкую производительность скриптовых языков в браузере.

Ко всему прочему, умные парни из Google подумали и о безопасности пользователей. Весь нативный код выполняется в двойной (!) песочнице, что позволяет блондинкам и прочим продвинутым личностям не бояться забагованных приложений и атак злых вирусов.

Ну и на десерт у нас платформонезависимость. Да-да! Мы можем написать плюсовый код, и он будет работать на Windows, OS X и даже, не побоюсь этого слова, Linux. А вишенкой на этом десерте будет поддержка x86- и ARM-архитектур.

В 2011-м Гуглец включил поддержку NaCl в Chrome. Другие браузеры, к сожалению, пока не поддержали инициативу интернет-гиганта. Старожилам интернета в голову невольно могут прийти воспоминания об ActiveX, который и ныне здравствует (в кругу любителей IE), но, в отличие от технологии Майкрософт, Native Client распространяется с открытым исходным кодом под новой лицензией BSD. Да и над безопасностью в NaCl подумали лучше.

GameDev уже вовсю штампует игрушки для NaCl

 

Для чего можно использовать Native Client

На практике Native Client можно использовать в первую очередь для запуска игрушек в браузере. Собственно, первый опыт уже есть — под Google NaCl портировали Quake. Да, да, ту самую кваку 1996 года выпуска, в которой ты провел столько лет, разрубая жирных огров саперной лопаткой (если ты не знаешь, как зарубить лопатой вооруженного гранатометом и бензопилой огра, напиши мне) и разрывая в клочья зомби из рокетлаунчера.

Исполнение машинного кода в браузере отлично поможет разгрузить сервер. Например, если у нас есть онлайн-сервис для конвертации видео в разные форматы, то алгоритм работы с ним должен выглядеть примерно так: пользователь загружает видео на сервер, долго ждет, пока наш мощный CPU перелопатит файл, выбрасывая в атмосферу много калорий тепла, а потом счастливый юзер скачивает результат с нашего сервера. Но если мы перенесем конвертор с сервера на клиент, то мы сразу уберем нагрузку с нашего железа и нехило расчистим интернет-канал, который за «умеренную» плату предоставил нам хостер. Да и пользователь будет доволен — в среднем конвертация должна пройти быстрее, так как сотни мегабайт туда-обратно по сети не гоняются. А для юзеров с паранойей можно с гордостью заявить, что их драгоценные personal data целиком обрабатываются только на их ПК. Это, кстати, актуально и для корпоративного сектора.

 

Как это работает

Native Client — это общее название для набора разнообразных программных компонентов, которые работают вместе для обеспечения безопасного функционирования C++ кода в вебе. На высоком уровне NaCl состоит из тулчейна (компилятора, линкера и так далее) и рантайм-библиотек, которые встроены в браузер и позволяют нативному коду безопасно работать с нужными API.

Для переносимости приложений между разными архитектурами существует расширение Portable Native Client (PNaCl). Отличие его заключается в том, что при компиляции код транслируется в промежуточное представление, а уже после запуска на той или иной платформе браузер переводит это представление в машинный код.

Для обеспечения безопасности Гугл сделал две вещи. Первая — это специальный набор API, с которым может работать код, выполняющийся под NaCl. Нативный модуль не должен пытаться выйти за пределы разрешенного API, вмешиваться в работу стороннего кода или браузера.

Второй важный момент, обеспечивающий беззаботную жизнь для пользователей Native Client, — это специальный анализатор кода, который должен удостовериться, что приложение не пытается сделать ничего противоправного.

Как взаимодействуют между собой модуль NaCl и браузер

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

C++ код может общаться с JavaScript посредством специальных сообщений. Сообщения пересылаются асинхронно, то есть не надо ждать, пока другая сторона получит его.

 

Пишем Hello NaCl

Теперь у нас есть представление о Native Client, и нужно пробовать написать что-нибудь полезное… или не очень. Мы будем делать Hello World, ну или Hello NaCl.

Для начала нужно скачать и установить Native Client SDK. Ссылку на страницу загрузки ты найдешь во врезке. Там же будет и инструкция по установке. Скажу лишь, что обязательно будет нужен Python 2.7 и make.

Вместе с SDK идет простой веб-сервер, который может хостить приложения на localhost. Самый простой путь запустить его — это выполнить следующие команды:
$ cd pepper_$(VERSION)/getting_started
$ make serve
SDK может содержать в себе несколько разных версий, правильную нужно подставить вместо $(VERSION). Также можно использовать любой другой веб-сервер. PNaCl включен по умолчанию в версии хрома 31 и старше. Но нужно следить, чтобы выбранная версия SDK поддерживалась установленной версией Chrome.

Великий и могучий Гугл любит преданных разработчиков и потому любезно предоставил пример с минимальным кодом для создания NaCl-модуля. Лежит этот код в папке pepper_$(VERSION)/getting_started/part1 и состоит из нескольких файлов. Первый — это index.html. В нем находится HTMLLayout и JS-код для взаимодействия с плюсовым модулем. Если внимательно присмотреться, то можно заметить файл с расширением nmf, а точнее, hello_tutorial.nmf. Это манифест, который указывает на нашу HTML, NaCl-модуль и служит вместилищем дополнительных настроек для тонкого тюнинга.

Далее идет hello_tutorial.cc, он и является исходником на C++, который потом можно собрать с помощью Makefile. Сделать это до безобразия просто:
$ cd pepper_$(VERSION)/getting_started/part1
$ make
Если мы использовали веб-сервер, идущий вместе с SDK, то после сборки в хроме достаточно вбить такой URL: http://localhost:5103/part1, и ты станешь свидетелем чуда — текст на открывшейся странице изменится с LOADING… на SUCCESS. Впечатляет, не правда ли?

Официальная страница Native Client

Так как мы собирались делать Hello NaCl, то нам придется немного изменить код. Для этого заглянем в файл index.html и найдем там JavaScript-функцию moduleDidLoad. Кстати, сейчас самое время пробежаться по всему коду HTML-файла и остановиться на непонятных вещах, благо все они щедро сдобрены комментариями. В функции moduleDidLoad происходит загрузка нашего NaCl-модуля hello_tutorial и вывод того самого текста SUCCESS, который мы успели лицезреть при переходе по линку /part1. Теперь пошлем нативному модулю слово hello, для этого достаточно вызвать функцию postMessage у переменной модуля. В коде это будет выглядеть примерно так:
function moduleDidLoad() {
HelloTutorialModule = document.getElementById('hello_tutorial');
updateStatus('SUCCESS');
// Посылаем сообщение Native Client модулю
HelloTutorialModule.postMessage('hello');
}
Сообщение послали, теперь надо его получить. Для этого надо реализовать член-функцию HandleMessage в файле hello_tutorial.cc. В файле содержится TODO, которое недвусмысленно намекает на то, что нужно делать. В обработчике сообщения мы будем отправлять браузеру ответ с помощью функции PostMessage, но перед этим выполним пару проверок.
virtual void HandleMessage(const pp::Var& var_message) {
if (!var_message.is_string())
return;
std::string message = var_message.AsString();
pp::Var var_reply;
if (message == "hello") {
var_reply = pp::Var("hello from NaCl");
PostMessage(var_reply);
}
}
Как видно из кода, мы первым делом проверяем, пришла ли нам строка, а не что-то другое. Класс Var служит оберткой со счетчиком ссылок для сырых переменных C++. Именно объекты этого класса пересылаются между веб-страницей и нативным модулем. Далее мы проверяем, что нам пришло именно hello, и отправляем ответ, предварительно обернув его объектом класса Var.

В index.html уже есть обработчик сообщений от NaCl-модуля. Он просто выведет JS alert с полученной строкой:
function handleMessage(message_event) {
alert(message_event.data);
}
После того как мы сделали нужные изменения, можно пересобирать модуль и обновлять страницу http://localhost:5103/part1. Увидев message box с заветной строкой hello from NaCl, мы можем с гордостью заявить, что освоили новую технологию.

 

Заключение

Гугл придумал полезную штуку. Жаль, что пока никто, кроме «корпорации добра», не поддержал Native Client платформу. Достаточно высокая производительность является преимуществом по сравнению с Java, апплеты которой также могут выполняться в браузере, а высокий уровень безопасности уделывает ActiveX от Microsoft. Будем ждать, пока Chrome захватит мир или другие разработчики браузеров внедрят в свои творения Native Client.

 

WWW

Официальная страница платформы Native Client: https://developer.chrome.com/native-client

Загрузка Native Client SDK и инструкция по установке: https://developer.chrome.com/native-client/sdk/download

Комментарии

Подпишитесь на ][, чтобы участвовать в обсуждении

Обсуждение этой статьи доступно только нашим подписчикам. Вы можете войти в свой аккаунт или зарегистрироваться и оплатить подписку, чтобы свободно участвовать в обсуждении.

Check Also

Мошенничество по воздуху. Разбираем возможность Cryptogram Replay Attack в Apple Pay

Задача платежной системы — списать нужную сумму в пользу продавца со счета верное число ра…