代码之家  ›  专栏  ›  技术社区  ›  newbie

谷歌应用程序引擎中是否可以进行长时间轮询?

  •  8
  • newbie  · 技术社区  · 15 年前

    我需要经常使用需要轮询服务器的应用程序,但是GAE对请求有限制,所以发出大量请求可能非常昂贵。是否可以使用长轮询并使请求等待最多30秒的更改?

    3 回复  |  直到 14 年前
        1
  •  10
  •   Andrew Whitaker    14 年前

    谷歌Appengine有了一个新的功能频道API 一 possibility to build a good realtime application .

    另一种解决方案是使用第三部分Comet服务器,如Mochiweb 或者用iframe模式扭曲。

    客户1,等待事件:

    client1 --Iframe Pattern--> Erlang/Mochiweb(HttpLongPolling):
    

    客户端2,发送消息:

    client2 --XhrIo--> AppEngine --UrlFetch--> Erlang/Mochiweb
    

    为了使用带有彗星图案的Mochiweb,Richard Jones写了一篇很好的 主题(在Google上:Richard Jones百万用户Comet应用程序)。

        2
  •  2
  •   mckoss    15 年前

    我们尝试在应用程序引擎上实现一个类似Comet的长轮询解决方案,结果参差不齐。

    def wait_for_update(request, blob):
        """
        Wait for blob update, if wait option specified in query string.
        Otherwise, return 304 Not Modified.
        """
        wait = request.GET.get('wait', '')
        if not wait.isdigit():
            return blob
        start = time.time()
        deadline = start + int(wait)
        original_sha1 = blob.sha1
        try:
            while time.time() < deadline:
                # Sleep one or two seconds.
                elapsed = time.time() - start
                time.sleep(1 if elapsed < 7 else 2)
                # Try to read updated blob from memcache.
                logging.info("Checking memcache for blob update after %.1fs",
                             elapsed)
                blob = Blob.cache_get_by_key_name(request.key_name)
                # Detect changes.
                if blob is None or blob.sha1 != original_sha1:
                    break
        except DeadlineExceededError:
            logging.info("Caught DeadlineExceededError after %.1fs",
                         time.time() - start)
        return blob
    

    我看到的问题是,在长时间轮询之后的请求,在长时间轮询请求之后正在进行序列化(同步)。我可以在Chrome中查看一个跟踪,并看到如下时间线:

    1. 请求1已发送。获取(未修改)blob(等待更改)。
    2. 请求2已发送。修改blob。
    3. 完全超时后,请求1返回(数据未修改)。
    4. 请求2在服务器上得到处理,并返回成功。

    我已经使用wireshark和chrome/timeline来确认我正在通过与长轮询连接不同的TCP连接向服务器发送修改请求。所以这个snychronization必须在应用引擎生产服务器上进行。据我所知,谷歌没有记录服务器行为的细节。

    我认为等待通道API是我们从应用程序引擎获得良好实时行为的最好希望。

        3
  •  0
  •   naikus    15 年前

    我认为长时间投票是不可能的。google appengine的默认请求超时为30秒。 在长轮询中,如果消息生成时间超过30秒,那么它将失败。 您最好使用短轮询。

    另一种方法是“模拟”具有30秒限制的长轮询。要做到这一点,如果一条消息没有在20秒内到达,比如说,服务器可以发送一条“令牌”消息而不是一条普通消息,要求客户机使用它并重新连接。

    好像有 feature request (并被接受)在谷歌上出现了长期投票

    推荐文章