Websocket 或长轮询(使用 AJAX)使用 PHP 检测数据库中的更改

Posted

技术标签:

【中文标题】Websocket 或长轮询(使用 AJAX)使用 PHP 检测数据库中的更改【英文标题】:Websocket or Long Polling (using AJAX) to detect Changes in Database using PHP 【发布时间】:2013-01-22 23:14:01 【问题描述】:

我的研究

我花了数小时在 Google 和 SO 上研究 Websockets 和 Long Polling、它们的优缺点等,但我还没有找到一个明确的解决方案。

我已经阅读了更多关于这个主题的文章,而不是我曾经研究过的任何文章,包括这些(仅举几例):

    Ajax/php - should I use one long running script or polling? Long Polling using jQuery and PHP Poll Database for Changes - Ajax/jQuery

我还研究了以下内容:

    http://cometdproject.dojotoolkit.org/ http://socket.io/

这个问题的理由

乍一看,这个问题似乎是重复的或过于本地化,但是,经过我的广泛研究,我无法收集足够的信息来做出明智的决定,决定走哪条路线。

因此,我希望你们中的一个天才会花时间回答这个问题,并与我们其他人分享你的精彩知识:-)

我的问题

简而言之,我的问题确实在标题中;如果我试图检测对数据库记录的更改,是使用 websocket (socket.io) 还是长轮询 (jQuery 和 AJAX) 更好?

如果答案是 websockets,那么请提供一个基本示例,因为这些确实让我感到困惑,即使是 Google 上的所有文章...

此外,可能还有其他更好或更适合的方法,如果有,请分享,我愿意接受任何建议!


其他信息

这可能不会影响最终答案,但以防万一,我想解释一下我试图检测的内容以及可能需要考虑的一些事项。

实际上,我正在尝试检测登录会话的任何更改。换句话说,如果数据库中的用户令牌已更改他们的超时已用完,则他们已被注销,我想显示一条消息通知他们。

我认为这不会产生影响,但最终代码需要适合 SSL。使用 AJAX 很容易,但我对 websockets 方面不熟悉。

最初,我编写了一个系统,它使用 javascript 从服务器检索超时,然后在timeout 秒内,它会轮询服务器以查看 timeout 是否已过期。我认为这是完美的,直到我意识到它只有在客户端计算机上的时间与服务器上的时间匹配时才有效。因此我不得不放弃这个:-(

无论如何,我希望我的问题不要太本地化,我期待听到您的意见和答案。请不要浪费您的时间来帮助我编写 PHP 数据库代码或 jQuery AJAX 代码,除非它有复杂的部分,因为我有能力自己编写这部分,并且堆栈上还有很多其他需要您的帮助比我多。如果它们是更好的解决方案,我对您的意见和/或如何使用 websockets 实现这一点更感兴趣:-)。

【问题讨论】:

不完全是一个答案,但我使用pubnub.com 得到了非常好的结果它很容易实现而且速度很快。 您可以考虑使用 redis 数据库,这样您就可以在数据更改时触发事件,并与客户端建立实时双向连接以使用 socket.io 扩展所需数据 @Chris 感谢您的意见,但我真的不想为自己能做的事情付钱 @eyurdakul 害怕 Redis 不是一个选项,这个应用程序链接到一个 SQL 数据库,它也链接到一个桌面应用程序,所以我不能移动到不同的数据库引擎:-( 关于你的粗体超时问题:使用 UTC 时间而不是客户端时间来实现这一点。 【参考方案1】:

这是我见过的关于长轮询和 WebSocket API 的最佳比较:http://www.websocket.org/quantum.html

正如上面的文章所说,WebSocket API 远优于长轮询(或任何其他伪双向通信),但一个缺点是浏览器支持仍然不完全存在(IE 终于开始支持 WebSocket API在 IE10 中)。

因此,如果您正在寻找一个完整的双向通信解决方案,请在 WebSocket API 可用时使用它,而在它不可用时回退到 Ajax 长轮询或您喜欢的任何彗星方法。

要回答您的问题,如果您只是偶尔进行服务器端/数据库查询(“偶尔”一词是相对的,需要在您的系统上进行测试),那么简单的 Ajax 请求应该没问题。但是,如果您每隔 10 秒或更短时间就向服务器发送一次请求,那么使用 WebSocket API 绝对是理想的选择。

回答您的最后一个问题,SSL 100% 可用于 WebSocket API。只需使用 wss 协议而不是标准 ws 协议,就可以了。

【讨论】:

这就是我查看 socket.io 的原因,因为如果 websocket API 不可用,这将回退到其他方法。我遇到的问题是我找不到关于 socket.io 和 node.js 如何工作的清晰解释。尽管有很多关于谷歌和 SO 的文章,我还是找不到任何清楚的东西。我知道 wss 协议,但不确定它如何与我安装的 SSL 一起工作。您是否知道有关如何使用 websockets 检测数据库中的更改的任何明确解释?当然使用 PHP 和 Javascript? 我同意 Socket.IO 之类的文档很少而且不是很好,这就是我从头开始编写自己的 PHP WebSocket 解决方案的原因。基本原理是你的PHP脚本在后台不断的运行while循环,监听socket连接。您可以轻松地将数据库查询添加到该脚本(或单独包含的脚本),并根据需要通过套接字连接将数据发送到客户端。这能回答你的问题吗? Socket.io 甚至可以在 ie6 及更高版本以及所有其他流行的浏览器中运行。如果 html5 websocket 不起作用,那么它使用 flash 我认为 Socket.IO 首先退回到 Ajax 长轮询,如果不存在,它使用 Flash。也许我错了。【参考方案2】:

您在“...我正在尝试检测对数据库记录的更改...”的部分中写道。 websockets 中没有任何东西可以检测数据库的变化;那不是它的用途。)

在我看来,一种经济的实现方式是让更改代理(在您的情况下是注销)在更改时通知侦听器,而不是通过某种方式监视以检测该更改。

我的意思是数据库被一些特定的脚本操作改变了。我会考虑扩展每个操作以触发 websocket 事务。

【讨论】:

以上是关于Websocket 或长轮询(使用 AJAX)使用 PHP 检测数据库中的更改的主要内容,如果未能解决你的问题,请参考以下文章

Tornado-长轮询_webSocket

python之轮询长轮询websocket

轮询长轮询长连接socket连接WebSocket

轮询长轮询长连接socket连接WebSocket

服务端向客户端推送消息:轮询,长轮询(兼容性好),以及websocket(主流浏览器都支持)

React + axios 如何实现长轮询