Implemented subscription logic

This commit is contained in:
2024-03-10 23:06:00 +01:00
parent 39869d605c
commit 87d47f8ce8
11 changed files with 125 additions and 43 deletions

View File

@ -3,10 +3,11 @@
namespace NoccyLabs\Mercureact\Http\Middleware;
use NoccyLabs\Mercureact\Broker\Message;
use NoccyLabs\Mercureact\Broker\SseSubscriber;
use NoccyLabs\Mercureact\Broker\TopicManager;
use NoccyLabs\Mercureact\Configuration;
use NoccyLabs\Mercureact\Http\Exeption\RequestException;
use NoccyLabs\Mercureact\Http\Exeption\SecurityException;
use NoccyLabs\Mercureact\Http\Exception\RequestException;
use NoccyLabs\Mercureact\Http\Exception\SecurityException;
use NoccyLabs\SimpleJWT\JWTToken;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
@ -80,9 +81,26 @@ class MercureHandler
body: $responseStream
);
$this->eventClients->attach($responseStream, $request);
$responseStream->on('close', function () use ($responseStream) {
$this->eventClients->detach($responseStream);;
$subscriber = new SseSubscriber($responseStream, $request);
$query = $request->getUri()->getQuery();
$query = explode("&", $query);
$topics = [];
foreach ($query as $param) {
if (!str_contains($param, "="))
throw new RequestException(
message: "Invalid request data",
code: RequestException::ERR_INVALID_REQUEST_DATA
);
[ $name, $value ] = array_map('urldecode', explode("=", $param, 2));
if ($name === 'topic') $topics[] = $value;
// TODO check claims for access
}
$this->topicManager->subscribe($subscriber, $topics);
//$this->eventClients->attach($responseStream, $request);
$responseStream->on('close', function () use ($subscriber, $topics) {
$this->topicManager->unsubscribe($subscriber, $topics);
});
return $response
@ -149,8 +167,9 @@ class MercureHandler
return Response::plaintext("urn:uuid:".$message->id."\n");
}
private function checkTopicClaims(string|array $topic, array $claims): bool
private function checkTopicClaims(string|array $topic, array $claims, bool $all=false): bool
{
// TODO match all topics if $all, reject on mismatch
foreach ((array)$topic as $match) {
foreach ($claims as $claim) {
if ($claim === "*") return true;
@ -169,6 +188,8 @@ class MercureHandler
*/
private function publishMercureMessage(Message $message): void
{
$this->topicManager->publish($message);
// foreach ($this->webSocketClients as $webSocket) {
// $webSocket->write(json_encode([
// 'type' => $message->type,