Google App Engine 中可以进行长轮询吗?

发布于 2024-09-17 00:56:28 字数 80 浏览 8 评论 0原文

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

I need to make application that needs to poll server often, but GAE has limitations on requests, so making a lot of requests could be very costly. Is it possible to use long polling and make requests wait for the maxium 30 seconds for changes?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

情绪失控 2024-09-24 00:56:28

Google AppEngine 有一个新功能 Channel API,您可以使用它
可以构建一个良好的实时应用程序

另一个解决方案是使用第三方 Comet 服务器,例如 mochiweb
或用 iframe 模式扭曲。

客户端1,等待事件:

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

客户端2,发送消息:

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

要使用带有彗星模式的mochiweb,Richard Jones 写了一篇很好的文章
主题(在谷歌上:理查德琼斯百万用户彗星应用程序)。

Google AppEngine has a new feature Channel API, with that you have
a possibility to build a good realtime application.

Another solution is to use a third part comet server like mochiweb
or twisted with a iframe pattern.

Client1, waiting a event:

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

Client2, sending a message:

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

To use mochiweb with comet pattern, Richard Jones has written a good
topic (on google: Richard Jones A Million-user Comet Application).

吐个泡泡 2024-09-24 00:56:28

我们尝试在 App Engine 上实现类似 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 已发送。 GET(未修改)blob(等待更改)。
  2. 请求 2 已发送。修改斑点。
  3. 完全超时后,请求 1 返回(数据未修改)。
  4. 请求 2 在服务器上得到处理,并返回成功。

我使用了wireshark和Chrome/timeline来确认我正在通过与长轮询连接不同的TCP连接向服务器发送修改请求。因此,此同步必须发生在 App Engine 生产服务器上。据我所知,谷歌没有记录服务器行为的细节。

我认为等待通道 API 是我们从 App Engine 获得良好实时行为的最大希望。

We've tried implementing a Comet-like long-polling solution on App Engine, with mixed results.

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

The problem I'm seeing is that requests following a long-polling one, are getting serialize (synchronized) behind the long-polling request. I can look at a trace in Chrome and see a timeline like this:

  1. Request 1 sent. GET (un-modified) blob (wait until changed).
  2. Request 2 sent. Modify the blob.
  3. After full time-out, Request 1 returns (data unmodified).
  4. Request 2 gets processed on server, and returns success.

I've used wireshark and Chrome/timeline to confirm that I AM sending the modification request to the server on a distinct TCP connection from the long-polling one. So this snychronization must be happing on the App Engine production server. Google doesn't document this detail of the server behavior, as far as I know.

I think waiting for the channel API is the best hope we have of getting good real-time behavior from App Engine.

画▽骨i 2024-09-24 00:56:28

我认为长轮询是不可能的。 google appengine 的默认请求超时为 30 秒。
在长轮询中,如果消息生成时间超过 30 秒,则会失败。
使用短轮询可能会更好。

另一种方法是“模拟”30 秒限制内的长轮询。为此,如果消息未在(例如 20 秒)内到达,服务器可以发送“令牌”消息而不是普通消息,要求客户端使用它并再次连接。

似乎有功能请求(且已接受)谷歌应用程序引擎进行长轮询

I don't think long polling is possible. The default request timeout for google appengine is 30 seconds.
In long polling if the message takes more than 30 secs to generate, then it will fail.
You are probably better off using short polling.

Another approach is to "simulate" long polling withing the 30 sec limit. To do this if a message does not arrive within, say 20 sec, the server can send a "token" message instead of a normal message, requiring the client to consume it and connect again.

There seems to be feature request (and its accepted) on google appengine for long polling

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文