使用PHP/JS/MySQL进行轮询的简单/高效方法

使用PHP/JS/MySQL进行轮询的简单/高效方法,php,jquery,mysql,polling,Php,Jquery,Mysql,Polling,我有一个简单的web应用程序,它列出了一组私人用户和他们发布的最后一条消息 我目前正在使用Ajax进行轮询,每30秒点击一次php脚本,它会获取所有人和最新消息,然后以JSON的形式返回。我解析它并更新DOM 效率不是很高,因为大多数情况下,没有任何变化,但它仍然每30秒获取一次所有数据 有什么基本的我可以做的,只是用代码来改善这一点 我应该用像这样的东西吗 有很多关于实现长轮询的教程,但我希望尽可能简单。当您每30秒使用一次请求http时,可能会使用很多资源,如果有1000个或更多用户,我认为

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

我目前正在使用Ajax进行轮询,每30秒点击一次php脚本,它会获取所有人和最新消息,然后以JSON的形式返回。我解析它并更新DOM

效率不是很高,因为大多数情况下,没有任何变化,但它仍然每30秒获取一次所有数据

  • 有什么基本的我可以做的,只是用代码来改善这一点

  • 我应该用像这样的东西吗


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

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

    我建议使用NodeJS作为javascript服务器,它是一个基于Chrome的javascript运行时构建的平台,可以轻松快速构建,并支持长轮询和非阻塞请求

    使用nodejs,您可以构建能够处理多个用户和实时应用程序的web服务器

    有许多框架可以通过NodeJS实现

  • 如果你想试试的话,这是一个简单的教程。。

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

    因此,如果
    http://localhost/example/request
    正在返回:

    {
        "phoneNumbers": [
            {
                "type": "home",
                "number": "212 555-1234"
            },
            {
                "type": "fax",
                "number": "646 555-4567"
            }
        ]
    }
    
    对于每个请求,如果未更新任何内容,则可以返回以下内容:

    {
        "updated": false
    }
    
    {
        "updated": true,
        "phoneNumbers": [
            {
                "type": "work",
                "number": "111-222-3333"
            }
        ]
    }
    
    此外,您还可以让
    updated:true
    指示它已更新:

    {
        "updated": false
    }
    
    {
        "updated": true,
        "phoneNumbers": [
            {
                "type": "work",
                "number": "111-222-3333"
            }
        ]
    }
    
    总的来说,您需要做的就是在每个查询中检查返回对象的
    updated
    属性。仅当
    updated
    true


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

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

    下面是它的工作原理:

    您可以按照现在的状态发出AJAX请求。
    服务器端脚本仅在有更新时返回(回显)。如果没有,它将继续循环并等待更新。这将使AJAX请求保持挂起状态。
    当有更新时,服务器端脚本返回,客户端JS更新DOM,并立即发出新的AJAX请求

    PS-要使其工作,您必须确保脚本未设置为30秒后超时

    在psuedo代码中,这就是服务器端脚本的外观

    $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);
    

    在进行民意调查时,如果没有任何变化,那么就不要每隔30秒反复返回相同的数据,你能不能有一个特殊的返回代码告诉Javascript不要对网页进行任何更改?@phillid的想法是正确的。更好的做法是只利用http协议的+web浏览器对缓存和有条件http请求的出色支持。@rambo coder,谢谢,我喜欢这样的声音。你能告诉我一个例子或更多信息的方向吗?如果网站上同时有很多活跃的用户(例如,页面打开时可能有400多个用户),这是否可以。它不会最大化apache连接的数量吗?(托管在mac os服务器上的apache上)这可能不是最具可扩展性的选项。谷歌最初在浏览器中使用GChat,但我想他们在负载均衡器后面使用了一个强大的服务器集群。谢谢,所以基本上每次轮询时,它都会更新当前登录用户记录上的“last_polled”datetime字段,如果自那时起内容发生了变化,则会更新:true。因此,这是一个额外的MySQL查询,但会减少带宽。我的理解正确吗?是的,这就是我的想法。这样,只有在JSON更新时,而不是每次更新时,才能通过JSON发送,从而节省带宽。