Прежде, чем я продолжу, должен предупредить о plug-n-play сервисах предоставляющих отправку push уведомлений, если вы желаете платить им (Parse, mobDB, Pushwoosh, Urban Airship, etc.), но это не путь война. Давайте сделаем это сами, с нуля (и бесплатно) (на самом деле — не так уж и с нуля, но платить никому не придется).
Если ты хочешь сделать яблочный пирог с нуля, то сначала создай вселенную
Карл Саган
Вот три компонента, которые играют важную роль в нашей системе доставки push уведомлений:
- API метод для получения токенов мобильных устройств
- Worker — постоянно подключен к серверам Apple/Google и следит за очередью в Redis
- Код, который, по факту, отправляет сообщения в очередь
Прежде всего надо спросить пользователя, хочет ли он принимать push уведомления (золотые слова) и если пользователь согласиться — отправить device token (не знаю как перевести, думаю device token будет понятно всем). Их (device token) мы будем сохранять в простую модель ActiveRecord, которую назовем Device
# Schema Information # Table name: devices # id :integer not null, primary key # user_id :integer # token :string(255) # enabled :boolean default(TRUE) # created_at :datetime not null # updated_at :datetime not null # platform :string(255) class Device < ActiveRecord::Base attr_accessible :enabled, :token, :user, :platform belongs_to :user validates_uniqueness_of :token, :scope => :user_id end
Экземпляры Device (записи в базу) должны создаваться когда приложение вызывает соответствующий API метод
resource :devices do post do @device = Device.create(user: current_user, token: params[:token], platform: params[:platform]) present @device, with: WellWithMe::Entities::Device end end
Используем модель Notification из Redis в качестве очереди
class NotificationSender @queue = :notifications def self.perform @list = Redis::List.new(Notification.key_name) while notification = @list.pop do notification_json = JSON.parse(notification) if notification_json['platform'] == 'iOS' note = Grocer::Notification.new( device_token: notification_json['token'], alert: notification_json['message'], sound: 'default', badge: 0 ) PUSHER.push(note) elsif notification_json['platform'] == 'Android' gcm = GCM.new(ENV['gcm_key']) registration_id = [notification_json['token']] options = { 'data' => { 'message' => notification_json['message'] }, 'collapse_key' => 'updated_state' } response = gcm.send_notification(registration_id, options) end end end end
NotificationSender читает задачи из очереди при этом постоянно поддерживает соединение с серверами, не пытаясь устанавливать новые соединения для отправки каждого push уведомления, чему Apple активно препятствует: заметка Apple о соединения с серверами push уведомлений
Данный код отрабатывает каждую минуту, проверяя очередь уведомлений Redis и отсылая push уведомления на устройства.
Были использованы замечательные джемы grocer для iOS и GCM для Android. Оба джема прекрасно работают и очень хорошо документированы. Единственно ограничение состоит в том, что вы должны создать сертификаты для iOS и правильно их экспортировать — просто следуйте инструкциям от Apple.
Теперь у Вас есть легко расширяемая система отправки Push уведомлений. Push уведомления помогут увеличить число Ваших пользователей, но не злоупотребляйте ими, иначе возникнет обратный эффект
А переводчик пойдет писать свой костыль почти в том же духе, только выкинув Redis и добавив Windows Phone
ссылка на оригинал статьи http://habrahabr.ru/post/214607/
Добавить комментарий