mercureact/src/Http/Middleware/WebSocketHandler.php

71 lines
2.0 KiB
PHP
Raw Normal View History

2024-03-10 20:22:28 +01:00
<?php
namespace NoccyLabs\Mercureact\Http\Middleware;
use NoccyLabs\Mercureact\Broker\TopicManager;
use NoccyLabs\Mercureact\Configuration;
use NoccyLabs\React\WebSocket\WebSocketConnection;
use NoccyLabs\React\WebSocket\WebSocketMiddleware;
use Psr\Http\Message\ServerRequestInterface;
use React\EventLoop\Loop;
use React\EventLoop\LoopInterface;
use React\Promise\Promise;
use React\Promise\PromiseInterface;
use SplObjectStorage;
class WebSocketHandler
{
private LoopInterface $loop;
private WebSocketMiddleware $webSocket;
public function __construct(
private Configuration $config,
private SplObjectStorage $webSocketClients,
private TopicManager $topicManager,
?LoopInterface $loop=null
)
{
$this->loop = $loop ?? Loop::get();
$this->webSocket = new WebSocketMiddleware();
$this->webSocket->on(WebSocketMiddleware::EVENT_CONNECTION, $this->onWebSocketConnection(...));
}
/**
*
*
* @param ServerRequestInterface $request
* @param callable $next
* @return PromiseInterface
*/
public function __invoke(ServerRequestInterface $request, callable $next): PromiseInterface
{
return new Promise(
function (callable $resolve, callable $reject) use ($next, $request) {
if ($request->getUri()->getPath() == "/.well-known/mercure")
$resolve(call_user_func($this->webSocket, $request, $next));
else
$resolve($next($request));
}
);
}
/**
*
*
*/
private function onWebSocketConnection(WebSocketConnection $connection)
{
$this->webSocketClients->attach($connection);
$connection->on('close', function () use ($connection) {
$this->webSocketClients->detach($connection);
});
$request = $connection->getServerRequest();
$topic = $request->getQueryParams()['topic'][0]??'';
$connection->setGroup($topic);
}
}