3

I have configured my iOS application with Apple Push Notification (APN) service enabled. I was able to send notifications to devices with PHP and Python 3 scripts. I tested both on local server with local machine. But now I need to write the script in Python2.

Below is the script I've written and when I run this I get nothing. Neither a notification to my device nor error in command line.

import socket, ssl, json, struct
import binascii
import os

deviceToken = 'my_device_tocken_without_spaces' 

thePayLoad = {
     'aps': {
          'alert':'My first push notification!',
          'sound':'default'
          }
     }

theCertfile = 'ck3_2.pem'

theHost = ( 'gateway.sandbox.push.apple.com', 2195 )

data = json.dumps( thePayLoad )

theFormat = '!BH32sH%ds' % len(data)

theNotification = struct.pack( theFormat, 0, 32, deviceToken, len(data), data )

ssl_sock = ssl.wrap_socket( socket.socket( socket.AF_INET, socket.SOCK_STREAM ), certfile = theCertfile )

ssl_sock.connect( theHost )

ssl_sock.write( theNotification )

ssl_sock.close()

What did I miss? How can I check where is the mistake happen?

I ran PHP script in localhost using XAMPP and I ran Python script in command line because I was unable to set-up Python with XAMPP which I already posted a question here.

Community
  • 1
  • 1
AnujAroshA
  • 4,623
  • 8
  • 56
  • 99

3 Answers3

2

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
Jim Horng
  • 1,587
  • 1
  • 13
  • 23
0

I think there's nothing wrong with your code. You can try adding following lines after ssl_sock.connect( theHost )

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

Which will print information about ssl of your connection.

Alternatively you can create a sample server and change the connections in your client and test against the server. http://carlo-hamalainen.net/blog/2013/1/24/python-ssl-socket-echo-test-with-self-signed-certificate

Gihan
  • 4,163
  • 6
  • 31
  • 49
  • Yes, you are correct. The code is almost correct and it runs inside the remote server but not local machine. Anyway the error that gives when trying to run in a local machine is `File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py", line 333, in connect self._real_connect(addr, False) File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py", line 314, in _real_connect self.ca_certs, self.ciphers) ssl.SSLError: [Errno 336265218] _ssl.c:351: error:140B0002:SSL routines:SSL_CTX_use_PrivateKey_file:system lib` – AnujAroshA Dec 17 '14 at 07:10
  • Is your certificate file path is correct? or has access rights?. I found similar error http://stackoverflow.com/a/6806097/625144 – Gihan Dec 19 '14 at 17:40
0

You imported binascii, but you forgot to use it. Convert the token and json data to byte arrays, e.g.:

deviceToken = binascii.a2b_hex('my_device_tocken_without_spaces')

and

data = json.dumps(thePayLoad, separators=(',', ':'), ensure_ascii=False).encode('utf-8')
Hans Terje Bakke
  • 1,412
  • 12
  • 14