Push-уведомления с PushSharp - основы
Мне нужно нажать уведомления на десятки тысяч устройств iOS, которые установили мое приложение. Я пытаюсь сделать это с помощью PushSharp, но здесь мне не хватает фундаментальных понятий. Сначала я попытался запустить это в службе Windows, но не смог заставить его работать - получить нулевые ссылочные ошибки, исходящие из вызова _push.QueueNotification(). Затем я сделал именно то, что сделал документальный образец кода, и он работал:
PushService _push = new PushService();
_push.Events.OnNotificationSendFailure += new ChannelEvents.NotificationSendFailureDelegate(Events_OnNotificationSendFailure);
_push.Events.OnNotificationSent += new ChannelEvents.NotificationSentDelegate(Events_OnNotificationSent);
var cert = File.ReadAllBytes(HttpContext.Current.Server.MapPath("..pathtokeyfile.p12"));
_push.StartApplePushService(new ApplePushChannelSettings(false, cert, "certpwd"));
AppleNotification notification = NotificationFactory.Apple()
.ForDeviceToken(deviceToken)
.WithAlert(message)
.WithSound("default")
.WithBadge(badge);
_push.QueueNotification(notification);
_push.StopAllServices(true);
Проблема №1:
Это работает отлично, и я вижу, что уведомление появляется на iPhone. Однако, поскольку он назывался Push-сервисом, я предположил, что он будет вести себя как услуга - это значит, я создаю экземпляр и вызываю _push.StartApplePushService() в службе Windows, возможно. И я подумал, что на самом деле очередь моих уведомлений, я мог бы сделать это в интерфейсе (приложение администратора, скажем):
PushService push = new PushService();
AppleNotification notification = NotificationFactory.Apple()
.ForDeviceToken(deviceToken)
.WithAlert(message)
.WithSound("default")
.WithBadge(badge);
push.QueueNotification(notification);
Очевидно (и, как я уже сказал), это не сработало - последняя строка продолжала бросать исключение с нулевой ссылкой.
У меня возникли проблемы с поиском какой-либо другой документации, которая бы показывала, как настроить это на основе сервиса/клиента (а не просто называть все сразу). Возможно ли, или я не могу понять, как использовать PushSharp?
Проблема №2:
Кроме того, я не могу найти способ нацеливаться на многие токены устройства одновременно, не зацикливая их и не ставя в очередь уведомления по одному за раз. Это единственный способ или я тоже что-то упустил?
Спасибо заранее.
Ответы
Ответ 1
@baramuse объяснил все это, если вы хотите увидеть сервисный "процессор", вы можете просмотреть мое решение на https://github.com/vmandic/DevUG-PushSharp, где я реализовал рабочий процесс, к которому вы стремитесь, т.е. службу выигрыша, win-процессор или даже веб-api ad hoc-процессор с использованием одного и того же ядра процессор.
Ответ 2
Из того, что я прочитал и как я его использую, ключевое слово "Сервис" может ввести вас в заблуждение...
Это сервис, который вы настраиваете один раз и запускаете его.
С этого момента он будет ждать, пока вы введете новые уведомления внутри своей очереди, и это вызовет события, как только что-то произойдет (отчет о доставке, ошибка доставки...). Он асинхронный, и вы можете нажать (= queue) 10000 уведомлений и дождаться, когда результаты вернутся позже, используя обработчики событий.
Но все же это обычный экземпляр объекта, который вам нужно будет создать и получить как обычный. Он не предоставляет никакого "внешнего прослушивателя" (например, http/tcp/ipc connection), вам нужно будет его создать.
В моем проекте я создал небольшой веб-сервис, основанный на самообслуживании (полагающийся на ServiceStack), который заботится о времени жизни конфигурации и экземпляра, но только предоставляет функцию SendNotification.
И о Проблема № 2, на самом деле не существует "пакетной очереди", но по мере того, как функция очереди возвращается сразу (в очередь и нажимать позже), это просто вопрос цикла в вашу список токенов устройства...
public void QueueNotification(Notification notification)
{
if (this.cancelTokenSource.IsCancellationRequested)
{
Events.RaiseChannelException(new ObjectDisposedException("Service", "Service has already been signaled to stop"), this.Platform, notification);
return;
}
notification.EnqueuedTimestamp = DateTime.UtcNow;
queuedNotifications.Enqueue(notification);
}