2012-12-07 181 views
2

我试图优化我的服务器上的推送通知。现在我把它们一个接一个送出去(有一个老图书馆),需要一段时间(4小时)。如何将推送通知发送到多个设备(iOS)?

我重构了我的服务来发送一个带有很多设备标记的通知(现在我尝试了一批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); 

然后我试着发送3个通知给2个设备。只有第一个设备得到了它们(问题与设备无关,因为我试图单独使用它们)。 之后,在PushChannelBase class中抛出了OperationCanceledException。所以我不知道什么是错的。任何想法?

+0

嗨。这可以通过单个请求将单个推送消息发送到多个设备。我进行了研发并实施了代码,并使用5-10个设备进行了测试。 –

回答

3

您应该为要处理的每个项目排队一个单独的通知。
无法在单个通知上设置多个设备令牌。 OperationCanceledException将会发生,因为你这样做。

+0

拯救你! – Arjan

+0

嗨。这可以通过单个请求将单个推送消息发送到多个设备。我进行了研发并实施了代码,并使用5-10个设备进行了测试。 –

1

例如:控制台C#应用程序

这是假设

  1. 你有效的生产和开发证书
  2. 您已在数据库中存储多个设备令牌
  3. 你有一个通知来自您的数据库
  4. 您正在使用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); 
         } 
        } 
    
    } 
    
+0

有没有办法将推送通知发送给几个设备,而不是每个循环?如批量推送?所有一次.. – 2014-06-02 14:48:52

+0

这是一个批量推,每个循环只是添加设备到推队列。我在生产上使用它,像一个魅力:) – user890255

+0

嗨。这可以通过单个请求将单个推送消息发送到多个设备。我进行了研发并实施了代码,并使用5-10个设备进行了测试。 –

相关问题