如何向多个设备(iOS)发送推送通知?
Posted
技术标签:
【中文标题】如何向多个设备(iOS)发送推送通知?【英文标题】:How to send a push notification to more than one device (iOS)? 【发布时间】:2012-12-07 15:05:05 【问题描述】:我正在尝试优化我服务器上的推送通知。现在我一个一个地发送那些(带有一个旧图书馆),这需要一段时间(4小时)。
我重构了我的服务以发送带有大量设备令牌的通知(现在我尝试批量处理 500 个令牌)。为此,我正在使用Redth/PushSharp 库。我关注了sample code,然后我对其进行了调整以将通知发送到多个设备令牌。
PushService service = new PushService();
//Wire up the events
service.Events.OnDeviceSubscriptionExpired += new PushSharp.Common.ChannelEvents.DeviceSubscriptionExpired(Events_OnDeviceSubscriptionExpired);
service.Events.OnDeviceSubscriptionIdChanged += new PushSharp.Common.ChannelEvents.DeviceSubscriptionIdChanged(Events_OnDeviceSubscriptionIdChanged);
service.Events.OnChannelException += new PushSharp.Common.ChannelEvents.ChannelExceptionDelegate(Events_OnChannelException);
service.Events.OnNotificationSendFailure += new PushSharp.Common.ChannelEvents.NotificationSendFailureDelegate(Events_OnNotificationSendFailure);
service.Events.OnNotificationSent += new PushSharp.Common.ChannelEvents.NotificationSentDelegate(Events_OnNotificationSent);
service.Events.OnChannelCreated += new PushSharp.Common.ChannelEvents.ChannelCreatedDelegate(Events_OnChannelCreated);
service.Events.OnChannelDestroyed += new PushSharp.Common.ChannelEvents.ChannelDestroyedDelegate(Events_OnChannelDestroyed);
//Configure and start ApplePushNotificationService
string p12Filename = ...
string p12FilePassword = ...
var appleCert = File.ReadAllBytes(p12Filename);
service.StartApplePushService(new ApplePushChannelSettings(true, appleCert, p12FilePassword));
var appleNotification = NotificationFactory.Apple();
foreach (var itemToProcess in itemsToProcess)
itemToProcess.NotificationDateTime = DateTime.Now;
mobile.SubmitChanges();
string deviceToken = GetCleanDeviceToken(itemToProcess.MobileDevice.PushNotificationIdentifier);
appleNotification.ForDeviceToken(deviceToken);
service.QueueNotification(appleNotification
.WithAlert(itemsToProcess[0].MobileDeviceNotificationText.Text)
.WithSound("default")
.WithBadge(0)
.WithCustomItem("View", itemsToProcess[0].Value.ToString()));
//Stop and wait for the queues to drains
service.StopAllServices(true);
然后我尝试向 2 台设备发送 3 条通知。只有第一个设备得到了它们(问题与设备无关,因为我分别尝试了它们)。 紧接着在PushChannelBase class 中抛出一个 OperationCanceledException。所以我不知道怎么了。有什么想法吗?
【问题讨论】:
嗨。这可以在单个请求中将单个推送消息发送到多个设备。我进行了研发并实现了代码,并在 5-10 台设备上进行了测试。 【参考方案1】:您应该为每个要处理的项目排队单独的通知。 无法在单个通知上设置多个设备令牌。 OperationCanceledException 将会发生,因为您这样做了。
【讨论】:
嗨。这可以在单个请求中将单个推送消息发送到多个设备。我进行了研发并实现了代码,并在 5-10 台设备上进行了测试。【参考方案2】:示例:控制台 C# 应用程序
假设
-
您有有效的生产和开发证书
您已在数据库中存储了多个设备令牌
您有来自数据库的通知
您正在使用PushSharp 库
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PushSharp;
using PushSharp.Core;
using PushSharp.Apple;
using System.IO;
namespace MyNotification
class Program
//args may take "true" or "false" to indicate the app is running for
//development or production (Default = false which means Development)
static void Main(string[] args)
bool isProduction = false;
if (args != null && args.Length == 1)
Console.Write(args[0] + Environment.NewLine);
bool.TryParse(args[0], out isProduction);
try
//Gets a notification that needs sending from database
AppNotification notification = AppNotification.GetNotification();
if (notification != null && notification.ID > 0)
//Gets all devices to send the above notification to
List<iosDevice> devices = IosDevice.GetDevices(!isProduction);
if (devices != null && devices.Count > 0)
PushBroker push = new PushBroker();//a single instance per app
//Wire up the events for all the services that the broker registers
push.OnNotificationSent += NotificationSent;
push.OnChannelException += ChannelException;
push.OnServiceException += ServiceException;
push.OnNotificationFailed += NotificationFailed;
push.OnDeviceSubscriptionExpired += DeviceSubscriptionExpired;
push.OnChannelCreated += ChannelCreated;
push.OnChannelDestroyed += ChannelDestroyed;
//make sure your certifcates path are all good
string apnsCertFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "../../Certificate/Certificates_Apple_Push_Production.p12");
if (!isProduction)
apnsCertFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "../../Certificate/Certificates_Apple_Push_Development.p12");
var appleCert = File.ReadAllBytes(apnsCertFile);
push.RegisterAppleService(new ApplePushChannelSettings(isProduction, appleCert, "135TrID35")); //Extension method
foreach (IosDevice device in devices)
//if it is required to send additional information as well as the alert message, uncomment objects[] and WithCustomItem
//object[] obj = "North", "5" ;
push.QueueNotification(new AppleNotification()
.ForDeviceToken(device.DeviceToken)
.WithAlert(DateTime.Now.ToString())//(notification.AlertMessage)
//.WithCustomItem("Link", obj)
.WithBadge(device.BadgeCount + 1)
.WithSound(notification.SoundFile));//sound.caf
push.StopAllServices(waitForQueuesToFinish: true);
Console.WriteLine("Queue Finished, press return to exit...");
Console.ReadLine();
catch (Exception ex)
Console.WriteLine(ex.Message);
Console.ReadLine();
static void NotificationSent(object sender, INotification notification)
Console.WriteLine("Sent: " + sender + " -> " + notification);
static void NotificationFailed(object sender, INotification notification, Exception notificationFailureException)
Console.WriteLine("Failure: " + sender + " -> " + notificationFailureException.Message + " -> " + notification);
static void ChannelException(object sender, IPushChannel channel, Exception exception)
Console.WriteLine("Channel Exception: " + sender + " -> " + exception);
static void ServiceException(object sender, Exception exception)
Console.WriteLine("Service Exception: " + sender + " -> " + exception);
static void DeviceSubscriptionExpired(object sender, string expiredDeviceSubscriptionId, DateTime timestamp, INotification notification)
Console.WriteLine("Device Subscription Expired: " + sender + " -> " + expiredDeviceSubscriptionId);
static void ChannelDestroyed(object sender)
Console.WriteLine("Channel Destroyed for: " + sender);
static void ChannelCreated(object sender, IPushChannel pushChannel)
Console.WriteLine("Channel Created for: " + sender);
【讨论】:
有没有一种方法可以在没有 for each 循环的情况下向多个设备发送推送通知?比如批量推送?一下子.. 这会进行批量推送,for each 循环只是将设备添加到推送队列中。我在生产中使用它并且像魅力一样工作:) 嗨。这可以在单个请求中将单个推送消息发送到多个设备。我进行了研发并实现了代码,并在 5-10 台设备上进行了测试。 @V.J.你能解释一下你是怎么做到的吗?截至目前(2021 年 7 月),没有已知的 APNS 接口。解释你是如何做到的(不使用某种循环)。以上是关于如何向多个设备(iOS)发送推送通知?的主要内容,如果未能解决你的问题,请参考以下文章