2012-12-07 233 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個設備進行了測試。 –

相關問題