
Зачем нам зомби
Выбирать в качестве примера приложение «Hello world!» не очень интересно. Гораздо занятнее сделать минимально работающий прототип чего-нибудь полезного. Например, приложение для отслеживания изменений на сайте. В Интернете есть множество решений для этой задачи, начиная с VisualPing и заканчивая расширением для Сhrome. Большинство из них хотят денег за быстрые уведомления, грешат ложными срабатываниями — в общем, всем своим видом показывают что это хорошая, годная ниша. В качестве подопытного кролика будет выступать моя любимая игра с зомби — надо же как-то привлекать ваше внимание :)
Создаем себе облако

- Облако Bluemix с push-уведомлениями наперевес.
- Google Cloud Messaging для отправки уведомлений.
- Android-приложение, получающее push-уведомления.
- Приложение Node.js в облаке, внимательно следящее за сайтом и сразу же отсылающее уведомление при появлении новости.
Регистрируемся в Bluemix, заходим в панель управления и создаем приложение Node.js. Для создания приложения достаточно зайти в “dashboard”, указать имя для рабочего окружения (“space”) и выбрать “create an app”:

В следующем окне нужно выбрать тип приложения, для нашего примера это будет “mobile”:

По умолчанию все, что мы создаем, будет жить в рамках free tier, то есть абсолютно бесплатно. Деньги IBM захочет, если нам понадобится много памяти для приложений или мы станем отсылать больше миллиона уведомлений в месяц и т. д.
Важный момент: по умолчанию приложению выделяется 128 мегабайт памяти, а бесплатно можно использовать до 512 Мб. Поэтому сразу после создания увеличьте доступную приложению память, чтобы в погоне за зомби у сборщика мусора был оперативный простор при парсинге HTML.

Добавляем немного Google Cloud Messaging
Чтобы сделать пример компактным, я покажу, как отсылать уведомления только на Android, хотя Bluemix предоставляет инструменты и для работы с iOS. Заходим в Google Developers Console, создаем приложение, активируем для него push-уведомления и копируем в Bluemix параметры доступа:

Создаем мобильное приложение
За последние несколько лет средства разработки мобильных приложений шагнули далеко вперед. Я еще помню те времена, когда вдумчивая настройка Eclipse была вступительным экзаменом в мир Android-разработки. Сейчас все не так: скачиваем последнюю версию Android Studio, выбираем Create New Project, затем Blank Activity — и приложение готово. Можно запускать в эмуляторе, можно устанавливать на телефон.
Конкуренция — хорошая штука. В борьбе за разработчиков современные облачные решения предлагают не только саму облачную инфраструктуру, но и целую экосистему, построенную вокруг нее. Включая полезные библиотеки, например, для работы с push-уведомлениями. Чтобы подключить в проект соответствующую библиотеку Bluemix, добавим нужные зависимости в Gradle:
немного gradle
compile 'com.google.android.gms:play-services:+'
compile 'com.ibm.mobile.services:ibmbluemix:1.+'
compile 'com.ibm.mobile.services:ibmpush:1.+'
Android-приложение состоит из компонентов, обменивающихся между собой сообщениями. Чтобы код Bluemix мог выполнять требуемые задачи, нужно зарегистрировать в AndroidManifest.xml пару компонентов. Там же укажем необходимые приложению права:
немного xml
<?xml version="1.0" encoding="utf-8"?>
<manifest>
...
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
...
<application>
...
<service
android:name="com.ibm.mobile.services.push.IBMPushIntentService">
</service>
<receiver
android:name="com.ibm.mobile.services.push.IBMPushBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.ibm.mbaas.push.android.sample" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="com.ibm.mbaas.push.android.sample" />
</intent-filter>
</receiver>
</application>
</manifest>
Теперь можно добавить собственно код работы с уведомлениями. Простейший код, который подпишется на уведомления с тегом mytag, необходимо вставить в MainActivity.java. В коде нужно указать “route”, “app key” и “app secret”, они находятся в разделе “mobile options” на экране управления приложением:
и небольшая турка с java
import java.util.List;
import com.ibm.mobile.services.core.IBMBluemix;
import com.ibm.mobile.services.push.IBMPush;
import bolts.Continuation;
import bolts.Task;
public class MainActivity extends ActionBarActivity {
private IBMPush push = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
IBMBluemix.initialize(this,
"ff2c1e25-cc27-435d-b93a-a6b46fbc5056",
"14d8536672d53bb5eb9d1ba28e83292e6320495c",
"http://grigoryvp-test.eu-gb.mybluemix.net"
);
push = IBMPush.initializeService();
// Регистрируемся в сервисе.
push.register("mydevice", "myuser").continueWith(new Continuation<String, Void>() {
@Override
public Void then(Task<String> task) throws Exception {
if (task.isFaulted()) return null;
// Получаем теги, на которые подписаны.
push.getSubscriptions().continueWith(new Continuation<List<String>,Void>() {
@Override
public Void then(Task<List<String>> task) throws Exception {
if (task.isFaulted()) return null;
// Еще ни на что не подписаны?
if (task.getResult().isEmpty()) {
// Подписываемся на нужный тег.
push.subscribe("mytag").continueWith(new Continuation<String, Void>() {
@Override
public Void then(Task<String> task) throws Exception {
return null;
}
});
}
return null;
}
});
return null;
}
});
}
Все, приложение готово. При запуске оно подпишется на push-уведомления. Проверить, что все работает, можно непосредственно через веб-интерфейс Bluemix: переходим в раздел Notifications, выбираем «Отправить уведомление» — и видим уведомление в телефоне.

