PHP:在多个请求中保持API连接到API

JDe*_*ler 3 php wordpress https curl keep-alive

我正在为wordpress编写一个插件,需要为用户发出的每个请求调用API.

这些API调用使用HTTPS协议完成.目前,对于每个新用户请求,我需要重新打开HTTPS连接.

是的,curl允许持久连接(重用句柄或使用多句柄),但我想在多个用户请求中保持连接.

那么:是否可以通过多个PHP进程保持HTTPS连接打开并重用它?另一种方法是让用户的浏览器进行API谈话.但如果有可能我想避免这种情况.

Jos*_*bou 6

虽然许多人会告诉你PHP不是为此设计的(并且它们在技术上是正确的),但是这种问题已经通过使用持久性事件循环得到了解决.例如,使用node.js通过JavaScript实现服务器端并发,它启动在侦听事件的单个线程上运行的循环.而不是典型的PHP设置,它从Web服务器接收的每个请求都启动一个新线程,您可以使用与(不幸命名的)ReactPHP类似的架构.

你的概念最大的障碍是它作为WordPress插件运行.WordPress往往是极低的共同点,所以如果你想让它工作,你将需要排除一些安装.最大的诀窍是你无法(轻松)使用你的WordPress路由页面从这个ReactPHP循环加载.我知道你想避免额外的连接,但您可以通过连接到本地服务器ReactPHP,而不是每次都得到一个远程连接在更低的延迟得到这个运行.

如果您的服务器允许您打开某些本地端口,则可以创建一个新的ReactPHP服务器,如下所示:

$socket = new React\Socket\Server(8080, $loop);
Run Code Online (Sandbox Code Playgroud)

如果您没有端口访问权限,则可以通过本地套接字设置连接.这可能需要更多设置,并且在一般安装上工作会更棘手:

$socket = new React\Socket\Server('unix://path/to/unix/socket', $loop);
Run Code Online (Sandbox Code Playgroud)

我没有完成设置的步骤,但是如果你能够实现这一点,我认为这将是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 */)
    );
});
Run Code Online (Sandbox Code Playgroud)

我会留下ExternalService你的意思,因为我相信你已经在这里设置了一些东西.

对于您的WordPress页面,他们现在可以向极低延迟的本地ReactPHP发出请求.如果要使用套接字,可以尝试使用fsockopen,如果使用套接字,则可以尝试使用简单的curl.

另一个棘手的问题是初始化服务器.如果它是您拥有的服务器,具有shell访问权限,可以运行cron作业,或者exec()它非常简单:只需运行您的服务器脚本即可.否则,您需要花费几个小时来配置服务器以在新请求上运行此脚本,而不是将其计时.

另一种选择是翻转它:如果您可以在ReactPHP下提供整个应用程序(而不是首先点击WP调度程序),您可以在没有所有本地连接的情况下执行此操作并直接跳转到持久连接.当然,这会使得将它作为WordPress插件分发是不可能的.

当这一切都说完了,你应该问问自己是否真的值得付出努力来节省这些请求的延迟.我不是你所以我不能说,但如果你真的需要继续使用WordPress或PHP,这就是你可以做到的.你会发现它是一个指数简单的问题,如果你可以将WordPress的部分(也许是为了//mydomain.com/blog去WP,一切从您的ReactPHP应用服务).如果你可以离开PHP,它可以从简单到使用持久连接更容易配置而不是没有,因为这是node或Go中的标准方法.从结构上讲,它与在服务器启动时连接到数据库没有太大区别,而不是在每个连接上.