【问题标题】:How to talk between HTTP request & cli class objects如何在 HTTP 请求和 cli 类对象之间进行通信
【发布时间】:2016-08-18 12:40:04
【问题描述】:

我有一个正在运行的应用程序列出了 HTTP 请求。每个请求都被传递到单个页面,其中实例化了框架对象$app,这负责路由/控制器/模型等。

现在我有另一个类,它的对象是通过实例化的。一个 CLI 脚本让我们称之为$cliApp 现在的问题是我如何让两个对象互相交谈。 $app 每次有新请求时都会实例化。

$cliApp 仅在脚本运行时实例化一次。此脚本通过$loop 对象PHP React Event loop 循环运行。

Cli 应用正在运行 websocket。所以基本上我希望通过 http 和套接字进行通信。 http api。

附: :

现在我有一种使用消息队列的解决方案,例如0mq 等,但这似乎有点矫枉过正,因为我不想扩大规模并保持简单。

我目前正在尝试并感觉正确的另一个解决方案是在$http 请求创建的线程和$cli 请求创建的线程之间共享一个SptStorageObject。也许这是依赖注入的问题,我很难分享这个$store 对象。

【问题讨论】:

  • 对应用程序的每个请求都会在服务器上启动一个新线程。 CLI 也是如此。 PHP 中的线程从不共享任何东西。您需要一个消息传递系统来实现通信。所以你在正确的轨道上。
  • 我不完全确定我是否了解这里正在运行多少进程。基本上,您是否启动了 PHP 进程的一个实例(react http 服务器)并且 $cliApp 在其中?还是这里产生了多个 php 实例?
  • @Method 我只是在使用 React 事件循环和 Ratchet Websockets。 HTTP 请求来自另一个框架,即使用 symfony/silex 组件。
  • @colburton 是否可以在两者之间共享存储对象?如果是这样,请您指导我。我想实例化这个存储对象一次并在 2 之间共享?
  • 对象共享在 PHP 中是不可能的。这是设计使然。解决方案涉及一些其他服务,例如 Redis 或 Memcache。如果您与客户端(Websockets)有开放连接,您可能会考虑使用 Redis,因为它提供了“通道”,可以通知您存储数据的更改,而无需您的脚本每秒轮询一次。

标签: php oop design-patterns zeromq reactphp


【解决方案1】:

如果我理解正确,您有(假设已注明):

  • 一个通过 HTTP 进行通信的普通 PHP Web 应用程序(可能在 Apache 或类似的 Web 服务器上)
  • 一个长期运行的 PHP cli 应用,通过 websocket 进行通信。

大概这两个应用程序都在持续接收来自网络客户端的通信。据推测,它们也有自己的持久性数据存储,例如 MySQL 数据库或类似数据库,甚至可能共享同一个。

我将假设您需要的不仅仅是每个应用程序从持久数据存储中访问最新数据(或者两个进程使用单独的数据存储),而且您实际上需要按需两个进程之间的通信。

您在消息队列方面走在了正确的道路上,但正如您所注意到的,当您已经拥有两个独立工作的通信层时,添加第三个专用的进程间通信层是不必要的复杂性。

您需要让您的 cli 应用在需要启动与您的网络应用程序通信时使用 HTTP,并让您的网络应用程序在需要启动与您的 cli 应用程序通信时使用网络套接字。

这在实践中看起来相当简单。

在您的 cli 应用程序中,只需使用 cURL 来启动与您的 Web 应用程序的 HTTP 连接。这相当简单,网络上有无穷无尽的资源可以帮助您一路走来,如果您遇到困难,那么带着针对您的问题的新问题来到这里会让您继续前进。您的网络应用程序中的所有这些要求如下:

  • 如果基本面向客户端的页面不够用,cli 应用可以向其发送请求的适当端点
  • 如果 cli 应用需要访问 Web 客户端不应该使用的数据,则可以通过某种方法对其进行身份验证

要让您的 Web 应用程序启动与 cli 应用程序的 websocket 连接,这有点复杂,因为我不知道有任何专门针对 websocket 协议的原生 PHP 功能。但是,我确实发现 this (extremely permissive) github project 声称可以让您设置 Web 套接字服务器,而 also includes a client script 可以在您的 Web 应用程序进程存在时用于连接和发送/接收数据,然后关闭完成后将其放下。它似乎仍然有一些最小的活动,您可以直接使用它或将其用作编写自己的 websocket 客户端的起点。

在这种情况下,就像在相反的情况下一样,您需要 cli 客户端识别和验证来自 Web 客户端的流量,以便它可以为它提供适当的数据。

如果由于某种原因此方案不适合您,那么您将返回消息队列或共享数据存储(有人建议使用 redis,在某些情况下可以充当混合数据存储/消息队列)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-16
    • 2023-02-09
    • 2010-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多