Следим за зомби



.mc_2_news:first-child .mc_2_news_paragraph
Код, который будет опрашивать сайт и отсылать push-уведомления, выглядит следующим образом:
немного javascript
var content = "";
var ibmpush = require('ibmpush');
var request = require('request');
var cheerio = require('cheerio');
function periodic() {
request("https://www.pi-online.ru/", function (err, res, body) {
if (!err && 200 == res.statusCode) {
var $ = cheerio.load(body);
var contentNew = $(".mc_2_news:first-child .mc_2_news_paragraph").text();
if (content && content !== contentNew) {
var message = {
"alert" : "something updated",
"url": "http://www.google.com"
};
req.ibmpush.sendBroadcastNotification(message, null).then(
function() { logger.info("send success"); },
function() { logger.info("send failure"); }
);
}
content = contentNew;
}
setTimeout(periodic, 60 * 1000);
});
}
periodic();
Деплоим его в облако — и наше решение готово. Через несколько секунд после обновления сайта вы получите уведомление на мобильный телефон. Бесплатно.
Выводы
Показанное решение максимально простое: нет работы с базой данных, контроля ошибок, отображения текста новости и многих других нужных вещей. Зато оно служит наглядной демонстрацией того, насколько далеко продвинулись современные облачные решения. В рамках бесплатных приложений IBM вы можете создавать сервисы, работающие в круглосуточном режиме, отправлять сотни тысяч push-уведомлений, использовать огромное количество готовых библиотек. Борьба за программистов в самом разгаре, и, надеюсь, здоровая конкуренция принесет свои плоды и сделает нашу работу проще и удобнее.
BupycNet
Не совсем понятно, зачем городить огород из технологий, если можно воспользоваться готовым средством? К примеру у меня сервис PushAll. Вы себе пуш можете отправлять при помощи обычного cURL запроса на несколько устройств. Более того у меня можно сразу привязать RSS сайта и фильтровать района записи на получение по ключевым словам.
Причем вы можете также в облаке все это парсить. а пушить уже через мою систему в канал к примеру для своих пользователей.
eyeofhell Автор
Для демонстрации того, как сейчас работают современные облачные сервисы. Можно вообще ничего не программировать и воспользоваться готовым сервисом, к примеру visualping. Но если никто не будет программировать — откуда возьмется новый софт? :)
BupycNet
Ну это да :) Я о том. что было бы неплохо в статью еще добавить, а как к примеру туда быстренько прикрутить любое API.
Тогда можно будет и смски слать и пуши и много еще куда, везде где есть API.
И еще, мне кажется оно бесплатно до тех пор, пока таких как вы мало. ЕЩе я не совсем понял, а как часто оно будет парсить страницы? Не забанит ли сайт бота, который будет парсить?
Так то я бы мог даже своим пользователям предложить как решение для парсинга любых сайтов и превращения их в канал :)
eyeofhell Автор
Парсить будет так часто, как прописать в исходном коде. В моем примере раз в минуту, но можно хоть раз в секунду.
Большинство сайтов отдают кешированную главную страницу очень быстро и их лишние запросы не парят. Но если есть сомнения — всегда можно написать владельцем сайта и вежливо спросить насколько часто их можно осматривать.