4

我的手机(客户端)上运行了一个 J2ME 应用程序,

我想打开与服务器的 HTTP 连接并不断轮询服务器上的更新信息。

执行的每个轮询都会用完 GPRS 字节,从长远来看会变得昂贵,因为 GPRS 计费是基于发送和接收的数据包。是否有使用 HTTP 协议进行轮询的字节有效方式?

我也听说过长轮询,但我不确定它是如何工作的以及它的效率如何。

实际上,首选方法是服务器告诉手机应用程序新数据已准备好使用,这样就不需要进行轮询,但是我不知道这些技术,尤其是在 J2ME 中。

4

4 回答 4

6

如果您只想使用 HTTP 来解决这个问题,那么长轮询将是最好的方法。这很容易。首先,您需要在服务器端设置一个用于通知的 URL(例如http://example.com/notify),并定义一个通知协议。协议可以像一些文本行一样简单,每一行都是一个事件。例如,

  MSG user1
  PHOTO user2 album1
  EMAIL user1
  HEARTBEAT 300

手机上的轮询线程是这样工作的,

  1. 与通知 URL 建立 HTTP 连接。在 J2ME 中,您可以使用 GCF HttpConnection。
  2. 如果没有要推送的事件,服务器将阻塞。
  3. 如果服务器响应,获取每一行并生成一个新线程来通知应用程序并环回#1。
  4. 如果连接因任何原因关闭,请休眠一段时间并返回步骤 1。

您必须注意以下实施细节,

  1. 调整客户端和服务器上的 HTTP 超时。超时时间越长,效率越高。超时连接将导致重新连接。
  2. 在电话和服务器上启用 HTTP keepalive。TCP 的 3 次握手在 GPRS 术语中是昂贵的,所以尽量避免它。
  3. 检测过时的连接。在移动环境中,很容易获得陈旧的 HTTP 连接(连接消失但轮询线程仍在等待)。您可以使用心跳来恢复。假设心跳频率为 5 分钟。服务器应每 5 分钟发送一次通知。如果没有要推送的数据,只需发送 HEARTBEAT。在电话上,如果 5 分钟内没有收到任何消息,轮询线程应尝试关闭并重新打开轮询连接。
  4. 小心处理连接错误。当存在连接问题时,长轮询无法正常工作。如果处理不当,可能会破坏交易。例如,如果睡眠时间不够长,您可能会在第 4 步浪费大量数据包。如果可能,请检查手机上的 GPRS 可用性,并在 GPRS 不可用时暂停轮询线程以节省电池电量。
  5. 如果实施不当,服务器成本可能会非常高。例如,如果您使用 Java servlet,每个正在运行的应用程序将至少有一个对应的轮询连接及其线程。根据用户的数量,这可以快速杀死 Tomcat :) 您需要使用资源高效技术,例如 Apache Mina。

有人告诉我还有其他更有效的方法可以将通知推送到手机,比如使用 SMS 和一些 IP 级别的技巧。但是你要么必须做一些低级的非便携式编程,要么面临专利侵权的风险。长轮询可能是使用仅 HTTP 的解决方案可以获得的最好的。

于 2009-08-08T21:08:05.057 回答
2

我不知道你所说的“轮询”是什么意思,你是指像IMAP IDLE这样的东西吗?连接保持打开状态,一次又一次地建立连接本身没有开销。如前所述,另一种可能的解决方案是 HTTP 请求的 HEAD 标头(忘记了,谢谢!)。

查看本教程以了解 J2ME 中的 HTTP 连接的基础知识。

无法将数据推送到没有推送支持的应用程序/设备(如黑莓)。

于 2009-08-08T19:14:31.060 回答
1

HEAD HTTP 请求是 HTTP 提供的用于检查页面是否已更改的方法,浏览器和代理服务器使用它来检查页面是否已更新,而不会占用太多带宽。

在 HTTP 术语中,HEAD 请求与没有正文的 GET 相同,我假设这最多只有几百个字节,如果您的轮询不是很频繁,这看起来是可以接受的。

于 2009-08-08T19:14:27.330 回答
1

最好的方法是使用套接字连接。许多应用程序(如 GMail)都使用它们。

于 2009-08-09T10:08:03.780 回答