多个iPhone APN消息,单个连接

San*_*aal 6 iphone push apple-push-notifications

我有一个奇怪的问题.我正在尝试使用Python推送Apple推送通知.我可以毫无问题地连接和发送单个邮件.当我开始发送多条消息时会弹出问题,但它甚至比这更奇怪.

我正在测试多种设备......一些iPhone和一些iPod Touch.我可以毫不费力地向iPhone发送多条消息,但如果我在列表中有一个iPod Touch设备ID,那么之后的任何消息都将失败.

所以,如果我按顺序发送4条消息,如下所示:

1 - iPhone
2 - iPhone
3 - ipod Touch
4 - iPhone

将交付1和2,3和4将失败.

使用相同的设备ID,如果我将任何iPod Touch设备ID移动为第一条消息,则所有消息都将失败.同样,如果我只发送到iPhone,所有消息都会成功.

这是我正在测试的代码,在它的当前状态下,我只会得到前两条消息,最后两条消息每次都会失败.

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()
Run Code Online (Sandbox Code Playgroud)

任何帮助,将不胜感激...

Mic*_*son 14

如果收到无效的设备令牌或消息太长,Apple将默默地断开连接.接下来的几条消息将失败,因为它们只是被发送到以太网,本质上 - 连接已关闭,但TCP窗口没有用完.

在我工作的Urban Airship,当人们通过我们的服务测试他们的应用程序时,我们有一个调试模式.这将在发送消息后暂停一点,以确保这不是问题 - 如果连接断开,我们知道这是设备令牌的问题并报告错误.类似的方法可能是一种很好的方法,可以检查这是或不是,正在发生的事情.显然这会导致吞吐量下降,因此我们不建议将其用于生产环境.

  • 嗨,迈克尔,您是否可以确认从设备卸载应用程序时不会发生此行为?在我们的初始测试中,如果用户卸载了应用程序,但设备令牌仍然在与其他活动令牌相同的连接中发送推送消息,则不会影响交付.我只是想知道我们是否可以对这种行为充满信心,或者我们是否需要以某种方式过滤掉未安装设备的令牌. (3认同)