2009-07-23 7 views
12

Я пытаюсь отправить push-уведомления на iPhone с помощью Python. Я экспортировала свой сертификат и закрытый ключ в p12 файл из брелка доступа, а затем превратила его в PEM файл с помощью следующей команды:Подключение к APNS для iPhone с использованием Python

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

Я использую APNSWrapper в Python для подключения.

я запускаю следующий код:

 
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() 

И тогда я получаю сообщение об ошибке:

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

Может кто-нибудь помочь мне в этом?

+0

Так в чем была проблема? Сертификат или услуга? – JackLeo

ответ

8

Недавно я сделал это с помощью Django - http://leecutsco.de/2009/07/14/push-on-the-iphone/

Может быть полезно? Он уже не использует никаких дополнительных библиотек, кроме тех, которые включены в Python. Не потребовалось бы многого для извлечения метода send_message().

+1

Я предлагаю поместить контент в ответ вместо ссылки. В конце концов ссылка может устареть, и в этом случае другие могут не получить ответ. –

+0

Так же, как предсказал @Walty, ссылка сломалась. Новая ссылка - http://leecutsco.de/2009/07/14/push-on-the-iphone/ - было бы неплохо, если бы контент был в ответе. – johndodo

2

Вы рассматривали пакет Twisted? Ниже код взят из 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 Вы пробовали это с успехом? Есть ли у вас примеры использования кода для отправки сообщений? Спасибо. – elioty

1

было обнаружено несколько ошибок в первоначально опубликованном коде, так что это исправленная версия, которая работает для меня.

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

Я попытался как APNSWrapper и код Ли Пекхэма и не мог заставить его работать под Snow Leopard с Python 2.6. После большого количества проб и ошибок он, наконец, работал с pyOpenSSL.

Я уже сделал сообщение с подробностями и фрагментами кода here, поэтому я просто отправлю вас туда.

1

Попробуйте обновить до последней версии APNSWrapper (0.4). Теперь есть встроенная поддержка инструмента командной строки openssl (openssl s_client).