苹果推送通知:发送大量消息

18

我正在使用PHP连接到apn来向多个设备发送通知,尽管问题更多地是概念性的,因此不必具体限制在PHP上。

我将同时发送给约7000个设备(并且数量还在增长)。 我的进程每天运行一次,并向所有设备广播,因此我不会持续重新打开连接。

目前,我可以轻松地同时发送给2个设备,消息将成功传递。 但是,当我尝试发送到全部7000个设备时,似乎无法传递消息。

我的代码伪逻辑如下:

open connection to apple
loop over device-tokens
    write to socket connection per device
end loop
close connection to apple.
我看过某个地方说我只应该进行一次写入并构建一个巨大的主体,换句话说,伪代码将如下所示:
loop over device tokens
    create payload aggregating all devices
end loop
open connection to apple
write to socket ONCE with whole payload for 7000 devices
close connection

由于我显然不能向我的7000个生产用户发送测试消息,因此很难进行测试。 有其他人遇到过类似的问题吗?

谢谢


3
嗨,迈克。是的,我做过了。我在发布这个问题时的实现还处于相当早期阶段。问题是我把一些沙盒设备和生产设备放在同一个表中。有时候,如果你在使用生产证书时向沙盒设备令牌发送消息,苹果可能会断开连接。因此,简单的解决方法就是在每次写入事件后验证已正确写入的字节数,并确保连接未断开。如果断开了,你需要重新打开连接,并从上次离开的地方继续。祝好运! - BoomShaka
能否向多个设备广播推送消息? 我可以像您上面提到的那样聚合令牌并向所有设备发送一条消息吗? - Itay Levin
1
是的,这正是我在上面所做的。我将所有令牌收集到数据库表中,然后每周一次向所有设备发送相同的消息(甚至可以根据设备自定义消息)。但是,您需要为每个设备向APNS发送单独的有效载荷。因此,如果您有100个设备,那么就需要对套接字进行100次写入。 - BoomShaka
嗨 @BoomShaka!我遇到了同样的问题。你能发一下检查状态和重新连接的代码吗?我无法让它正常工作... - Julian F. Weinert
请查看这个问题:https://dev59.com/gmUq5IYBdhLWcg3wXvMC - Subodh Ghulaxe
显示剩余4条评论
2个回答

6
我读过苹果确实关注你与他们的服务器建立的连接数量,但我从未听说过任何写入限制。此外,我不确定您将在此处收到什么样的响应,但值得一试以查看发生了什么。也许可以尝试使用沙盒推送通知服务器,并仅使用生产设备的设备标记进行测试。这些手机不应接收发送到沙盒服务器的任何推送通知,如果沙盒报告“成功传送”,那将是一种无忧的测试方式。

迟来了很久,但你的答案基本上是正确的。谢谢 :) - BoomShaka
沙盒需要开发证书,生产环境需要生产证书。APNS文档说明,在开发环境中生成的设备令牌与生产环境完全不同。而且,如果APNS生产构建使用由开发构建直接生成的设备令牌,则会使设备令牌无效并断开连接。因此状态不会成功,但连接将被断开。为了测试,模拟APNS服务是一个更好的选择。 - Apurv Nerlekar

0

我明白你想要什么,而且我也曾遇到同样的问题,对我有用的是逆向工程。 我只是查看了库中验证设备令牌的函数。因此,在创建虚拟设备令牌时,我只需确保生成的令牌符合库的规范。

以下代码将让您生成有效的设备令牌,现在由您决定使用此函数生成多少百万个令牌。

   def generateRandomDeviceTokenAndAppendItToJson(tokenLength: Int) {
     val randomlyGeneratedDeviceToken = new StringBuilder()
      randomlyGeneratedDeviceToken.append("          \"")
        (1 to tokenLength) foreach {
         times: Int =>
        if (tokenLength equals Device.Apple)
         randomlyGeneratedDeviceToken.append(validCharacter().toString.charAt(0))
        else
         randomlyGeneratedDeviceToken.append(Random.alphanumeric.head)
        }
       randomlyGeneratedDeviceToken.append("\",")
       println(randomlyGeneratedDeviceToken)
       writer.write(randomlyGeneratedDeviceToken.toString())
      }

      private def validCharacter(): Int = {
       val a = Random.alphanumeric.head
       if ('0' <= a && a <= '9')
        return (a - '0')
       else if ('a' <= a && a <= 'f')
        return ((a - 'a') + 10)
       else if ('A' <= a && a <= 'F')
        return ((a - 'A') + 10)
       validCharacter() 
     }

苹果设备令牌(deviceToken)是64个字符,因此您需要迭代64次。


我怀疑这个能不能行。你可能已经反向工程了一个低级别的验证,它只是在某种程度上检查令牌的正确性。但这只是苹果防止垃圾邮件的第一道防线。我可以打赌一百万美元,你无法向随机设备令牌发送消息。苹果会很快关闭你的操作。即使在沙盒服务器上可以工作,这样的测试也不能证明任何东西。 - Csaba Toth
顺便问一句,这里没有验证吗?因为从你的代码来看,它似乎只是生成一个完全随机的64个十六进制字符长度的字符串。完全没有任何约束条件。 - Csaba Toth
同意Csaba Toth的观点,这确实生成了一个随机的64个字符长度的字符串,但是验证(请参见上面的有效字符函数)与apns在其端执行的验证相同(它让我分析令牌而不是在网络上找到它),并且它对我测试服务器性能非常有效。试试发送到apns,它会报告有效。 当然,它可能是实际生成的令牌,我们应该足够礼貌地将其发送到沙盒环境中,否则就像你说的那样,它会被视为垃圾邮件。 - Apurv Nerlekar
你说的“有效报告”是什么意思?仅仅因为APNS沙盒服务器消耗了它,并不意味着它是有效的。我认为APNS服务器的目标是消耗你扔给它的任何东西,否则会降低服务用户的性能。然后在幕后他们可能会拒绝该令牌。当你请求反馈时,这一切都将在实时APNS服务器中得到解决,你将收到无效/过期令牌列表。 - Csaba Toth
然而,也许这仍然可以用于测量您应用程序发送部分的性能,以衡量APNS发送库的性能。 - Csaba Toth
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接