App Engine:保持套接字打开超过2分钟

时间:2013-03-20 21:26:13

标签: java google-app-engine sockets

使用App Engine Trusted Tester套接字连接到APNS。写入套接字工作正常。

但问题是Socket在2分钟不活动后被收回。它在Trusted Tester网站上说任何套接字操作都会使套接字保持活动状态2分钟。在APNS决定关闭连接之前保持套接字打开更好。

在尝试了几乎所有的Socket API方法之后,无法写入输出流,无论如何,Socket会在2分钟后关闭。我错过了什么?

部署在java后端。

3 个答案:

答案 0 :(得分:1)

您不能将连接到APNS的套接字人为打开;没有发送实际推送通知。保持打开的唯一方法是发送一些任意数据/字节,但这会导致套接字立即关闭; APNS一检测到不符合协议的内容即关闭连接,即不是实际的推送通知。

SO_KEEPALIVE

SO_KEEPALIVE怎么样? App Engine明确表示支持它。我认为这只是意味着当你致电Socket.setKeepAlive(true)时它不会抛出异常;调用想要设置套接字选项之前没有实现异常。即使您启用keep-alive,如果您不发送超过2分钟的内容,您的套接字也将被回收(关闭);至少在现在的App Engine上。

实际上,这并不是一个大惊喜。指定TCP Keep Alive的RFC1122明确指出TCP Keep Alives不会每两小时发送一次以上,然后,只有在没有其他流量时才需要。虽然,它也说这个间隔也必须是可配置的,但java.net.Socket上没有可用于配置的API(很可能是因为它依赖于OS),我怀疑它会在App上设置为2分钟发动机。

SO_TIMEOUT

SO_TIMEOUT怎么样?这是完全不同的东西。 Socket.setSoTimeout()状态的javadoc:

  

使用指定的超时启用/禁用SO_TIMEOUT,以毫秒为单位。如果将此选项设置为非零超时,则与此Socket关联的InputStream上的read()调用将仅阻止这段时间。如果超时到期,则引发java.net.SocketTimeoutException,尽管Socket仍然有效。必须在进入阻止操作之前启用该选项才能生效。超时必须> 0.超时为零被解释为无限超时。

也就是说,当read()阻塞太长时间因为没有什么可读的时候你可以说“好吧,我不想再等待(阻止)了;让我们做其他事情”。这对我们的“2分钟”问题没有帮助。

What then?

解决此问题的唯一方法是:检测何时回收/关闭连接然后将其丢弃并打开新连接。并且有一个库可以完全支持它。

结帐java-apns-gae

这是一个开源的Java APNS库,专为在Google App Engine上工作(和使用)而设计。

https://github.com/ZsoltSafrany/java-apns-gae

答案 1 :(得分:0)

你试过getSoLinger()吗?这可能是当前工作(种类)的getSocketOpt,它可能会重置2分钟超时。从理论上讲,也可以进行零字节读取,但我不确定如果你尝试的话,会在输入流上使用这种方法。

public int read(byte b [],int off,int len)

如果这些建议不起作用,请向App Engine问题跟踪器提出问题。

还会有其他一些修复措施,例如:使用套接字选项等。

答案 2 :(得分:0)

使用getpeername()

来自https://developers.google.com/appengine/docs/java/sockets/overview ...

  

在2分钟不活动后,可以回收插座; 任何套接字   operation(例如getpeername)使套接字保持活动状态2   分钟即可。 (请注意,您无法在多个可用之间进行选择   套接字,因为这需要java.nio.SocketChannel,而不是   目前支持。)