2012-11-05 108 views
2

我有一个简单的Web应用程序,它列出了一组私人用户和他们发布的最后一条消息。使用PHP/JS/MySQL进行轮询的简单/高效方法

我目前只是通过使用Ajax轮询每30秒打一个php脚本,它将获取所有人和最新消息,然后返回为JSON。我解析并更新DOM。

大部分时间都不是很有效率,没有任何变化,但它仍然每30秒获取所有数据。

  1. 有没有什么基本的我可以做的,只是用代码来改善呢?

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

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

+0

当调查,而不是在返回相同的数据,并且每隔30秒,如果什么也没有改变过,你能不能有一个特殊的返回代码告诉Javascript不要改变网页? – phillid

+0

@phillid有正确的想法。更好的做法是仅仅利用http协议的+ web浏览器对缓存和条件http请求的出色支持。 – goat

+0

@rambo编码器,谢谢我喜欢那个声音。你能指点我的例子或更多信息的方向吗? – Quad6

回答

2

当您使用请求HTTP以每30秒就可能多的资源会使用,如果有1000个用户和更多的我认为这是不好的Web服务器,

我建议使用Nodejs有,节点JS是JavaScript的服务器是基于Chrome的JavaScript运行时构建的平台,可轻松快速构建,并支持长时间投掷和非块请求。

与nodejs,你可以建立你的网络服务器,可以处理许多用户和实时应用程序。

有很多框架可以与节点JS

  1. socket.io
  2. express

,如果你想尝试被实施,这是简单的教程.. http://martinsikora.com/nodejs-and-websocket-simple-chat-tutorial

0

无需改变大部分基础设施,您可以返回简单的消息确定是否有任何变化。

所以,如果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开销。

+0

谢谢,所以基本上在每次投票中,它将更新当前登录用户记录上的'last_polled'日期时间字段,然后如果自那时起东西已更改,它将更新:true。所以这是一个额外的MySQL查询,但会减少带宽。我遵循正确吗? – Quad6

+0

是的,就是这个想法。这样,只有在更新时才会通过JSON发送而不是每一次都会节省带宽。 –

0

在这种情况下,更好的解决方案是使用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); 
+0

如果一次有大量用户在网站上运行(即打开页面时可能有400多个用户),这样可以吗?它不会最大限度地提供apache连接的数量吗? (托管在mac os服务器上的apache上) – Quad6

+0

这可能不是最具可扩展性的选项。谷歌过去最初在浏览器中使用GChat,但我想他们在负载均衡器后面使用了一大群功能强大的服务器。 – xbonez