【问题标题】:Simple/efficient approach to polling with PHP/JS/MySQL使用 PHP/JS/MySQL 进行轮询的简单/高效方法
【发布时间】:2012-11-05 02:10:11
【问题描述】:

我有一个简单的网络应用程序,它列出了一个私人群组和他们发布的最后一条消息。

我目前只是通过使用 Ajax 每 30 秒访问一个 php 脚本进行轮询,该脚本获取所有人员和最新消息,然后以 JSON 形式返回。我解析并更新 DOM。

因为大部分时间效率不高,没有任何变化,但它仍然每 30 秒获取一次所有数据。

  1. 我能做些什么基本的事情,只是用代码来改进它?

  2. 我应该使用pusher.com 之类的东西吗?

有很多关于实现长轮询的教程,但我想尽可能简单。

【问题讨论】:

  • 当轮询时,如果没有任何变化,而不是每 30 秒一次又一次地返回相同的数据,你能不能有一个特殊的返回码告诉 Javascript 不对网页进行任何更改?
  • @phillid 有正确的想法。更好的办法是利用 http 协议的 + 网络浏览器对缓存和条件 http 请求的出色支持。
  • @rambo 编码器,谢谢我喜欢这样的声音。你能指出一个例子或更多信息的方向吗?

标签: php jquery mysql polling


【解决方案1】:

当您每 30 秒使用一次请求 http 时,可能会使用很多资源,如果有 1000 个或更多用户,我认为这对 Web 服务器不利,

我建议使用Nodejs,node js 是一个基于 Chrome 的 JavaScript 运行时构建的平台,可以轻松快速构建,并且支持长轮询和非阻塞请求。

使用 nodejs,您可以构建可以处理许多用户并用于实时应用程序的网络服务器。

有很多框架可以用node js实现

  1. socket.io
  2. express

如果您想尝试,这是一个简单的教程.. http://martinsikora.com/nodejs-and-websocket-simple-chat-tutorial

【讨论】:

    【解决方案2】:

    无需更改大部分基础架构,您可以返回一条简单的消息,指示是否已更改任何内容。

    所以,如果http://localhost/example/request 正在返回:

    {
        "phoneNumbers": [
            {
                "type": "home",
                "number": "212 555-1234"
            },
            {
                "type": "fax",
                "number": "646 555-4567"
            }
        ]
    }
    

    对于每个请求,如果没有更新,您可以改为返回以下内容:

    {
        "updated": false
    }
    

    此外,您还可以使用updated: true 表示它已更新:

    {
        "updated": true,
        "phoneNumbers": [
            {
                "type": "work",
                "number": "111-222-3333"
            }
        ]
    }
    

    总体而言,您所要做的就是在每个查询中检查返回对象的updated 属性。如果updatedtrue,则只需要解析响应

    不过,总体而言,每个 HTTP 请求都会造成开销。每次轮询时,都会向浏览器发出一个新请求。拥有大量并发用户将开始引入性能问题。我建议查看实时 Web 框架,例如 Node.js(如 viyancs 所述),因为它们为每个用户维护持久连接以允许“推送”数据(而不是轮询),从而减少 HTTP 开销。

    【讨论】:

    • 谢谢,所以基本上在每次投票时,它都会更新当前登录用户记录上的“last_polled”日期时间字段,然后如果从那时起发生了变化,它将被更新:true .所以这是一个额外的 MySQL 查询,但会减少带宽。我的关注正确吗?
    • 是的,就是这样。这样,您将通过仅在更新而不是每次更新时发送 JSON 来节省带宽。
    【解决方案3】:

    在这种情况下,更好的解决方案是使用 XHR 长轮询。它的工作方式与您现在所做的有点相似,即通过发出 AJAX 请求。

    它是这样工作的:

    您现在发出 AJAX 请求。
    服务器端脚本仅在有更新时返回(回显)。如果没有,它会一直循环并等待更新。这会使 AJAX 请求保持未决状态。
    当有更新时,您的服务器端脚本返回,您的客户端 JS 更新 DOM,并立即发出新的 AJAX 请求。

    PS - 为此,您必须确保脚本未在 30 秒后设置为超时。

    在伪代码中,这就是您的服务器端脚本的样子

    $newInfo = false;
    
    while ($newInfo === False) {
        $newInfo = getNewInfo(); // a method that returns the new info. False if nothing has changed
        // sleep here for a bit
        usleep(500000);
    }
    
    // will only reach here when something has changed
    echo json_encode($newInfo);
    

    【讨论】:

    • 如果网站上同时有很多活跃用户(即在页面打开的情况下可能有 400 多个用户),这是否可行。它不会最大化apache连接的数量吗? (托管在 mac os 服务器上的 apache 上)
    • 这可能不是最可扩展的选项。谷歌最初在浏览器中将其用于 GChat,但我想他们在负载均衡器后面使用了一大群强大的服务器。
    猜你喜欢
    • 2013-11-06
    • 2012-01-30
    • 1970-01-01
    • 2017-09-02
    • 1970-01-01
    • 1970-01-01
    • 2013-03-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多