我正在关注一个 PHP-MySQL 喊话箱教程,该教程仅涉及在数据库中发送和存储消息。完成后,我暂时选择了每 5 秒或每次使用 AJAX 发送新消息时刷新消息列表。但这在现实生活中的应用程序中效率太低并且消耗服务器(实际上是低强度的 DDOS)。那么如何在必要时刷新新消息列表呢?更准确地说,我如何在发生这种情况时收到一条新消息准确发送的通知,以便我可以显示它?
4 回答
解决您的问题的方法称为长轮询,您将在这个 SO question中找到更多信息。
这个想法是像您当前一样使用 AJAX 加载信息,但如果没有任何内容可返回,服务器将不会立即返回响应。相反,它只会在返回空响应之前保持连接打开预定义的秒数,或者在消息可用时立即返回。最大响应时间应该足够长以使其值得,但不要太长而冒着客户端超时的风险——大约 20 秒应该没问题。
尽管此解决方案允许您减少对服务器的 HTTP 调用次数,但它只是转移了问题:您的 PHP 脚本在等待消息可用时,仍然需要轮询您的数据库。如果您预计流量适中,那就没问题了。但是,如果您希望能够认真扩展,则必须寻找另一种解决方案。
最好的解决方案是使用适当的消息队列而不是数据库,例如Amazon SQS或IronMQ。
这些将无限扩展,并将提供诸如长轮询之类的功能(不确定 IronMQ,但 SQS 肯定可以)。
从服务器端事件获取通知称为推送技术。通常,这些实现利用 websockets 来避免轮询的压力。
Ratchet是一种常用的 PHP WebSocket 实现,它允许使用推送技术将数据发送到客户端。这将允许在不轮询或紧张服务器或连接池的情况下发送推送通知。
我强烈建议您检查客户端的Socket.IO 项目,这是一个很棒的实时通信库,可以处理基于访问者浏览器的所有协议和解决方案。这也将解决您的服务器端问题。
Socket.IO 旨在使每个浏览器和移动设备中的实时应用程序成为可能,从而模糊不同传输机制之间的差异。它在 JavaScript 中是 100% 无忧实时的。
- 网络套接字
- Adobe® Flash® 插座
- AJAX 长轮询
- AJAX 多部分流式传输
- 永远的 iframe
- JSONP 轮询
服务器无法通知 Web 浏览器。HTTP 是一个基于拉取的系统。AJAX 的全部目的是伪装成一个基于推送的系统。如果需要推送,则需要 AJAX。