多条 iPhone APN 消息,单一连接
Posted
技术标签:
【中文标题】多条 iPhone APN 消息,单一连接【英文标题】:Multiple iPhone APN messages, single connection 【发布时间】:2009-11-18 21:08:12 【问题描述】:我有一个奇怪的问题。我正在尝试让 Apple Push Notifications 与 Python 一起使用。我可以毫无问题地连接和发送个人消息。当我开始发送多条消息时,问题就会出现,但比这更奇怪。
我正在使用多种设备进行测试……一些 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()
任何帮助将不胜感激......
【问题讨论】:
【参考方案1】:如果收到无效的设备令牌或过长的消息,Apple 将静默断开您的连接。之后的下几条消息将失败,因为它们只是被发送到以太网中,本质上 - 连接已关闭,但 TCP 窗口并未耗尽。
在我工作的 Urban Airship,当人们通过推送我们的服务来测试他们的应用程序时,我们可以使用调试模式。在发送消息以确保这不是问题后,这将暂停一会儿 - 如果连接断开,我们知道这是设备令牌的问题并报告错误。类似的方法可能是您检查是否正在发生的事情的好方法。显然这会降低吞吐量,因此我们不建议将其用于生产环境。
【讨论】:
迈克尔,感谢您的详细回复,我怀疑您是正确的。这个问题源于我们存储所有用户的设备令牌以尝试支持每个用户的多个设备,因为我们将设备令牌附加到用户 ID 而不是唯一的设备 ID,我们引入了无效令牌的可能性由于设备令牌可以更改而被存储。 另外,感谢您提出一种方法来测试我们已经拥有的令牌的有效性,这是我担心的另一个问题。我注意到,当首先发送许多带有无效设备令牌的消息时,连接会在稍后断开一些消息。这就是您在上面描述的行为。 我还应该补充一点,Apple 将发送到生产服务器的开发设备令牌视为无效设备令牌(反之亦然)。如果您将开发设备令牌和生产设备令牌混合使用,则此问题经常出现。希望这会有所帮助! 我们的问题得到了解决,原来我们有一些开发 ID 存储在我们的生产数据库中,导致了这种行为。 嗨,Michael,您能否确认从设备上卸载应用程序时不会发生这种行为?在我们的初始测试中,如果用户卸载了应用程序,但设备令牌仍然与其他活动令牌在同一连接中发送推送消息,则不影响交付。我只是想知道我们是否可以对这种行为充满信心,或者我们是否需要以某种方式过滤掉已卸载设备的令牌。以上是关于多条 iPhone APN 消息,单一连接的主要内容,如果未能解决你的问题,请参考以下文章