Основы Opera Unite для разработчиков — обновлённые
В соавторстве с Arve, Chris, Zi Bin и Lissy.
Введение
Opera Unite представляет из себя веб-сервер, работающий внутри браузера Opera, который позволяет делать удивительные вещи. Одним нажатием на кнопку вы можете поделиться картинками, документами, видео, музыкой, совместными играми и множеством других вещей с друзьями и коллегами. В рамках Opera Labs несколько месяцев назад мы выпустили раннюю версию сервера Opera Unite, сегодня же речь пойдёт о бета-версии Opera 10.10, представляющей новую улучшенную версию Opera Unite.
Эта статья поможет вам начать путь по дороге разработки приложений Opera Unite — она рассказывает о том, как сервер Opera Unite работает и что он может. Ниже я коротко расскажу вам о базовых идеях Opera Unite, покажу как запустить веб-сервер в вашем браузере и продемонстрирую пример того, как написать приложение для Opera Unite в виде простого блога.
Содержание статьи по порядку:
- Основные понятия
- Запуск веб-сервера
- Создание приложения Opera Unite: простой блог
- Использование приложения Opera Unite
- Просмотр приложения Opera Unite
- Загрузка приложения Opera Unite на unite.opera.com
- Дальнейшее чтение
Основные понятия
Эта часть расскажет об основах работы Opera Unite и о том, как собираются приложения для Opera Unite.
Что такое Opera Unite?
Opera Unite — это веб-сервер, который работает внутри браузера Opera. Он позволяет пользователю устанавливать приложения и использовать их вместе с друзьями, коллегами или даже сразу со всеми, при желании. Всё взаимодействие происходит через центральный сервер Opera Unite, для чего Opera Unite использует прокси между сервером и его клиентами (доступными на unite.opera.com), чтобы избежать дополнительной настройки файрвола.
Прокси Opera Unite
Когда пользователь запускает веб-сервер в домашней сети, в этой сети есть устройство, которое выступает в роли файрвола, нуждающееся в дополнительной настройке. См. рисунок 1:
Рисунок 1: традиционная конфигурация веб-сервера
Обычно, пользователю нужно открыть порты и настроить их переадресацию на локальный компьютер для того, чтобы люди за файрволом могли иметь доступ к серверу.
Однако когда вы используете Opera Unite, никакой настройки не требуется, что видно на рисунке 2.
Рисунок 2: конфигурация при использовании сервера Opera Unite в браузере
Веб-сервер инициализирует подключение к прокси и использует это подключение для передачи обратно информации о входящих запросах.
Обратите внимание, что прокси — это всего лишь запасной механизм, который используется, чтобы наверняка передать ваши данные, в случае когда работа с NAT по какой-то причине невозможна. Также, Opera Unite поддерживает работу через UPnP, что позволяет передавать данные через прямое подключение, если эта возможность доступна. Это может значительно ускорить работу ваших приложений за счёт работы без прокси-сервера. Однако использование прямого подключение остаётся на совести каждого отдельного приложения и не всегда гарантирует более быструю работу приложения. UPnP не имеет механизма авторизации и подразумевает, что все локальные системы и их пользователи являются доверенными.
Приложения Opera Unite
Приложение Opera Unite состоит из файла config.xml
, содержащего базовую информацию о приложении, и вполне обычной для сайта структуры файлов. В этом смысле, они очень похожи на виджеты для Opera, хотя то, каким образом приложения Opera Unite запускаются и используется, сильно отличается от виджетов. Другое отличие состоит в том, что, в отличие от виджетов Opera, файл config.xml
для приложений Opera Unite должен содержать элемент feature
:
<feature name="http://xmlns.opera.com/webserver">
<param name="type" value="service"/>
<param name="servicepath" value="blog"/>
</feature>
В этом случае, для приложения становится доступен специальный JavaScript-объект opera.io.webserver
. Более подробно об этом можно прочитать в документации по JavaScript API для сервера Opera Unite.
Поскольку приложения Opera Unite используют те же технологии, что и виджеты Opera, то, запустив сервер Opera Unite, вы сможет легко контролировать и настраивать его при помощи HTML, CSS и JavaScript. Хотя, приложения Opera Unite получают доступ к функциям, обычно недоступным для виджетов или веб-страниц, например — изолированная файловая система (песочница).
Если вы хотите узнать больше о виджетах Opera, вы можете найти всю информацию в статьях о виджетах на сайте Dev.Opera.
Двигаемся дальше — запускаем Opera Unite и начинаем собирать простое приложение.
Запуск веб-сервера
Для большей безопасности и производительности веб-сервер не запускается по умолчанию про запуске Opera. Для запуска сервера нужно выбрать в меню Инструменты > Сервер Opera Unite > Включить Opera Unite, либо запустить одно из приложений Opera Unite. Сразу после этого появится диалог, который предложит вам ввести логин и пароль — те же, что используются на My Opera.
Обратите внимание, что для использования в Opera Unite подходят только те логины My Opera, что не содержат недопустимых для URL символов: «/», «.», «_» и пробелов.
На следующем шаге вам нужно назвать устройство. Вы можете выбрать имя из выпадающего списка или указать любое другое. Имя устройства будет идентифицировать ваш сервер для прокси. Сервер будет доступен по адресам вроде этих:
http://devicename.username.proxyaddress/applicationname
Таким образом, для того, чтобы увидеть приложение test
на сервере your_device
на operaunite.com
вам нужно открыть этот URL:
http://your_device.your_username.operaunite.com/test
Создание приложения Opera Unite: простой блог
А теперь короткий рассказ об изготовлении простого приложения для ведения блога, который позволит пользователю публиковать записи. Сохранённые записи немедленно становятся доступны всему миру при помощи сервера.
Приложение состоит из двух частей: первая — это те страницы, которые позволяют владельцу приложения управлять и настраивать его, вторая — это страницы, видимые всем пользователям, которые и отдаёт сервер.
Те, кому не терпится попробовать, могут загрузить код блога для Opera Unite. Он упакован в файл с расширением .ua
— такое расширение по умолчанию имеют все приложения Opera Unite. Вы можете разархивировать пакет, чтобы взглянуть на исходный код или просто перетянуть пакет в браузер Opera, чтобы запустить пример блога для Opera Unite.
Файлы и папки приложения
Наше приложение будет содержать файлы и папки, изображённые на рисунке 3:
Рисунок 3: структура папки приложения
config.xml
: файл настроек приложения.index.html
: логическое начало приложения, куда подключаются скрипты.script/script.js
: непосредственный код приложения.
Из указанных файлов строго необходимы только config.xml
и index.html
.
Также вы можете включить в состав пакета папку public_html
— волшебную папку для приложений Opera Unite. Обычно файлы и папки внутри вашего приложения недоступны пользователям, запрашивающим приложение, поэтому, если вы захотите отдать пользователю какой нибудь файл стилей, статические картинки или что-нибудь вроде этого, то положите файлы именно в эту папку. Эти файлы будут привязаны к относительному корню вашего приложения и, к примеру, файл cats.png внутри папки public_html
приложения helloOperaUnite
будет доступен по адресу:
http://your_device.your_username.operaunite.com/helloOperaUnite/cats.png
Настройки приложения: config.xml
Это приложение будет собрано точно так же, как виджет Opera, поэтому нам будет нужно задать настройки в файле config.xml
. Этот файл по сути является обычным файлом настройки для виджетов Opera, за исключением некоторых дополнительных особенностей. Для того, чтобы обозначить ваше приложение как приложение Opera Unite, вам потребуется включить элемент feature
в элемент widget
файла config.xml
.
Обратите внимание, что виджеты Opera упакованы в обычные zip-файлы и переименованы с расширением .wgt
, тогда как приложения Opera Unite упакованы и переименованы в файлы с расширением .ua
для указания на приложения Opera Unite, т.е. «Unite Application».
<widget>
<widgetname>My blogging application</widgetname>
<description>Blogging application example from the Opera Unite applications primer.</description>
<author>
<name>Hans S. Toemmerholt</name>
<organisation>Opera Software ASA</organisation>
</author>
<feature name="http://xmlns.opera.com/webserver">
<param name="type" value="service"/>
<param name="servicepath" value="blog"/>
</feature>
</widget>
Элемент widgetname
также является названием вашего приложения. Это название будет показано пользователю во время установки и использования приложения.
Вы также можете добавить в config.xml
элемент servicepath
. Содержимое этого элемента должно быть валидным URI и будет являться именем приложения, что присутствует в URI. Если этот элемент отсутствует, Opera попытается использовать в качестве URI приложения содержимое элемента widgetname
. Но если это имя не окажется валидным URI, установка прервётся с ошибкой.
После того, как приложение упаковано и запущено, упомянутый выше config.xml
сделает его доступным по адресу:
http://your_device.your_username.operaunite.com/blog/
Соединяем всё вместе: index.html
У нашего приложения нет интерфейса, кроме тех страниц, что он создаёт. Файл index.html
— это начальная точка приложения и, по сути, весь его интерфейс. В нашем пример мы используем минимальный файл HTML 5 со ссылкой на используемый файл скриптов:
<!DOCTYPE html>
<script src="script/script.js"></script>
Пишем скрипт: script.js
Обратите внимание на то, как мы подключили файл script.js в предыдущем примере. Веб-сервер слушает запросы от пользователей, которые в данный момент ходят по страницам приложения, и создаёт ответы, которые отправляются обратно. Ответом обычно является сгенерированная страница, содержащая информацию.
Функциональность Opera Unite доступна разработчикам через набор JavaScript API, делающий доступными объекты, представляющие веб-сервер, соединения, входящие запросы и исходящие ответы.
Шаг за шагом рассмотрим скрипт:
Обработчики запросов
Веб-сервер принимает запросы от клиентов и посылает им ответы обратно. Сервер Opera Unite основан на событийной модели и вызывает событие в DOM каждый раз, когда браузер обращается к серверу, запрашивая файлы имеющие отношение к приложению Opera Unite. Чтобы иметь возможность обрабатывать эти события, нужно повесить на них обработчики. Это делается при помощи window.onload
:
var webserver;
var entries = [];
window.onload = function () {
webserver = opera.io.webserver
if (webserver)
{
// Handle requests for various URLs
webserver.addEventListener('_index', showEntryList, false);
webserver.addEventListener('entry', showEntry, false);
webserver.addEventListener('form', showForm, false);
webserver.addEventListener('save', saveEntry, false);
}
}
Что же здесь происходит?
Первым делом мы проверяем, что наше приложения действительно является веб-приложением, проверяя существование объекта webserver
. Если он существует, то мы добавляем четыре обработчика событий: _index
, entry
, form
и save
.
Когда обработчики установлены, сервер будет вызывать одну из указанных функций каждый раз, когда пользователь посетит один из следующих URL’ов:
http://your_device.your_username.operaunite.com/blog/
http://your_device.your_username.operaunite.com/blog/entry/
http://your_device.your_username.operaunite.com/blog/form/
Запрос _index
особенный потому, что является запросом к корню приложения. Как мы увидим дальше, пользователь не сможет получить доступ к «save» напрямую, а только через форму.
Показываем список записей
Код функции showEntryList
для запроса _index
довольно простой. После получения запроса, функция в ответ создаёт HTML-документ со списком сохранённых записей.
function showEntryList(e)
{
var response = e.connection.response;
response.write( '<!DOCTYPE html>'
+ '<html><head><title>Entries</title></head>'
+ '<body><ul>'
);
for ( var i = 0, entry; entry = entries[i]; i++ )
{
response.write('<li>'+entry.date+': <a href="entry?id='+i+'">'+entry.title+'</a></li>');
}
response.write('</ul>'
+ '<p><a href="form">Add en entry</a></p>'
+ '</body></html>'
);
response.close();
}
Шаг за шагом, функция делает следующее:
Первым делом создаётся переменная, содержащая объект response
. Этот объект содержит все необходимые методы для отправки данных клиенту:
var response = e.connection.response;
Дальше идёт метод write
, который записывает данные в документ для браузера, который запросил страницу. Для начала создадим простую HTML-обёртку:
response.write('<!DOCTYPE html>'
+ '<html><head><title>Entries</title></head>'
+ '<body><ul>'
);
Существующие записи мы оформим списком ссылок:
for ( var i = 0, entry; entry = entries[i]; i++ )
{
response.write('<li>'+entry.date+': <a href="entry?id='+i+'">'+entry.title+'</a></li>');
}
И, наконец, закрываем подключение:
response.close();
Показываем запись
Дальше нам нужно вывести что-нибудь, когда пользователь кликнул по ссылке на запись:
function showEntry(e)
{
var index = e.connection.request.queryItems['id'][0];
var entry = entries[index];
// ToDo Should have error handling here
var response = e.connection.response;
response.write('<!DOCTYPE html>'
+ '<html><head><title>'+entry.title+'</title></head>'
+ '<body><h1>'+entry.title+'</h1>'
+ '<p>'+entry.date+'</p>'
+ '<div>'+entry.text+'</div>'
+ '</body></html>'
);
response.close();
}
Шаг за шагом, функция делает следующее:
Первым делом мы создаём переменную, содержащую объект request
, который содержит информацию о входящем запросе:
var request = e.connection.request;
Аргументы CGI GET содержатся в свойстве queryItems
запроса. Мы получаем id
записи, которую хотим вывести. Обратите внимание, что один и тот же CGI-аргумент может иметь несколько значений:
var index = request.queryItems['id'][0];
Дальше мы получаем соответствующую запись в блоге:
var entry = entries[index];
Метод write
записывает данные в документ, запрошенный браузером. Заголовок, дата и текст записи заворачиваются в подходящую разметку:
response.write('<!DOCTYPE html>'
+ '<html><head><title>'+entry.title+'</title></head>'
+ '<body><h1>'+entry.title+'</h1>'
+ '<p>'+entry.date+'</p>'
+ '<div>'+entry.text+'</div>'
+ '</body></html>'
);
Показываем форму для добавления записи
После нажатия на ссылку «Добавить запись» вы увидите знакомую форму:
function showForm(e)
{
var response = e.connection.response;
response.write('<!DOCTYPE html>'
+ '<html><head><title>Add entry</title></head>'
+ '<body><h1>Add entry</h1>'
+ '<form method="post" action="save">'
+ '<p><label for="namefield">Title</label> <input id="nameField" type="text" name="title"></p>'
+ '<p><label for="textArea">Text</label> <textarea id="textArea" name="text"></textarea></p>'
+ '<p><input type="submit" name="Add entry"></p>'
+ '</form>'
+ '</body></html>'
);
response.close();
}
Эта форма может быть гораздо сложнее, например: поддерживать обработку ошибок, вывод уже введённых данных и так далее. Также стоит придумать механизм авторизации для потенциально деструктивных операций с данными, но не будем увлекаться — всё-таки у нас простой пример.
Сохранение записи
Наконец, после отправки формы, новая запись должна быть сохранена. В данном примере записи хранятся в простом массиве, который будет утерян после перезапуска приложения, однако расширить пример и добавить механизм сохранения записей будет довольно просто:
function saveEntry(e)
{
var request = e.connection.request
var response = e.connection.response;
// Get POST data
var title = request.bodyItems['title'][0];
var text = request.bodyItems['text'][0];
entries.push({
'title' : title,
'text' : text,
'date' : new Date()
});
// Redirect back to the index of the application
response.setStatusCode(302);
response.setResponseHeader( 'Location', webserver.currentServicePath );
response.close();
}
Вместо request.queryItems
мы используем свойство bodyItems
, чтобы получить доступ к данным, отправленным при помощи POST — в нашем случае это заголовок и содержимое новой записи.
var title = request.bodyItems['title'][0];
var text = request.bodyItems['text'][0];
Отправка формы сохраняет запись в массив:
entries.push({
'title' : title,
'text' : text,
'date' : new Date()
});
И, наконец, когда новая запись сохранена, мы возвращаемся обратно к списку записей:
response.setStatusCode(302);
response.setResponseHeader( 'Location', webserver.currentServicePath );
response.close();
Таким образом мы создаём стандартный HTTP-редирект обратно к корню нашего приложения, который хранится в свойстве webserver.currentServicePath
. Этот редирект вызовет запрос _index
и мы снова получим список всех записей.
Как уже упоминалось, для полноценного использования этого примера, к нему стоит добавить обработку ошибок и статусные сообщения.
Использование приложения Opera Unite
Для того, чтобы запустить приложени Opera Unite, вам сначала нужно его установить. Перетяните config.xml
или полную zip-версию вашего приложения в окно браузера или откройте через файловый диалог. Если вы до сих пор не запускали приложения Opera Unite, то перед вам появится окно настройки Opera Unite, которое уже упоминалось в начале статьи.
Если вы кликнете дважды по приложению My blogging service
в панели приложений Opera Unite, вы должны увидеть страницу как на рисунке 4:
Рисунок 4: главная страница приложения-блога
Клик по ссылке Добавить запись покажет форму, которая позволит вам добавить новую запись в блог, как на рисунке 5:
Рисунок 5: форма для публикации записи
Если ввести в эту форму какой-то текст и нажать кнопку отправки, вы вернётесь на главную страницу блога, где уже будет видна ваша новая запись. Кликните по её заголовку, чтобы посмотреть запись. Добавьте несколько других записей, поиграйте со страницами и вы увидите что-нибудь вроде рисунка 6:
Рисунок 6: наш блог успешно заселён
Просмотр приложения Opera Unite
Если вы следовали всем описанным шагам и запустили приложение в браузере Opera, то теперь у вас есть полноценное веб-приложение. И любой желающий может увидеть его по ссылке:
http://devicename.username.proxyaddress/applicationname
В нашем случае, если устройство называется your_device
и на нём запущен приложение-блог, то его URL будет выглядеть так:
http://your_device.username.operaunite.com/blog
Как вы могли заметить, запуская пример, вы также можете зайти в корень устройства и увидеть все установленные на нём приложения, например:
http://your_device.username.operaunite.com/
Эта страница будет содержать информацию о всех установленных на данном устройстве приложениях, а также, если эти данные будут найдены в config.xml
, более подробную информацию о приложении и его авторе.
Загрузка приложения Opera Unite на unite.opera.com
Итак, вы собрали классное приложение Opera Unite и хотите, чтобы им могли пользоваться не только посетители вашего сервера Opera Unite — вы также хотите сделать его доступным для загрузки и установки на другие сервера Opera Unite, ведь так? Хорошо. И что же для этого нужно сделать? Ответ прост: приложение нужно загрузить на unite.opera.com — этот сайт предназначен для распространения приложений. Данная часть статьи расскажет вам о том, как это сделать.
Перед публикацией
В идеале, перед публикацией вам стоит протестировать приложение на наличие ошибок. Если это возможно, то протестируйте его на разных платформах, устройствах версиях браузера Opera. Также не забывайте, что пользователи ваших приложений могут использовать любой браузер, а не только Opera, поэтому протестируйте приложение в различных браузерах (Firefox, Safari, и т.п.).
Если вы столкнулись с проблемами в работе вашего приложения, но уверены, что с его кодом всё в порядке, то проверьте файл config.xml
на наличие ошибок. Он необходим для правильной работы приложения. Если вы откроете его в других браузерах, то сможете проверить его на корректность синтаксиса. Также стоит проверить, содержит ли config.xml
достаточное количество информации, ведь он будет использоваться для получения всей информации о приложении для репозитария unite.opera.com, а также для пользователей на страницах уже установленных приложений.
Также стоит подумать о переводе приложения на другие языки.
И, наконец, сделайте скриншот работающего приложения, как описано ниже.
Публикация приложения
Для публикации вашего приложения вам нужно посетить страницу загрузки. Выберите приложение в файловом диалоге и загрузите его. Внимательно прочтите и, при необходимости, уточните информацию из config.xml
. При желании, вы можете добавить более подробное описание.
Дальше выберите скриншот приложения в файловом диалоге, чтобы другие пользователи смогли понять что из себя представляет ваше приложение, прежде чем они попробуют его установить.
Помимо этого, вам нужно будет выбрать устройства для использования на которых ваше приложение было создано. Убедитесь, что оно был протестировано на указанных устройствах и выберите подходящую группу. Последним шагом будет выбор языков, поддерживаемых вашим приложением. Убедитесь, что вы предусмотрели перевод для всех выбранных языков.
Как я могу предложить воспользоваться моим приложением?
После того, как вы потратили кучу времени на изготовление приложения, вполне естественно, что вам захочется показать его другим людям. Чтобы увеличить число просмотров, вам нужно рассказать потенциальным пользователям каких возможностей стоит ожидать от вашего приложения. У каждого приложения есть короткое описание, которое автоматические копируется из файла config.xml
и длинное описание, где вы можете более подробно рассказать о приложении и особенностях его работы.
Используйте короткое описание, чтобы привлечь внимание пользователя, расскажите ему что ваше приложение может и какую пользу можно из него извлечь. Это может быть даже короткий подзаголовок, но он должен быть информативным. Вам стоит избегать фраз вроде «Скачай меня» или «Это супер-крутое приложение». Используйте длинное описание для того, чтобы объяснить пользователям какие возможности предоставляет ваше приложение, как они реализованы. Также полезно будет рассказать про изменения в различных версиях приложения, правила игры и так далее.
И, наконец, не забудьте сделать скриншот приложения в работе. В качестве примера, вы можете вдохновиться приложениями команды Opera Unite.
Обратите внимание, что идеальные размеры для скриншота составляют 445 × 230 пикселов — именно эти размеры используются на сайте Opera Unite. Если ваши скриншоты будут разных размеров, то они будут приведены к единым размерам, что может привести к нежелательным результатам.
Одобрение приложений Opera Unite
Все приложения Opera Unite должны быть одобрены специальными сотрудниками Opera Software. Мы проверим их на ошибки, чтобы убедиться в том, что все пользователи смогут их запустить, однако мы не несём ответственности за содержимое этих приложений и не даём гарантий касательно их функциональности. Подробнее об этом в читайте в правилах.
Каким правилам нужно соответствовать для одобрения приложения?
Некоторые требования, которые мы предъявляем к приложениям:
- Приложение должно иметь внятное название и описание.
- Приложение не должно иметь очевидных ошибок, поэтому протестируйте его перед загрузкой.
- Приложение не должно содержать намеренно опасного кода.
- Приложение не должно содержать информации, на которую вы не имеете авторского права.
- Приложение не должно содержать или ссылаться на информацию «для взрослых» или провокационную информацию.
- Приложение должно отдавать HTML-страницы совместимые со стандартами, которые доступны для всех современных браузеров и устройств.
Дальнейшее чтение
Теперь вы разбираетесь в основах создания и загрузки приложений Opera Unite, и вам, возможно, будет интересно узнать больше:
- JavaScript API для приложений Opera Unite — документация в формате JSDoc для JavaScript-интерфейсов и методов, доступных для работы с сервером Opera Unite.
- JavaScript API для Opera File I/O — документация в формате JSDoc для JavaScript-интерфейсов и методов, доступных для работы с файлами и папками.
- Markuper: шаблонизатор для приложений Opera Unite
- Yusef: фреймворк для Opera Unite
This article is licensed under a Creative Commons Attribution, Non Commercial - Share Alike 2.5 license.
Comments
The forum archive of this article is still available on My Opera.