虽然很多人会告诉您 PHP 不是为此而设计的(而且他们在技术上是正确的),但这种问题已经通过使用持久事件循环得到了解决。例如服务器端并发是通过使用 node.js 使用 JavaScript 实现的,它启动一个在单个线程上运行的循环以侦听事件。与典型的 PHP 设置不同,它会在它从网络服务器收到的每个请求中启动一个新线程,您可以使用类似的架构与(不幸地命名为)ReactPHP。
您的概念最大的障碍是它作为 WordPress 插件运行。 WordPress 往往是非常最低公分母,因此如果您希望它起作用,您将需要排除一些安装。最大的技巧是您将无法(轻松)使用您的 WordPress 路由页面从这个 ReactPHP 循环加载。我知道您正在尝试避免额外的连接,但是您可以通过连接到本地 ReactPHP 服务器来以更低的延迟运行它,而不是每次都获得远程连接。
如果你的服务器允许你打开一些本地端口,你可以像这样创建一个新的 ReactPHP 服务器:
$socket = new React\Socket\Server(8080, $loop);
如果您没有端口访问权限,则可以通过本地套接字设置连接。这可能需要更多的设置时间,并且在进行常规安装时会更加棘手:
$socket = new React\Socket\Server('unix://path/to/unix/socket', $loop);
我还没有完成设置步骤,但是如果你可以让它工作,我认为这将是 WordPress 最可靠的方法,因为你总是有一些文件系统访问您的插件。
您应该能够看到如何使用Closure 来构建您的服务器,或者使用一些静态类方法(首选,因为从那时起该类可以负责在它被丢弃时重新连接) .
use React\Http\Server;
use Psr\Http\Message\ServerRequestInterface as Request;
use React\Http\Response;
use MyNamespace\Api\ExternalService;
$server = new Server(function (Request $request) {
$ch = ExternalService::getConnectionHandle();
// Do something with your $ch based on the $request here
return new Response(
200,
['Content-Type' => 'application/json'],
json_encode(/* some data from your request */)
);
});
我将把ExternalService 留给你写,因为我确定你已经在这里设置了一些东西。
对于您的 WordPress 页面,他们现在可以向您的极低延迟本地 ReactPHP 发出请求。如果你想使用套接字,你可以尝试fsockopen,或者如果你通过 TCP 来使用简单的 curl。
另一个难点是初始化服务器。如果它是您拥有的服务器,可以访问 shell,可以运行 cron 作业,或者拥有 exec(),这非常简单:只需运行您的服务器脚本。否则,您将需要花费几个小时来配置您的服务器,以便在新请求上运行此脚本并且不会超时。
另一种选择是翻转它:如果您可以让整个应用程序在 ReactPHP 下提供服务(而不是先点击 WP 调度程序),您可以在没有所有本地连接的情况下执行此操作并直接跳转到持久连接。当然,这会使它无法作为 WordPress 插件分发。
说完这些,您应该问问自己,节省这些请求的延迟是否真的值得付出努力。我不是你,所以我不能说,但如果你真的需要继续使用 WordPress 或 PHP,你可以这样做。如果您可以删除 WordPress 部分,您会发现这是一个指数级更简单的问题(也许让 //mydomain.com/blog 转到 WP,其他一切都从您的 ReactPHP 应用程序提供)。如果您可以脱离 PHP,那么使用持久连接配置它会从更简单变为可能更容易配置,因为这是 node 或 Go 中的标准方法。在架构上,它与在服务器启动时连接到您的数据库没有太大区别,而不是在每个连接上。