PHP:在多个请求中保持与 API 的 HTTPS 连接打开
PHP: Keep HTTPS Connection to API open throughout multiple requests
我正在为 wordpress 编写一个插件,需要为用户发出的每个请求调用 API。
这些 API 调用是使用 HTTPS 协议完成的。
目前,对于每个新用户请求,我都需要重新打开 HTTPS 连接。
是的,curl 允许持久连接(重复使用句柄或使用多句柄),但我想在多个用户请求中保持连接。
因此:是否可以通过多个 PHP 进程保持 HTTPS 连接打开并重新使用它?另一种方法是让用户的浏览器与 API-对话。但如果可能的话,我想避免这种情况。
虽然很多人会告诉您 PHP 不是为此设计的(并且它们在技术上是正确的),但此类问题已经通过使用持久事件循环得到解决。例如服务器端并发是通过 JavaScript 通过使用 node.js 实现的,它在侦听事件的单个线程上启动循环 运行ning。不同于典型的 PHP 设置,它在每次从网络服务器收到请求时启动一个新线程,您可以使用类似的架构(不幸的是命名) ReactPHP.
您的概念最大的障碍是它 运行宁作为 WordPress 插件。 WordPress 往往是 非常 最低公分母,所以如果你想让它工作,你将需要排除一些安装。最大的技巧是您将无法(轻松地)使用您的 WordPress 路由页面从这个 ReactPHP 循环加载。我知道您正在尝试避免额外的连接,但您可以通过连接到本地 ReactPHP 服务器以更低的延迟获得此 运行ning,而不是每次都获取远程连接。
如果您的服务器允许您打开一些本地端口,您可以像这样创建一个新的 ReactPHP 服务器:
$socket = new React\Socket\Server(8080, $loop);
如果您没有端口访问权限,您可以通过本地套接字设置连接。这可能需要更多的时间来设置,并且在进行常规安装时会更棘手:
$socket = new React\Socket\Server('unix://path/to/unix/socket', $loop);
我还没有完成设置的步骤,但是 如果 你可以让它工作,我认为这将是 WordPress 最可靠的方法,因为你将始终在您的插件中访问一些文件系统。
你应该能够看到如何断开你的持久连接,或者使用你构建服务器的 Closure
,或者一些静态的 class 方法(首选,从那时起 class 可以负责在掉线时重新连接)。
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 页面,他们现在可以向您的极低延迟本地 React 发出请求PHP。如果你想使用套接字,你可以尝试 fsockopen,或者如果你通过 TCP 使用简单的卷曲。
另一个难点是初始化服务器。如果它是您拥有的服务器,可以 shell 访问,可以 运行 cron
工作,或者有 exec()
,这很简单:只需 运行 您的服务器脚本。否则,您将需要花几个小时将您的服务器配置为 运行 这个脚本在新请求时不会超时。
另一种选择是翻转它:如果你可以让整个应用程序在 ReactPHP 下提供服务(而不是先点击 WP 调度程序),你可以在没有所有本地连接的情况下做到这一点,并且直接跳转到持久连接。当然,这将使它无法作为 WordPress 插件分发。
说完一切后,您应该问问自己,节省这些请求的延迟是否真的值得付出努力。我不是你,所以我不能说,但如果你真的需要继续使用 WordPress 或 PHP,这就是你可以做到的。如果您可以删除 WordPress 部分(也许 //mydomain.com/blog
转到 WP,其他所有内容都由您的 ReactPHP 应用程序提供),您会发现这是一个指数级简单的问题。如果你可以摆脱 PHP,那么配置持久连接比没有配置更简单,因为这是 node 或 Go 中的标准方法。在架构上,它与在服务器启动时连接到您的数据库没有太大区别,而不是在每次连接时。
我最终通过浏览器发出了这些请求。
浏览器在服务器要求时保持 HTTP(S) 连接打开。
唉,这个解决方案有一些缺点:
- 认证难度较大
- 服务器负载增加,因为必须维护更多连接
- 解决方案需要额外的 JavaScript
但是请求速度要快得多(大约 3 倍)并且 WordPress 运行 服务器上的负载最小化。
我正在为 wordpress 编写一个插件,需要为用户发出的每个请求调用 API。
这些 API 调用是使用 HTTPS 协议完成的。 目前,对于每个新用户请求,我都需要重新打开 HTTPS 连接。
是的,curl 允许持久连接(重复使用句柄或使用多句柄),但我想在多个用户请求中保持连接。
因此:是否可以通过多个 PHP 进程保持 HTTPS 连接打开并重新使用它?另一种方法是让用户的浏览器与 API-对话。但如果可能的话,我想避免这种情况。
虽然很多人会告诉您 PHP 不是为此设计的(并且它们在技术上是正确的),但此类问题已经通过使用持久事件循环得到解决。例如服务器端并发是通过 JavaScript 通过使用 node.js 实现的,它在侦听事件的单个线程上启动循环 运行ning。不同于典型的 PHP 设置,它在每次从网络服务器收到请求时启动一个新线程,您可以使用类似的架构(不幸的是命名) ReactPHP.
您的概念最大的障碍是它 运行宁作为 WordPress 插件。 WordPress 往往是 非常 最低公分母,所以如果你想让它工作,你将需要排除一些安装。最大的技巧是您将无法(轻松地)使用您的 WordPress 路由页面从这个 ReactPHP 循环加载。我知道您正在尝试避免额外的连接,但您可以通过连接到本地 ReactPHP 服务器以更低的延迟获得此 运行ning,而不是每次都获取远程连接。
如果您的服务器允许您打开一些本地端口,您可以像这样创建一个新的 ReactPHP 服务器:
$socket = new React\Socket\Server(8080, $loop);
如果您没有端口访问权限,您可以通过本地套接字设置连接。这可能需要更多的时间来设置,并且在进行常规安装时会更棘手:
$socket = new React\Socket\Server('unix://path/to/unix/socket', $loop);
我还没有完成设置的步骤,但是 如果 你可以让它工作,我认为这将是 WordPress 最可靠的方法,因为你将始终在您的插件中访问一些文件系统。
你应该能够看到如何断开你的持久连接,或者使用你构建服务器的 Closure
,或者一些静态的 class 方法(首选,从那时起 class 可以负责在掉线时重新连接)。
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 页面,他们现在可以向您的极低延迟本地 React 发出请求PHP。如果你想使用套接字,你可以尝试 fsockopen,或者如果你通过 TCP 使用简单的卷曲。
另一个难点是初始化服务器。如果它是您拥有的服务器,可以 shell 访问,可以 运行 cron
工作,或者有 exec()
,这很简单:只需 运行 您的服务器脚本。否则,您将需要花几个小时将您的服务器配置为 运行 这个脚本在新请求时不会超时。
另一种选择是翻转它:如果你可以让整个应用程序在 ReactPHP 下提供服务(而不是先点击 WP 调度程序),你可以在没有所有本地连接的情况下做到这一点,并且直接跳转到持久连接。当然,这将使它无法作为 WordPress 插件分发。
说完一切后,您应该问问自己,节省这些请求的延迟是否真的值得付出努力。我不是你,所以我不能说,但如果你真的需要继续使用 WordPress 或 PHP,这就是你可以做到的。如果您可以删除 WordPress 部分(也许 //mydomain.com/blog
转到 WP,其他所有内容都由您的 ReactPHP 应用程序提供),您会发现这是一个指数级简单的问题。如果你可以摆脱 PHP,那么配置持久连接比没有配置更简单,因为这是 node 或 Go 中的标准方法。在架构上,它与在服务器启动时连接到您的数据库没有太大区别,而不是在每次连接时。
我最终通过浏览器发出了这些请求。 浏览器在服务器要求时保持 HTTP(S) 连接打开。
唉,这个解决方案有一些缺点:
- 认证难度较大
- 服务器负载增加,因为必须维护更多连接
- 解决方案需要额外的 JavaScript
但是请求速度要快得多(大约 3 倍)并且 WordPress 运行 服务器上的负载最小化。