如何可靠,高效地读取Java Server中Apple推送通知服务器的所有错误响应?

我正在研究Java中的Apple推送通知的服务器端开发。 我正在使用增强格式,以便检测失败的消息并重新发送跟踪错误消息的消息。 我知道Apple不保证Push Notifications的发送,但我希望能够知道Apple是否收到了我的消息以及是否包含任何错误。

我注意到当我尝试向Apple发送无效消息(无效设备令牌,太大的有效负载等等)时,我可以在套接字关闭之前发送更多消息。 当套接字关闭时,从Apple读取错误代码为时已晚,所以我不知道哪条消息是坏消息(或者即使有错误的消息,因为Apple说连接可能偶尔会关闭,即使没有错误)。

我在JavaPNs源中看到的处理此问题的方法是在发送每条消息(或消息组)后立即读取Apple的响应。 如果频繁执行则从套接字读取,并在没有任何内容可读的情况下等待超时。 如果您不经常发送推送通知,这是可以接受的。

如果您尝试以高频率发送大量通知(比方说每秒数百个),则无法在每条消息之后停止等待来自Apple的响应(即使您等待的响应时间仅为20毫秒,限制你每秒50条消息,你无法知道Apple写错误响应需要多长时间,所以短暂的等待可能还不够。 如果您在每条消息之后没有停止阅读可能的错误,那么在向Apple发送消息期间您的连接可能会被关闭,在这种情况下,您将无法获得导致连接关闭的消息的ID 。

我正在考虑的另一种方法是在单独的线程中执行读取和写入。 通过这种方式,我可以更好地从Apple获取错误消息(在连接关闭之前),而不会影响我向Apple发送消息的速度。 这种方法在编程上更复杂,并且由于我的服务器需要将APN发送到多个iOS应用程序,每个应用程序都需要自己的套接字和读取器/写入器线程,这将使我需要的线程数增加两倍。

在尝试向Apple的沙盒服务器发送推送通知时,学习了APN服务器的所有上述行为。 我不确定Apple的生产服务器的行为是否更好,我不确定在生产服务器上执行测试是个好主意。

我的问题 – 有没有办法在关闭连接之前可靠地读取Alpha的错误响应,而不会牺牲性能? 是否有可能以某种方式从服务器关闭后从套接字读取输入?

我遇到了和你一样的问题。 我尝试了两种方法,但在关闭连接之前,它们都没有能够可靠地读取Apple的错误响应:

  1. 对于每个套接字,我启动了两个线程,一个用于连续写入,另一个用于阻塞读取。 在大多数情况下,当写入遇到“Socket Broken”exception时,读取线程可以读取错误响应,但它并不完全可靠。
  2. 对于每个套接字,我只启动了一个连续写入的线程,当遇到exception时,在try cache块中,尝试读取错误响应。 在大多数情况下,套接字是关闭的,所以我只读了一个例外。