2015-03-21 1 views
2

Я использую PyAPN для отправки уведомлений на устройства iOS. Я часто отправляю группы уведомлений сразу. Если какой-либо из токенов плохо по какой-либо причине, процесс остановится. В результате я использую расширенную настройку и следующий метод:PyAPNs и необходимость спать между сообщениями

apns.gateway_server.register_response_listener 

я использую это для отслеживания маркеров была проблемой, и я забрать оттуда отправку остального. Проблема в том, что при отправке единственного способа уловить эти ошибки - использовать таймер сна между отправителями токенов. Например:

for x in self.retryAPNList: 
    apns.gateway_server.send_notification(x, payload, identifier = token) 
    time.sleep(0.5) 

Если я не использую таймер сна ошибки не поймана, и, таким образом, весь мой список APN не отправляется, как процесс останавливается, когда есть плохой маркер. Однако этот таймер сна несколько произволен. Иногда достаточно 0,5 секунд, в то время как в другое время мне приходилось устанавливать его в 1. Ни в коем случае это не работало без добавления дополнительной задержки сна. Это замедляет веб-звонки, и он чувствует себя меньше, чем пуленепробиваемый, чтобы ввести случайное время сна.

Любые предложения по тому, как это может работать без задержки между вызовами APN или есть ли наилучшая практика для необходимой задержки?

Добавление дополнительного кода в соответствии с запросом, сделанным ниже. Вот 3 метода внутри класса, который я использую, чтобы управлять этим:

class PushAdmin(webapp2.RequestHandler): 

    retryAPNList=[] 
    channelID="" 
    channelName = "" 
    userName="" 

    apns = APNs(use_sandbox=True,cert_file="mycert.pem", key_file="mykey.pem", enhanced=True) 

    def devChannelPush(self,channel,name,sendAlerts): 
     ucs = UsedChannelStore() 
     pus = PushUpdateStore() 
     channelName = "" 
     refreshApnList = pus.getAPN(channel) 
     if sendAlerts: 
      alertApnList,channelName = ucs.getAPN(channel) 
      if not alertApnList: alertApnList=[] 
      if not refreshApnList: refreshApnList=[] 
      pushApnList = list(set(alertApnList+refreshApnList)) 
     elif refreshApnList: 
      pushApnList = refreshApnList 
     else: 
      pushApnList = [] 

     self.retryAPNList = pushApnList 
     self.channelID = channel 
     self.channelName = channelName 
     self.userName = name 
     self.retryAPNPush() 

    def retryAPNPush(self): 
     token = -1 
     payload = Payload(alert="A message from " +self.userName+ " posted to "+self.channelName, sound="default", badge=1, custom={"channel":self.channelID}) 

     if len(self.retryAPNList)>0: 
      token +=1 
      for x in self.retryAPNList: 
        self.apns.gateway_server.send_notification(x, payload, identifier = token) 
        time.sleep(0.5) 

Ниже класс вызова (сокращайте сократить непроизводительные связанные элементы):

class ChannelStore(ndb.Model): 
    def writeMessage(self,ID,name,message,imageKey,fileKey): 
     notify = PushAdmin() 

     notify.devChannelPush(ID,name,True) 

Ниже небольшое изменение, которое я сделанный для размещения таймера сна, который, похоже, решил проблему. Тем не менее, я все еще обеспокоен тем, будет ли предоставленное время правильной суммой при любых обстоятельствах.

def retryAPNPush(self): 
     identifier = 1 
     token = -1 
     payload = Payload(alert="A message from " +self.userName+ " posted to "+self.channelName, sound="default", badge=1, custom={"channel":self.channelID}) 

     if len(self.retryAPNList)>0: 
      token +=1 
      for x in self.retryAPNList: 
       self.apns.gateway_server.send_notification(x, payload, identifier = token) 
      time.sleep(0.5) 

Разрешение:

Как отмечалось в комментариях в нижней части, решение этой проблемы было перенести следующее заявление уровне модуля вне класса. Делая это, нет необходимости в каких-либо операциях сна.

apns = APNs(use_sandbox=True,cert_file="mycert.pem", key_file="mykey.pem", enhanced=True) 
+0

это один из вкладчика, могу я увидеть более завершенный фрагмент кода? в том числе, как создается apns, как обрабатывается retryAPNList, чтобы исследовать проблему, спасибо :) –

+0

Спасибо за ваш ответ. Я добавил еще немного кода в мой OP выше. – C6Silver

ответ

1

В самом деле, PyAPNS будет автоматически повторная отправка упала уведомление для вас, пожалуйста, см PyAPNS

Так что вам не придется повторять самостоятельно, вы можете просто записывать то, что уведомления плохих маркеры.

Поведение вашего кода может быть результатом объекта APNS хранится в локальной области (в пределах if len(self.retryAPNList)>0:)

Я предлагаю вам вытащить объект APNS для класса или уровня модуля, так что он может завершить процедуру обработки ошибок и повторно использовать TCP-соединение.

Пожалуйста, любезно дайте мне знать, если это помогает, спасибо :)

+0

Вы правы, что я могу удалить слушателя из перспективы повторной отправки. Тем не менее, процесс по-прежнему не работает без добавления задержки сна.По вашему предложению я переместил объект APNS на уровень класса и, следовательно, после оператора if, с которым вы ссылаетесь, я называю его «self.apns». Результат будет таким же без введения задержки. Я тестирую 2 токена, первый плохой и второй хороший. Без задержки добавляется второй токен, который никогда не отправляется, поскольку он зацикливается на первом. Когда я добавляю задержку, вторая отправляется очень быстро. – C6Silver

+0

@ C6Silver Можете ли вы отправить журнал? Спасибо :) –

+0

и весь код, включая способ вызова класса? Спасибо :) –