GeniusesOfSymfony / WebSocketBundle

:part_alternation_mark: Websocket server for Symfony applications (powered by Ratchet), includes a Autobahn.JS based JavaScript client
MIT License
609 stars 140 forks source link

TopicPeriodicTimer only registered for one Topic, wrongly cleared if any one Topic has zero connections #476

Open Androbin opened 1 year ago

Androbin commented 1 year ago

Description

The function TopicPeriodicTimerInterface::registerPeriodicTimer takes a Topic parameter, but once the first Topic registers a timer, it is not called for any additional Topic. Furthermore, if any one Topic has zero connections, any and all timers registered within the TopicInterface are cleared.

Example code

<?php

namespace App\Websocket\Topic;

use Gos\Bundle\WebSocketBundle\Topic\TopicPeriodicTimerInterface;
use Gos\Bundle\WebSocketBundle\Topic\TopicPeriodicTimerTrait;
use Ratchet\Wamp\Topic;

class AcmePeriodicTopic extends AcmeTopic implements TopicPeriodicTimerInterface
{
    use TopicPeriodicTimerTrait;

    public function registerPeriodicTimer(Topic $topic): void
    {
        // Adds the periodic timer the first time a client connects to the topic
        $this->periodicTimer->addPeriodicTimer(
            $this,
            'hello',
            300,
            function () use ($topic) {
                $topic->broadcast('Hello world');
            }
        );
    }

    /**
     * Name of the topic.
     */
    public function getName(): string
    {
        return 'acme.periodic.topic';
    }
}

Steps

Androbin commented 1 year ago

The root problem is that TopicPeriodicTimer::addPeriodicTimer doesn't take the Topic passed to TopicPeriodicTimerInterface::registerPeriodicTimer as a parameter.