开发者

Python APNs does not process request

I'm trying to implement a server side script for sending push notifications to apple push notification server. I create the ssl connection, I send the payload - but am unable to get a response from the APNs. Here is my code:

import socket, ssl, pprint, struct, time, binascii

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# require a certificate from the server
ssl_sock = ssl.wrap_socket( s,
                            keyfile="/Users/Jeff/Desktop/pickmeup-key2-noenc.pem",
                            certfile="/Users/Jeff/Desktop/pickmeup-cert2.pem",
                            server_side=False,
                            do_handshake_on_connect=True,
                            cert_reqs=ssl.CERT_REQUIRED,
                            ca_certs="/Users/Jeff/Desktop/entrustrootcert.pem",)
                            #ciphers="ALL")
ssl_sock.connect(('gateway.sandbox.push.apple.com', 2195))

print repr(ssl_sock.getpeername())
print ssl_sock.cipher()
print pprint.pformat(ssl_sock.getpeercert())

command = '\x00'
identifier = 1987
expiry = time.time()
deviceToken = "9858d81caa236a86cc67d01e1a07ba1df0982178dd7c95aae115d033b93cb3f5"
alert = "This is a test message"
sound = "UILocalNotificationDefaultSoundName"
payload = "{\"aps\":{\"alert\":\"%s\",\"sound\":\"%s\"}}" %(alert, sound)

packetFormat = "!cIIH%dsH%ds" %(32, len(payload))

packet = struct.pack(packetFormat, 
                    command, 
                    identifier,
                    int(expiry),
                    32, 
                    binascii.unhexlify(deviceToken), 
                    len(payload), 
                    payload)
nBytesWritten = ssl_sock.write(packet)
print "nBytesWritten = %d" %(nBytesWritten)

data = ssl_sock.read(1024)
print len(data)

ssl_sock.close()

Running this script, I generate the following output:

('17.149.34.132', 2195)
('AES256-SHA', 'TLSv1/SSLv3', 256)
{'notAfter开发者_如何学编程': 'May 31 00:04:27 2012 GMT',
 'subject': ((('countryName', u'US'),),
             (('stateOrProvinceName', u'California'),),
             (('localityName', u'Cupertino'),),
             (('organizationName', u'Apple Inc'),),
             (('organizationalUnitName', u'Internet Services'),),
             (('commonName', u'gateway.sandbox.push.apple.com'),))}
nBytesWritten = 133
0

Any ideas on what might be going wrong? (I am sending enhanced push notifications so I am expecting a response from apple push notification server)


The key thing to note is that read() is returning no data. In Python, read() is supposed to block until data is available or the connection closes. Apple is closing your connection.

Why? Well, probably because you sent a malformed request. command=0 is a normal push notification; command=1 is enhanced. The big-endian 1987 will be interpreted as a 0-byte device token and a 1987-byte payload, neither of which are valid.

(And FWIW, I'd use B instead of c for the command ID; it seems to make more sense.)


you may consider https://github.com/djacobs/PyAPNs that wrapped lot of useful features, including:

  • error handling
  • support enhanced message format and auto resend messages which are sent before error response
  • non-blocking ssl socket connection with great performance


Apple Push notification server doesn't give a response, it's a one-way binary socket. Rather than rolling your own solution you could try apns-python-wrapper or apns

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