You cannot keep a socket connected to APNS artificially open; without sending actual push notifications. The only way to keep it open is to send some arbitrary data / bytes, but this will immediately close the socket; APNS closes the connection as soon as it detects something that does not comply with the protocol, that is, something that is not the actual push notification.
SO_KEEPALIVE
What about SO_KEEPALIVE ? App Engine clearly says that it is supported. I think it just means that it will not throw an exception when you call Socket.setKeepAlive(true) ; calls wanted to set socket parameters. Exceptions not implemented before. Even if you enable keep-alive, your socket will be restored (closed) if you do not send something more than 2 minutes; at least on the App Engine.
Actually, this is not a big surprise. RFC1122 , which indicates that TCP Keep Alive explicitly indicates that TCP Keep Alives should not be sent more than once every two hours, and then only necessary if there was no other traffic. Although, he also says that this interval should also be customizable, the java.net.Socket API that you could use to configure it (most likely because it is very OS dependent) does not exist, and I doubt that It will be installed for 2 minutes in App Engine.
SO_TIMEOUT
What about SO_TIMEOUT ? This is for something completely different. The javadoc Socket.setSoTimeout() says:
Enable / disable SO_TIMEOUT with the specified timeout in milliseconds. If this parameter is set to a non-zero timeout, the read () call in the InputStream associated with this Socket will be blocked only for this amount of time. If the timeout expires, a java.net.SocketTimeoutException is thrown, although Socket is still valid. The option must be activated before the lock operation is entered. The timeout must be> 0. A zero timeout is interpreted as an infinite timeout.
That is, when read() blocked for too long because there is nothing to read, you can say "well, I donβt want to wait (block) anymore, but do something else instead." This will not help with our 2 minutes problem.
What then?
The only way around this problem is to detect when the connection will be restored / closed, and then throw it away and open a new connection. And there is a library that supports just that.
Check out java-apns-gae .
This is an open source Java APNS library that has been specifically designed to work (and use) with the Google App Engine.
https://github.com/ZsoltSafrany/java-apns-gae