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

扩展聊天应用程序-短轮询与长轮询(AJAX、PHP),php,javascript,ajax,sockets,Php,Javascript,Ajax,Sockets,我运行了一个网站,用户可以通过浏览器相互聊天(比如Facebook聊天)。处理现场互动的最佳方式是什么?(现在,我每30秒进行一次民意调查,以更新在线用户和新收到的消息,每秒在聊天页面上进行一次民意调查,以获取新消息。) 我考虑过的事情: HTML5WebSockets:没有使用它,因为它不适用于所有浏览器(仅适用于chrome) FlashSockets:我没有使用它,因为我想最终支持移动网络 现在,我使用短轮询,因为我不知道AJAX长轮询的可伸缩性有多大。我现在正在从servint运行一

我运行了一个网站,用户可以通过浏览器相互聊天(比如Facebook聊天)。处理现场互动的最佳方式是什么?(现在,我每30秒进行一次民意调查,以更新在线用户和新收到的消息,每秒在聊天页面上进行一次民意调查,以获取新消息。)

我考虑过的事情:

  • HTML5WebSockets:没有使用它,因为它不适用于所有浏览器(仅适用于chrome)
  • FlashSockets:我没有使用它,因为我想最终支持移动网络

现在,我使用短轮询,因为我不知道AJAX长轮询的可伸缩性有多大。我现在正在从servint运行一个VPS服务器(运行apache)。我应该使用长轮询还是短轮询?我不需要绝对即时的响应时间(只需要“足够好”的聊天应用程序)。短轮询经常会导致几十万用户杀死我的服务器吗?我如何缩放这个,请帮助

在cometd和nodejs推出之前,每个人都曾经这样做过

我看到的问题是,Apache上的PHP请求非常昂贵。如果聊天应用程序每秒钟检查一次消息,您就会发现Apache没有足够的资源来响应请求。我认为需要改进的另一个方面是改进聊天应用程序的上下文

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

一些你可以使用的技巧

  • 为您的客户端提供一个轻量级的端点,该端点具有有关聊天会话的某些上下文、是否有新消息挂起、有多少消息等。如果没有新消息,客户端可以通过立即更新或不更新来对此作出响应。该端点可以通过http请求提供一个简单的json对象。我们保证此状态消息的大小是固定的,如果状态响应没有更改,您可以将其衰减。请参阅下一条消息

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

一些要考虑的优化;

  • 使用PHP操作码缓存,如APC

  • 在所有请求上设置一个较低的超时,您不希望任何请求挂起服务器

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

  • 运行一些负载测试,看看您的限制是什么

  • 经常对性能进行基准测试,以确保您的应用程序变得更快

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


当需要扩展时,添加新服务器并使用负载平衡器分发请求。我使用清漆和HAProxy取得了巨大成功,设置它们也不复杂

如果我是你,我会选择一个使用html5 web套接字的库,但如果html5不可用,则会选择使用flash套接字的库。如果没有html5,则浏览器的漏洞应该很小

此外,您还应该放弃php,或者用python或ruby与em websocket一起编写的线程套接字服务器对其进行补充。

一些注意事项:

  • 每秒钟进行一次投票都太过分了。该应用程序仍然会感觉非常灵敏,检查之间会有几秒钟的延迟 <> LI>为了节省DB的流量和速度响应,考虑使用内存缓存来存储未传递的消息。您仍然可以将消息持久化到db,内存中的缓存只用于查询新消息,以避免每个用户每x秒查询一次db
  • 在x秒不活动后,用户聊天超时,以停止对服务器的轮询。这可以确保有人打开窗户时不会继续产生流量。提供一个简单的“仍然存在?继续聊天”链接,用于超时会话,并在超时之前警告用户,以便他们可以延长超时时间
  • 我建议从轮询开始,而不是comet/长轮询/套接字。投票很容易构建和支持,短期内可能会扩展得很好。如果你获得了大量的流量,你可以用硬件和负载平衡器来解决这个问题。整个网络都是基于轮询的——轮询的规模肯定很大。在某种程度上,comet/long polling/etc等备选方案的复杂性是有意义的,但在额外的开发时间/复杂性得到证明之前,您需要大量的流量

我知道Apache通常不能很好地处理多个同时连接。并且还认识到,可能会有其他针对该场景构建的解决方案(nodejs等)。但是现在,我想避免重写整个应用程序。那么为不同的平台实现多个解决方案呢?也就是说,如果支持HTML5,浏览器使用HTML5,如果支持flash,浏览器使用flash,如果上述任何一项都不支持,浏览器使用ajax。你可能会对这篇文章感兴趣,你的最后一点非常有帮助-我一直在努力决定我的应用程序中的第一个轮询实现需要如何经得起未来的考验,我想我会采纳你的建议,让简单的轮询快速运行,然后计划一个明智的长期解决方案。动态增量是我从未想过的,非常好的一点