Tengo un problema extraño. Estoy intentando que Apple Push Notifications funcione con Python. Puedo conectar y enviar mensajes individuales sin ningún problema. Los problemas aparecen cuando comienzo a enviar más de un mensaje, pero es más extraño que eso.Múltiples mensajes de iPhone APN, conexión única
Estoy probando con varios dispositivos ... algunos iPhones y algunos iPod Touch. Puedo enviar múltiples mensajes a los iPhones sin problemas, pero si tengo una identificación de dispositivo iPod Touch en la lista, cualquier mensaje que ocurra fallará.
Así que si envío 4 mensajes en secuencia como esta:
1 - iPhone
2 - iPhone
3 - iPod Touch
4 - iPhone
1 y 2 serán entregados, 3 y 4 fallan
Usando las mismas ID de dispositivo, si muevo cualquiera de las ID del dispositivo iPod Touch para que sea el primer mensaje, todos los mensajes fallarán. Del mismo modo, si solo envío a iPhones, todos los mensajes tendrán éxito.
Aquí está el código que estoy probando, en su estado actual, solo recibiría los dos primeros mensajes, los dos últimos fallarán siempre.
import struct, ssl, json, sys, time, socket, binascii
from optparse import OptionParser
class PushSender(object):
def __init__(self, host, cert, key):
self.apnhost = (host, 2195)
self.sock = ssl.wrap_socket(socket.socket(socket.AF_INET, socket.SOCK_STREAM),
keyfile = key,
certfile = cert,
do_handshake_on_connect=False)
self.sock.connect(self.apnhost)
while True:
try:
self.sock.do_handshake()
break
except ssl.SSLError, err:
if err.args[0] == ssl.SSL_ERROR_WANT_READ:
select.select([self.sock], [], [])
elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
select.select([], [self.sock], [])
else:
raise
def send_message(self, token, message):
payload = {'aps':{'alert':message}}
token = binascii.unhexlify(token)
payloadstr = json.dumps(payload, separators=(',',':'))
payloadLen = len(payloadstr)
fmt = "!BH32sH%ds" % payloadLen
notification = struct.pack(fmt, 0, 32, token, payloadLen, payloadstr)
self.sock.write(notification)
self.sock.
def close(self):
self.sock.close()
def main():
parser = OptionParser()
parser.add_option("-c", "--certificate", dest="cert",
metavar="FILE",
help="Certificate file",)
parser.add_option("-p", "--privatekey", dest="key",
metavar="FILE",
help="Key file",)
parser.add_option("--host", help="apn host", dest='host')
(options, args) = parser.parse_args()
sender = PushSender(options.host, options.cert, options.key)
iphone1 = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
print 'Sending iPhone #1 a message.'
print sender.send_message(iphone1,'Hey iPhone #1.')
iphone2 = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
print 'Sending iPhone #2 a message.'
print sender.send_message(iphone2,'Hey iPhone #2.')
ipod1 = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
print 'Sending iPod #1 a message.'
print sender.send_message(ipod1,'Hey iPod #1.')
iphone3 = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
print 'Sending iPhone #3 a message.'
print sender.send_message(iphone3,'Hey iPhone #3.')
sender.close()
if __name__=="__main__":
main()
Cualquier ayuda se agradece ...
Michael, gracias por la respuesta detallada, sospecho que tiene razón. Este problema se debió al hecho de que estábamos almacenando todos los tokens de dispositivo de un usuario en un intento de admitir varios dispositivos por usuario, ya que estábamos adjuntando un token de dispositivo a un ID de usuario en lugar de un ID de dispositivo único, presentamos la posibilidad de se almacenan tokens inválidos ya que un token de dispositivo puede cambiar. – Sangraal
Además, gracias por sugerir una forma en que puedo probar los tokens que ya tenemos para la validez, ese fue otro problema que me preocupaba. Me he dado cuenta al enviar muchos mensajes con un token de dispositivo no válido primero, la conexión soltaría algunos mensajes más tarde. Ese es el comportamiento que describes arriba. – Sangraal
También debo agregar que Apple considera que un token de dispositivo de desarrollo enviado a un servidor de producción es un token de dispositivo no válido (y viceversa). Este problema aparece con bastante frecuencia, entonces, si mezcla tokens de dispositivo de desarrollo y tokens de dispositivo de producción. Espero que esto ayude! –