2024-03-13 01:37:46 +00:00
|
|
|
<?php
|
|
|
|
|
2024-03-13 23:32:44 +00:00
|
|
|
namespace NoccyLabs\Mercureact\Broker\Subscriber;
|
2024-03-13 01:37:46 +00:00
|
|
|
|
|
|
|
use Evenement\EventEmitterInterface;
|
|
|
|
use Evenement\EventEmitterTrait;
|
2024-03-13 23:32:44 +00:00
|
|
|
use NoccyLabs\Mercureact\Broker\Message;
|
|
|
|
use NoccyLabs\Mercureact\Broker\TopicManager;
|
2024-03-13 01:37:46 +00:00
|
|
|
use NoccyLabs\React\WebSocket\WebSocketConnection;
|
|
|
|
use NoccyLabs\SimpleJWT\JWTToken;
|
|
|
|
use Psr\Http\Message\ServerRequestInterface;
|
|
|
|
use React\Stream\WritableStreamInterface;
|
|
|
|
use Symfony\Component\Uid\Uuid;
|
|
|
|
|
|
|
|
class WsSubscriber implements SubscriberInterface, EventEmitterInterface
|
|
|
|
{
|
|
|
|
|
|
|
|
use EventEmitterTrait;
|
|
|
|
|
|
|
|
const EVENT_SUBSCRIBE = 'subscribe';
|
|
|
|
const EVENT_UNSUBSCRIBE = 'unsubscribe';
|
|
|
|
const EVENT_ERROR = 'error';
|
|
|
|
|
|
|
|
private string $id;
|
|
|
|
|
|
|
|
public function __construct(
|
|
|
|
private WebSocketConnection $stream,
|
|
|
|
private ServerRequestInterface $request,
|
|
|
|
private TopicManager $topicManager,
|
|
|
|
private ?JWTToken $token = null
|
|
|
|
)
|
|
|
|
{
|
|
|
|
$this->id = (string)Uuid::v7();
|
|
|
|
$this->stream->on('text', $this->onWebSocketData(...));
|
|
|
|
}
|
|
|
|
|
|
|
|
private function onWebSocketData(string $data): void
|
|
|
|
{
|
|
|
|
$toks = str_getcsv($data, " ");
|
|
|
|
switch (array_shift($toks)) {
|
|
|
|
case 'auth':
|
|
|
|
$this->stream->write('{"ok":true}');
|
|
|
|
break;
|
|
|
|
case 'subscribe':
|
|
|
|
$this->topicManager->subscribe($this, $toks);
|
|
|
|
$this->stream->write('{"ok":true}');
|
|
|
|
break;
|
|
|
|
case 'unsubscribe':
|
|
|
|
$this->topicManager->unsubscribe($this, $toks);
|
|
|
|
$this->stream->write('{"ok":true}');
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
$this->stream->write('{"ok":false}');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function deliver(Message $message): void
|
|
|
|
{
|
|
|
|
$this->stream->write(json_encode([
|
|
|
|
'event' => $message->type,
|
|
|
|
'topic' => $message->topic,
|
|
|
|
'data' => $message->data
|
|
|
|
], JSON_UNESCAPED_SLASHES));
|
|
|
|
}
|
|
|
|
|
2024-03-13 23:45:26 +00:00
|
|
|
public function isAuthenticated(): bool
|
2024-03-13 01:37:46 +00:00
|
|
|
{
|
|
|
|
return $this->token && $this->token->isValid();
|
|
|
|
}
|
|
|
|
|
2024-03-14 13:03:27 +00:00
|
|
|
public function getMercureClaims(): ?array
|
|
|
|
{
|
|
|
|
return $this->request->getAttribute('mercure.claims');
|
|
|
|
}
|
|
|
|
|
2024-03-13 01:37:46 +00:00
|
|
|
public function getPayload(): array
|
|
|
|
{
|
|
|
|
return $this->request->getAttribute('mercure.payload')??[];
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getId(): string
|
|
|
|
{
|
|
|
|
return "urn:uuid:".$this->id;
|
|
|
|
}
|
|
|
|
}
|