【问题标题】:PHP Daemon - Receive commands from Browser?PHP Daemon - 从浏览器接收命令?
【发布时间】:2015-10-16 22:20:38
【问题描述】:

我喜欢编写一个在 Linux 后台运行的 PHP 脚本。

我想弄清楚在 PHP 守护程序(脚本)和浏览器客户端之间发送和接收元数据的解决方案是什么?

我以为我可以在守护程序本身中包含 http 请求处理,但守护程序脚本每秒可以接收 500-1000 个请求。所以守护进程本身的http请求不是一个好的解决方案。

Redis 或 ZeroMQ 是解决这个问题的方法吗?像这样的:

(browser clients) <-----> redis <-----> PHP Daemon Script

如果 PHP 守护进程向客户端发送消息,则浏览器应立即通过 ajax(长轮询)获取元数据。

【问题讨论】:

  • 最好的解决方案是使用Mongrel2。它是一个使用 ZeroMQ 作为其传输层的 Web 服务器。 HTTP 或 WebSocket 协议的表示方式相同,它将消息传递到 ZMQ 端点 - 这是您的脚本开始的地方。您可以在一台机器上拥有一个守护程序,或者以循环方式处理请求的数百万个守护程序。或者您可以自己实现整个HTTP解析/使用websockets(您必须自己实现websocket解析+对浏览器的连接处理)。 Mongrel2 的性能优于任何可用的服务器。

标签: php redis message-queue zeromq


【解决方案1】:

Chris Brand 给了你答案,websockets。我只是想更详细地了解您的问题,以帮助指出您的一些误解。

在浏览器之外建立非 http 连接的唯一有效方法是使用 websockets - 它是浏览器与外部服务器通信的唯一接口,不包括完整的 http 开销。

你的图表:

(browser clients) <-----> redis <-----> PHP Daemon Script

... 似乎将 redis 视为一种通信协议,它不是,它是一个数据存储。您不会使用 redis 将通信从浏览器传递到 PHP 脚本,就像您将 MySQL 用于相同的任务一样。不管怎样,乍一看,Redis 似乎无法直接接收 websocket 连接,因此无论如何您都无法将浏览器直接连接到它,所以图片看起来更像:

(browser clients) <-----> PHP Daemon Script <-----> redis (or any other data store)

如果您愿意,可以使用 ZMQ 来管理您的通信,这样做可能有令人信服的理由,但这是特定于应用程序的。无论如何,ZMQ 会 websockets 之上存在,并为此添加自己品牌的开销。也就是说,它专为这种高容量消息传递而设计。

我的建议是研究直接使用 websockets 与您的后端通信。 Chris Brand 提出了另一个很好的建议来研究使用 node.js,但是学习曲线(如果您熟悉 JS,则相对较小)对于您的项目的这次迭代可能不值得。如果您遇到消息传递/连接可靠性问题,那么您可能会研究 ZMQ 可以为您提供什么。

【讨论】:

  • 感谢@Jason 的回答,我现在明白了。是的,我正在考虑在我的项目中使用 node.js,希望学习曲线不会太深。我确实有一些JS经验。如果我决定使用 node.js,那么该图仍然有效吗?像这样:(browser clients websocket) &lt;-----&gt; node.js &lt;-----&gt; redis or ZMQ
  • 我想重申一下,redis 和 ZMQ 服务于相同的目的。 redis 是数据存储,ZMQ 是消息传递框架。我猜测这种混乱来自于 redis 确实具有一些有限的消息传递/发布订阅功能。要回答您的问题,是的,同样的图表适用于节点或 PHP。
【解决方案2】:

如果您希望浏览器通过长轮询获得实时反馈...我不认为 Redis 是一个选项。据我所知,Redis 不允许长轮询查询……如果查询时该值不存在……它将返回 null。

我的建议是使用 websockets 之类的东西。 PHP 有一些与 websockets 一起使用的库,我熟悉的一个是http://socketo.me/。但是,这意味着客户端将直接与您的 PHP 脚本交互。您可以通过在其前面添加负载平衡器并在不同的端口/盒子等上具有多个守护程序来扩展它。

如果你不必使用 PHP,我宁愿推荐 NodeJS 之类的东西。它是用来做这样的事情的,默认情况下它会做 Ratchet PHP 试图模仿的事情。

【讨论】:

  • 我认为 Redis 可以使用 ajax 长轮询。如果我错了,请纠正.. 基本上 PHP 守护程序脚本将使用 redis 来存储值,而 ajax 长轮询将检查来自 Redis 的响应...
  • 我想如果您通过另一个 PHP 脚本进行轮询(不确定来自前端的直接连接是否会起作用)然后让脚本保持连接打开直到 Redis 响应,这是可能的。然后,您可能可以使用会话标识符为每个用户会话/连接设置一个唯一密钥。
猜你喜欢
  • 2015-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-15
  • 2013-04-28
相关资源
最近更新 更多