mikemadisonweb / yii2-rabbitmq

RabbitMQ Extension for Yii2
MIT License
72 stars 32 forks source link

I can't configure yii2-rabbitmq. #18

Closed rootlevel closed 7 years ago

rootlevel commented 7 years ago

Hi! Firstly... thanks to all contributors for awesome package! The second one, can some one explain to me why my producer throw this error (if i trying place simple message to my queue).

Missing required parameter "user" when instantiating "PhpAmqpLib\Connection\AbstractConnection".

rabbitmq component configuration (in both... console.php and web.php file configs)

return [
        'class' => 'mikemadisonweb\rabbitmq\Configuration',
        'connections' => [
            'default' => [
                'host' => '192.168.22.101',
                'port' => '5672',
                'user' => 'loginxxx',
                'password' => 'xxx',
                'vhost' => 'interpretation_host',
                'heartbeat' => 0,
            ],
        ],
        'producers' => [
            'event_main_interpretation' => [
                'connection' => 'default',
                'exchange_options' => [
                    'name' => 'interpretation',
                    'type' => 'direct',
                ],
            ],
        ],
        'consumers' => [
            'event_main_interpretation' => [
                'connection'       => 'default',
                'exchange_options' => [
                    'name' => 'main_interpretation',
                    'type' => 'direct',
                ],
                'queue_options' => [
                    'name'         => 'interpretation',
                    'routing_keys' => ['interpretation'],
                    'durable'      => true,
                    'auto_delete'  => false,
                ],
                'callback' => \app\commands\interpretation\InterpretationDataConsumer::class,
            ],
        ],
];

My container definition ("included" in web and console config)

return [
    'definitions' => [],
    'singletons' => [
        'rabbitmq.main-interpretation.consumer' => [
            [
                'class' => \app\commands\interpretation\InterpretationDataConsumer::class,
            ],
            [
                'some-dependency-consumer' => \yii\di\Instance::of('\app\commands\interpretation\InterpretationDataConsumer'),
            ],
        ],
        'rabbitmq.main-interpretation.producer' => [
            [
                'class' => \app\commands\interpretation\InterpretationDataProducer::class,
            ],
            [
                'some-dependency-producer' => \yii\di\Instance::of('\app\commands\interpretation\InterpretationDataProducer'),
            ],
        ],
    ],
];

Code in controller which place message to queue:

            \Yii::$app->rabbitmq->load();

            $producer = \Yii::$container->get('rabbitmq.main-interpretation.producer');

            $msg = serialize([
                'val1' => 1,
                'val2' => 2,
            ]);

            $producer->publish($msg, 'interpretation');

Producer (\app\commands\interpretation\InterpretationDataProducer)

<?php
namespace app\commands\interpretation;

use mikemadisonweb\rabbitmq\components\Producer;

class InterpretationDataProducer extends Producer
{

}

Can some one help to me?

mikemadisonweb commented 7 years ago

Hi, can you please post complete stack trace of an error?

mikemadisonweb commented 7 years ago

Why did you put an instance of InterpretationDataProducer class as a dependency to itself? And same thing with the producer. You don't need to describe console commands as services in DI container, rather you can use the built-in ones like this:

// should be in console.php
    'controllerMap' => [
        'rabbitmq-consumer' => \mikemadisonweb\rabbitmq\controllers\ConsumerController::class,
        'rabbitmq-producer' => \mikemadisonweb\rabbitmq\controllers\ProducerController::class,
    ],

Consumer command here would trigger a method execute() in a Consumer class that you defined in a 'callback' parameter. Example of Consumer class:

<?php

use mikemadisonweb\rabbitmq\components\ConsumerInterface;
use PhpAmqpLib\Message\AMQPMessage;

class ImportDataConsumer implements ConsumerInterface
{
    /**
     * @param AMQPMessage $msg
     * @return bool
     */
    public function execute(AMQPMessage $msg)
    {
        $data = unserialize($msg->body);
        var_dump($data);

        return ConsumerInterface::MSG_ACK;
    }
}

If this callback class have a dependency, then it's worth to define it as a singleton service in DI. As for the producer, there is no need to define it as service as well. After you configure one in 'producers' array you can get it like so:

$producer = \Yii::$container->get(sprintf('rabbit_mq.producer.%s', 'event_main_interpretation'));
rootlevel commented 7 years ago

Thanks Mikhail! After reading your comments i was understand, the problem in my config and producer container name. I completely deleted my container initialization (DI singleton containers configs). After that i changed "producer"-call like you tell me:

$producer = \Yii::$container->get(sprintf('rabbit_mq.producer.%s', 'event_main_interpretation'));

And... fantastic, it works! But all my produced tasks wrote to default queue. The default queue named like amq.gen-uk3TX_mm1usNpaP1bxcTYA. Hmmm..... I think i missed something. I missed producer queue_options in my rabbitmq componen config.


return [
        'class' => 'mikemadisonweb\rabbitmq\Configuration',
        'connections' => [
            'default' => [
                'host' => '192.168.22.112',
                'port' => '5672',
                'user' => 'loginxxx',
                'password' => 'XXXX',
                'vhost' => 'interpretation_host',
                'heartbeat' => 0,
            ],
        ],
        'producers' => [
            'event_main_interpretation' => [
                'connection' => 'default',
                'exchange_options' => [
                    'name' => 'main_interpretation',
                    'type' => 'direct',
                ],
                'queue_options' => [
                    'name'         => 'interpretation',
                    'routing_keys' => ['interpretation'],
                    'durable'      => true,
                    'auto_delete'  => false,
                ],
            ],
        ],
        'consumers' => [
            'event_main_interpretation' => [
                'connection'       => 'default',
                'exchange_options' => [
                    'name' => 'main_interpretation',
                    'type' => 'direct',
                ],
                'queue_options' => [
                    'name'         => 'interpretation',
                    'routing_keys' => ['interpretation'],
                    'durable'      => true,
                    'auto_delete'  => false,
                ],
                'callback' => \app\commands\interpretation\InterpretationDataConsumer::class,
            ],
        ],

Now all functionaloty it's works fine. Thanks again!

zz8023 commented 5 years ago

您好,我在执行Producer Times时犯了这个错误。 Class rabbit_mq.producer.import_data does not exist