扩展聊天应用程序 - 短轮询与长轮询(AJAX,PHP)

时间:2011-03-15 15:02:02

标签: php javascript ajax sockets

我运营一个网站,用户可以通过浏览器互相聊天(想想Facebook聊天)。处理实时交互的最佳方式是什么? (现在我每隔30秒进行一次民意调查,以更新在线用户和新收到的消息,并且每秒都会在聊天页面上进行另一次民意调查以获取新消息。)

我考虑过的事情:

  • HTML5网络套接字:没有使用它,因为它不适用于所有浏览器(仅限chrome)。
  • Flash套接字:没有使用它,因为我想最终支持移动网络。

现在,我正在使用短轮询,因为我不知道AJAX长度轮询的可扩展性如何。我正在从servint运行VPS服务器(运行apache)。我应该使用长轮询还是短轮询?我不需要绝对的立即响应时间(对于聊天应用来说只是“足够好”)。是否有几十万用户要杀死我的服务器?我该如何扩展,请帮忙!

3 个答案:

答案 0 :(得分:43)

一些注意事项:

  • 每秒轮询都是矫枉过正。通过检查之间的几秒延迟,应用程序仍然会感觉非常敏感。
  • 要保存数据库的流量和速度响应,请考虑使用内存缓存来存储未传递的邮件。您仍然可以将消息持久保存到数据库,内存缓存将仅用于查询新消息,以避免每个用户每隔x秒对数据库进行一次查询。
  • 在x秒不活动后超时用户聊天以停止轮询到您的服务器。这可以确保某人打开窗户不会继续产生流量。提供一个简单的“还在那里?继续聊天。”超时会话的链接,并在超时前警告用户,以便他们可以延长超时时间。
  • 我建议开始使用轮询而不是彗星/长轮询/套接字。轮询很容易建立和支持,并且可能在短期内扩展得很好。如果你获得了大量的流量,你可以抛出硬件和负载平衡器来解决问题。整个网络都是基于民意调查 - 大多数情况下都会轮询。有一点像彗星/长轮询/等替代方案的复杂性是有意义的,但在额外的开发时间/复杂性合理之前,你需要大量的流量。

答案 1 :(得分:23)

这是每个人在引入cometd和nodejs之前曾经做过的事情。

我认为问题是Apache上的PHP请求非常昂贵。如果您的聊天应用程序每秒检查一次消息,您将发现自己处于Apache没有足够资源来响应请求的情况。我认为需要改进的另一个领域是改善聊天应用程序的上下文。

如果不检索新邮件,为什么每秒更新一次? 如果没有消息怎么办?

您可以使用的一些技巧;

  • 为您的客户提供轻量级端点,其中包含聊天会话的一些上下文,待处理的新消息,消息的数量等等。客户端可以通过立即更新来响应,如果没有新消息。此端点可以通过http请求提供简单的json对象。您可以保证此状态消息的大小固定,如果状态响应没有改变,您可以将其拒绝。见下一条消息。

  • javascript轮询中的简单衰减,如果客户端连续几次从服务器收到相同的响应,您可以按设定的时间递增轮询,目前您说它是每秒。如果你这样做,你将增加到每2,4,6,8,10秒。一旦服务器的响应发生变化,您就会重置衰减。

要考虑的一些优化;

  • 使用像APC这样的PHP操作码缓存。

  • 为所有请求设置低超时,您不希望有任何请求挂起您的服务器。

  • 优化您的PHP代码,使其精简且快速。

  • 运行一些负载测试以查看您的限制。

  • 基准性能通常是为了确保您的应用程序变得更快。

  • 检查apache日志,了解应用程序整体运行状况和响应时间的故事迹象。

当需要进行扩展时,添加新服务器并使用负载均衡器来分发请求。我已经使用Varnish和HAProxy取得了巨大的成功,设置它们并不复杂。

答案 2 :(得分:1)

如果我是你,我会选择一个使用html5网络套接字的库但如果html5不可用则会回到闪存套接字上,那么通过破解的浏览器应该是分钟。

此外,您应该放弃php或使用带有em-websocket的python或ruby编写的线程套接字服务器来补充它。