Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Event Listener in Symfony's console commands

I have used the GeniusesOfSymfony WebsocketBundle to integrate websockets into my system.

I am now trying to push a notification using the following code (this code is located in a symfony command)

protected function execute(InputInterface $input, OutputInterface $output)
{
    $messageData = array(
        'message' => $input->getArgument('message'),
        'title' => $input->getOption('title') === null ? $this->title : $input->getOption('title'),
        'timeout' => $input->getOption('timeout') === null ? $this->timeout : $input->getOption('timeout'),
    );

    $pusher = $this->getContainer()->get('gos_web_socket.zmq.pusher');
    $pusher->push($messageData, 'broadcast');

    $output->writeln('Message has been sent');
}

This works perfectly. However, how can I check if the push() function has actually pushed my message to the scoket server? I want to be able to output "Message has been sent" only if this is actually true.

Update

The GeniusesOfSymfony documentation learned me that there are two events to check if it has been a success or an error.

gos_web_socket.push_success
gos_web_socket.push_fail

But I think i can't just do:

if ($event('gos_web_socket.push_success')) {
    $output->writeLn("Message has been sent");
} else {
    $output->writeLn("Message has NOT been sent");
}
like image 344
Peter Avatar asked Dec 17 '25 17:12

Peter


1 Answers

You should make yourself familiar with the event-dispatcher component of symfony. The underlying pattern is the Observer Pattern.

To put it short: Events are dispatched from a service (the subject) to enable other services (the observers) to react on them.

This is an example how you may implement this for gos_web_socket.push_success and gos_web_socket.push_fail

First, create your observers (EventListeners):

use Gos\Bundle\WebSocketBundle\Event\PushHandlerEvent;
class AcmeListener
{
    // ...

    public function onSuccess(PushHandlerEvent $event)
    {
        // ... do something
    }

    public function onFailure(PushHandlerEvent $event)
    {
        // ... do something
    }
}

Register this listeners to the according events in your services.yml:

services:

  acme.socket_listeners:
    class:  "AcmeListener"
    tags:
      - { name: kernel.event_listener, event: gos_web_socket.push_success, method: onSuccess }
      - { name: kernel.event_listener, event: gos_web_socket.push_fail, method: onFailure }

This should give you a start.

Update:

As event-listeners are nothing more than callables (read: functions), you could implement them directly in your command as well to have access to your $output:

protected function execute(InputInterface $input, OutputInterface $output)
{
    $messageData = array(
        'message' => $input->getArgument('message'),
        'title' => $input->getOption('title') === null ? $this->title : $input->getOption('title'),
        'timeout' => $input->getOption('timeout') === null ? $this->timeout : $input->getOption('timeout'),
    );

    $pusher = $this->getContainer()->get('gos_web_socket.zmq.pusher');
    $eventDispatcher = $this->getContainer()->get('event_dispatcher');
    $eventDispatcher->addListener(
        'gos_web_socket.push_success',
        function (PushHandlerEvent $event) use ($output) {
            $output->writeln('Message has been sent');
        }
    );
    $pusher->push($messageData, 'broadcast');


}
like image 70
Jojo Avatar answered Dec 19 '25 05:12

Jojo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!