【问题标题】:polling a HTTP server from J2ME client从 J2ME 客户端轮询 HTTP 服务器
【发布时间】:2009-08-08 18:46:25
【问题描述】:

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

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

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

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

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

【问题讨论】:

    标签: java http java-me mobile polling


    【解决方案1】:

    如果您只想使用 HTTP 解决此问题,long polling 将是最好的方法。这很容易。首先,您需要在服务器端设置一个用于通知的 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 的解决方案可以获得的最好的解决方案。

    【讨论】:

    • 很好的答案!但是我不明白以下几点: 1. 如果没有要推送的事件,服务器将阻塞是什么意思。 2. 什么是心跳? 3. Tomcat是否有活跃用户数限制。
    • 答案: 1. 当没有推送时,您希望保持连接打开并等待事件。查看阻塞队列。 2. Heartbeat 是一个管理数据包,用于告诉电话服务器处于活动状态。如果空闲时间过长,您应该发送此信息,以避免手机进入陈旧的连接恢复模式,这会更昂贵。 3.对于像Tomcat这样的servlet,每个HTTP请求都是一个线程。线程数等于正在运行的应用程序数。即使最大值是可配置的,如果数字太大,服务器将不会执行。我会尽量保持在数百,而不是数千。
    【解决方案2】:

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

    查看tutorial 了解 J2ME 中 HTTP 连接的基础知识。

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

    【讨论】:

    • 从这个意义上讲,轮询是查询服务器,或者更确切地说是以固定的时间间隔询问它。例如,客户会从更一般的意义上问“我的数据准备好了吗?”或“自从我们上次谈话以来有什么变化吗?”查询将在技术意义上和服务器可以理解的语言中完成。
    • HEAD 不会发回任何 HTTP 内容(没有正文),但如果目标是节省 GPRS 流量,它会非常昂贵。很多事情必须在地毯下发生(3 次 TCP 握手、请求和响应与所有标头)。如果你的消息很小,它可能与 GET 没有区别。
    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

      • 你有参考吗?也许您可以向我们展示一些 AJAX 代码?
      • 我尝试制作一个示例应用程序:Midlet 正在监听服务器(我使用了用 Ruby 编写的示例)。您可以按“0”最小化应用程序。如果收到一些消息,应用程序会弹出并显示它。 depositfiles.com/files/68ix6gskv(对不起,我不知道怎么附加文件)
      猜你喜欢
      • 2013-11-13
      • 1970-01-01
      • 2014-09-12
      • 1970-01-01
      • 2011-05-14
      • 2011-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多