Closed vittore closed 5 years ago
I'd suggest not extending ContainerAwareCommand
since that is deprecated and injecting the pusher as a dependency (either as a constructor argument or a setPusher(PusherInterface $pusher)
call. If it's too painful we can add public: true
onto the pusher service definitions but personally I think the scope of what's considered a public service by the bundle should be kept to a minimum (I did do a pass to explicitly mark things public/private, it looks like the pushers are inheriting the public:false
set on the abstract pusher definition as a result).
The other option is you can use a compiler pass in your own application to make the service public if you really need to but this kind of $this->container->get()
stuff is really not the encouraged practice anymore, it's preferred to use explicit dependency injection instead.
Uhm.... something goes wrong. I done:
namespace App\Command;
use Gos\Bundle\WebSocketBundle\Pusher\PusherInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
class SendMessageCommand extends Command
{
private $pusher;
public function __construct(PusherInterface $pusher)
{
$this->pusher=$pusher;
parent::__construct();
}
protected function configure()
{
$this->setName('send-socket:message')
->setDescription('Send message')
->addOption(
'user',
null,
InputOption::VALUE_REQUIRED,
'user',
''
)
->addOption(
'message',
null,
InputOption::VALUE_REQUIRED,
'message',
''
);
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$pushMessage['text']=$input->getOption('message');
$pushMessage['to'] =strtolower($input->getOption('user'));
$this->pusher->push($pushMessage, 'you4b_message');
}
}
But when run I get:
In DefinitionErrorExceptionPass.php line 37:
Cannot autowire service "App\Command\SendMessageCommand": argument "$pusher" of method "__construct()" references interface "Gos\Bundle\WebSocketBundle\Pusher\PusherInterface" but no such service exists. You should maybe alias this interface to one of these existing services: "gos_web_socket.wamp.pusher.data_collector", "gos_web_socket.wamp.pusher.data_collector.inner".
What is correct definition for this service?
Thanks. v.
You have to manually specify the $pusher
argument to get the correct pusher. The PusherInterface
isn't aliased to anything since by default all of the pusher services are available as services and stripped out if they aren't enabled, so you can't autowire the pushers unfortunately. Here's an example service definition I use:
App\EventListener\BroadcastResourceCreatedListener:
tags:
- { name: kernel.event_listener, event: app.resource_created, method: onResourceCreated }
- { name: monolog.logger, channel: app }
arguments:
'$pusher': '@gos_web_socket.wamp.pusher'
Also, make sure you typehint the interface because when the kernel is in debug mode (i.e. dev environment) the pushers are decorated so if you typehinted Gos\Bundle\WebSocketBundle\Pusher\Wamp\WampPusher
instead of Gos\Bundle\WebSocketBundle\Pusher\PusherInterface
you'll run into problems because the decorating Gos\Bundle\WebSocketBundle\DataCollector\PusherDecorator
class is used.
Sorry but I don't undestand. I do this in services.yml:
services:
App\Command\SendMessageCommand:
arguments:
'$pusher': '@gos_web_socket.wamp.pusher'
And this in command definition:
<?php
namespace App\Command;
use Gos\Bundle\WebSocketBundle\Pusher\PusherInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
class SendMessageCommand extends Command
{
private $pusher;
public function __construct(PusherInterface $pusher)
{
$this->pusher=$pusher;
parent::__construct();
}
protected function configure()
{
$this->setName('send-socket:message')
->setDescription('Send message')
->addOption(
'user',
null,
InputOption::VALUE_REQUIRED,
'user',
''
)
->addOption(
'message',
null,
InputOption::VALUE_REQUIRED,
'message',
''
);
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$pushMessage['text']=$input->getOption('message');
$pushMessage['to'] =strtolower($input->getOption('user'));
$this->pusher->push($pushMessage, 'you4b_message');
}
}
But I get this error:
php bin/console send-socket:message --user user1-it --message caio
[WARNING] Some commands could not be registered:
In MessageSerializer.php line 35:
Class 'Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer' not found
There are no commands defined in the "send-socket" namespace.
I "simply" want to send a push message to a specific user via php bin/console
command.
Sigh. :(
v.
In MessageSerializer.php line 35: Class 'Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer' not found
You need to composer require symfony/serializer
as indicated in the "suggest" section of the Composer install. That will probably fix your issue with the command not being registered since its dependencies aren't all being resolved correctly.
It's works.
Thanks a lot. v.
Hi,
I'm using symfony 3.4 (with flex) and autowire; in composer.json I have:
so version 2 is used.
Now I have a command (
extends ContainerAwareCommand
) that it will send a message:But i get the error:
Is there an example for push with version 2?
Thanks in advance. v