85 lines
1.9 KiB
PHP
85 lines
1.9 KiB
PHP
<?php
|
|
|
|
namespace NoccyLabs\Mercureact\Broker;
|
|
|
|
use SplObjectStorage;
|
|
|
|
class Topic
|
|
{
|
|
const MAX_HISTORY_AGE = 180;
|
|
|
|
/** @var string Topic name */
|
|
private string $topic;
|
|
|
|
/** @var array<string,Message> */
|
|
private array $messages = [];
|
|
|
|
/** @var int Creation unixtime */
|
|
private int $created;
|
|
|
|
private SplObjectStorage $subscribers;
|
|
|
|
public function __construct(string $topic)
|
|
{
|
|
$this->topic = $topic;
|
|
$this->subscribers = new SplObjectStorage();
|
|
$this->created = time();
|
|
}
|
|
|
|
public function publish(Message $message)
|
|
{
|
|
// TODO check if message id has already been published
|
|
if (isset($this->messages[$message->id])) return;
|
|
|
|
$this->messages[$message->id] = $message;
|
|
|
|
|
|
foreach ($this->subscribers as $subscriber) {
|
|
// Skip sending private messages to unauthorized subscribers
|
|
if ($message->private && !$subscriber->isAuthorized()) {
|
|
continue;
|
|
}
|
|
// Deliver to the subscriber
|
|
$subscriber->deliver($message);
|
|
}
|
|
}
|
|
|
|
public function getAge(): int
|
|
{
|
|
return time() - $this->created;
|
|
}
|
|
|
|
public function getHistorySize(): int
|
|
{
|
|
return count($this->messages);
|
|
}
|
|
|
|
public function getSubscriberCount(): int
|
|
{
|
|
return count($this->subscribers);
|
|
}
|
|
|
|
public function addSubscriber(SubscriberInterface $subscriber)
|
|
{
|
|
$this->subscribers->attach($subscriber);
|
|
}
|
|
|
|
public function removeSubscriber(SubscriberInterface $subscriber)
|
|
{
|
|
$this->subscribers->detach($subscriber);
|
|
}
|
|
|
|
/**
|
|
* Garbage collect histry
|
|
*
|
|
*/
|
|
public function garbageCollect(): void
|
|
{
|
|
$this->messages = array_filter(
|
|
$this->messages,
|
|
fn($message) => $message->getAge() < self::MAX_HISTORY_AGE
|
|
);
|
|
}
|
|
}
|
|
|