2009-07-23 8 views
12

Sto tentando di inviare notifiche push a un iPhone utilizzando Python. Ho esportato il mio certificato e la chiave privata in un file P12 da accesso portachiavi e poi convertito in file PEM utilizzando il seguente comando:Connessione a APNS per iPhone con Python

openssl pkcs12 -in cred.p12 -out cert.pem -nodes -clcerts 

sto usando APNSWrapper in Python per la connessione.

ho eseguire il codice seguente:

 
deviceToken = 'Qun\xaa\xd ... c0\x9c\xf6\xca' 

# create wrapper 
wrapper = APNSNotificationWrapper('/path/to/cert/cert.pem', True) 

# create message 
message = APNSNotification() 
message.token(deviceToken) 
message.badge(5) 

# add message to tuple and send it to APNS server 
wrapper.append(message) 
wrapper.notify() 

E poi ho il messaggio di errore:

 
ssl.SSLError: (1, '_ssl.c:485: 
error:14094416:SSL routines:SSL3_READ_BYTES:sslv3 alert certificate unknown') 

Qualcuno mi può aiutare su questo?

+0

Quindi qual era il problema? Certificato o servizio? – JackLeo

risposta

8

Recentemente ho fatto questo utilizzando Django - http://leecutsco.de/2009/07/14/push-on-the-iphone/

può essere utile? Non sta facendo uso di librerie aggiuntive oltre a quelle già incluse in Python. Non ci vorrebbe molto per estrarre il metodo send_message().

+1

Suggerisco di inserire il contenuto nella risposta anziché nel collegamento. Alla fine il link potrebbe non essere aggiornato, nel qual caso altri potrebbero non beneficiare della risposta. –

+0

Come previsto da @Walty, il collegamento si è interrotto. Il nuovo link è http://leecutsco.de/2009/07/14/push-on-the-iphone/ - Sarebbe bello se il contenuto fosse in risposta. – johndodo

2

Avete considerato il pacchetto Twisted? Il codice di seguito è tratto dal here:

from struct import pack 
from OpenSSL import SSL 
from twisted.internet import reactor 
from twisted.internet.protocol import ClientFactory, Protocol 
from twisted.internet.ssl import ClientContextFactory 

APNS_SERVER_HOSTNAME = "<insert the push hostname from your iPhone developer portal>" 
APNS_SERVER_PORT = 2195 
APNS_SSL_CERTIFICATE_FILE = "<your ssl certificate.pem>" 
APNS_SSL_PRIVATE_KEY_FILE = "<your ssl private key.pem>" 

class APNSClientContextFactory(ClientContextFactory): 
    def __init__(self): 
     self.ctx = SSL.Context(SSL.SSLv3_METHOD) 
     self.ctx.use_certificate_file(APNS_SSL_CERTIFICATE_FILE) 
     self.ctx.use_privatekey_file(APNS_SSL_PRIVATE_KEY_FILE) 

    def getContext(self): 
     return self.ctx 

class APNSProtocol(Protocol): 
    def sendMessage(self, deviceToken, payload): 
     # notification messages are binary messages in network order 
     # using the following format: 
     # <1 byte command> <2 bytes length><token> <2 bytes length><payload> 
     fmt = "!cH32cH%dc" % len(payload) 
     command = 0 
     msg = struct.pack(fmt, command, deviceToken, 
          len(payload), payload) 
     self.transport.write(msg) 

class APNSClientFactory(ClientFactory): 
    def buildProtocol(self, addr): 
     print "Connected to APNS Server %s:%u" % (addr.host, addr.port) 
     return APNSProtocol() 

    def clientConnectionLost(self, connector, reason): 
     print "Lost connection. Reason: %s" % reason 

    def clientConnectionFailed(self, connector, reason): 
     print "Connection failed. Reason: %s" % reason 

if __name__ == '__main__': 
    reactor.connectSSL(APNS_SERVER_HOSTNAME, 
         APNS_SERVER_PORT, 
         APNSClientFactory(), 
         APNSClientContextFactory()) 
    reactor.run() 
+0

@coonj Hai provato con successo? Avete qualche esempio di utilizzo del codice per inviare messaggi? Grazie. – elioty

1

c'erano alcuni bug nel codice pubblicato originariamente, quindi ecco una versione corretta che funziona per me.

from struct import pack 
from OpenSSL import SSL 
from twisted.internet import reactor 
from twisted.internet.protocol import ClientFactory, Protocol 
from twisted.internet.ssl import ClientContextFactory 
import binascii 
import struct 

APNS_SERVER_HOSTNAME = "gateway.sandbox.push.apple.com" 
APNS_SERVER_PORT = 2195 
APNS_SSL_CERTIFICATE_FILE = "<your ssl certificate.pem>" 
APNS_SSL_PRIVATE_KEY_FILE = "<your ssl private key.pem>" 
DEVICE_TOKEN = "<hexlified device token>" 
MESSAGE = '{"aps":{"alert":"twisted test"}}' 

class APNSClientContextFactory(ClientContextFactory): 
    def __init__(self): 
     self.ctx = SSL.Context(SSL.SSLv3_METHOD) 
     self.ctx.use_certificate_file(APNS_SSL_CERTIFICATE_FILE) 
     self.ctx.use_privatekey_file(APNS_SSL_PRIVATE_KEY_FILE) 

    def getContext(self): 
     return self.ctx 

class APNSProtocol(Protocol): 

    def connectionMade(self): 
     print "connection made" 
     self.sendMessage(binascii.unhexlify(DEVICE_TOKEN), MESSAGE) 
     self.transport.loseConnection() 

    def sendMessage(self, deviceToken, payload): 
     # notification messages are binary messages in network order 
     # using the following format: 
     # <1 byte command> <2 bytes length><token> <2 bytes length><payload> 
     fmt = "!cH32sH%ds" % len(payload) 
     command = '\x00' 
     msg = struct.pack(fmt, command, 32, deviceToken, 
          len(payload), payload) 
     print "%s: %s" %(binascii.hexlify(deviceToken), binascii.hexlify(msg)) 
     self.transport.write(msg) 

class APNSClientFactory(ClientFactory): 
    def buildProtocol(self, addr): 
     print "Connected to APNS Server %s:%u" % (addr.host, addr.port) 
     return APNSProtocol() 

    def clientConnectionLost(self, connector, reason): 
     print "Lost connection. Reason: %s" % reason 

    def clientConnectionFailed(self, connector, reason): 
     print "Connection failed. Reason: %s" % reason 

if __name__ == '__main__': 
    reactor.connectSSL(APNS_SERVER_HOSTNAME, 
         APNS_SERVER_PORT, 
         APNSClientFactory(), 
         APNSClientContextFactory()) 
    reactor.run() 
0

Ho provato entrambi APNSWrapper e il codice di Lee Peckham e non poteva farlo funzionare sotto Snow Leopard con Python 2.6. Dopo un sacco di tentativi ed errori ha finalmente funzionato con pyOpenSSL.

Ho già fatto un post con dettagli e frammenti di codice here quindi ti rimando qui.

1

Provare ad aggiornare all'ultima versione di APNSWrapper (0.4). È ora disponibile il supporto integrato dello strumento da riga di comando openssl (openssl s_client).