[英]How can I share PHP objects between Swoole workers/processes
我正在使用 Swoole 开发我自己的具有自定义逻辑的 WebSocket 服务器。 我为Swoole\WebSocket\Server
制作了简单的包装器,并实现了一些用作事件处理程序的类。 这是包装器示例:
final class Server
{
private WebSocketServer $server; // Alias used here, this is Swoole web socket server
public Collection $articles;
public function __construct()
{
$this->server = new WebSocketServer('0.0.0.0', 9501);
$this->articles = new Collection;
$openHandler = new OpenHandler($this, ...);
$messageHandler = new MessageHandler($this);
$closeHandler = new CloseHandler($this);
$this->on(Event::Open, $openHandler);
$this->on(Event::Message, $messageHandler);
$this->on(Event::Close, $closeHandler);
}
public function run(): void
{
$this->server->start();
}
private function on(Event $event, callable $callback): void
{
$this->server->on($event->name, $callback);
}
}
这是处理程序示例:
final class CloseHandler
{
private Server $server;
public function __construct(Server $server)
{
$this->server = $server;
}
public function __invoke(WebSocketServer $server, int $descriptor): void
{
$d = new Descriptor($descriptor);
if (!$user = $this->server->articles->findUserByDescriptor($d)) {
return;
}
$user->getDescriptors()->remove($d);
echo "User {$user->getId()->asInt()} disconnected..." . PHP_EOL;
}
}
问题是$this->server->articles
似乎每次引发服务器事件时都指向不同的 object 实例。
我发现每次用户打开连接时,都会使用不同的 workerId 和 workerPid。 这可以以某种方式解释$this->server->articles
问题。 我认为(但不确定)我可以将服务器配置为使用单个工作者和单个进程,但这可能会导致性能问题,所以情况并非如此。
我找到Swoole\Table
class 但据我了解,它不能连续保存自己的副本。 我的意思是你可以在表格行中有STRING 、 INT或FLOAT ,但不能有TABLE 。 我需要层次结构来表示这个结构:
这种数据类型也有一些领域逻辑。 当然,我认为我可以使用Swoole\Table
来实现它,但成本是多少?
所以我的问题是:如果可能的话,我如何在 Swoole WebSocket 服务器中共享 PHP 对象?
您可以使用PHP-DI自动装配您的 class,PHP-DI 将实例化您的类(如果之前未实例化)并在调用该方法时传递 class 实例。
或者您可以使用 static getter 来实现,如下所示:
文章.php
<?php
class Article
{
private static Article $article;
public static function getInstance(): Article
{
if (!isset(self::$article)) {
self::$article = new Article();
}
return self::$article;
}
}
CloseHander.php
<?php
class CloseHandler
{
...
public function __invoke()
{
...
if (!$user = Article::getInstance()->findUserByDescriptor($d)) {
return;
}
...
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.