I am using Swoole to develop my own WebSocket server with custom logic. I've made simple wrapper for Swoole\WebSocket\Server
and implemented some classes that work as event handlers. Here is wrapper example:
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);
}
}
And here is handler example:
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;
}
}
The thing is that it seems that $this->server->articles
points to different object instance every time server event raised.
I found that every time user opens connection, different workerId and workerPid used. This can somehow explain $this->server->articles
issue. I think (but not sure) I can configure server to use single worker and single process but this could lead to performance issues so this is not the case.
I found Swoole\Table
class but as I understood it can't hold its own copy in a row. I mean you can have STRING , INT or FLOAT in table row but not TABLE . I need hierarchy to represent this structure:
This data types also have some domain logic. Sure I think I can implement it using Swoole\Table
but what the cost?
So my question is: How can I share PHP objects inside Swoole WebSocket server if it is possible?
You can use PHP-DI to autowire your class, PHP-DI will instantiate your class(if not instantiated before) and pass the class instance whenever the method is invoked.
Or you can use static getter to achieve that, look below:
Article.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;
}
...
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.