简体   繁体   English

如何从 Symfony 项目中运行 bin/console messenger:consume 命令?

[英]How to run bin/console messenger:consume command out of Symfony project?

I use Messenger Component in a non-Symfony project and Doctrine as a DSN transport.我在非 Symfony 项目中使用Messenger 组件,并使用 Doctrine 作为 DSN 传输。 Now I want to test my code and consume the messages on my local machine, but I don't know how to run the messenger command in the console.现在我想测试我的代码并在本地机器上使用消息,但我不知道如何在控制台中运行 messenger 命令。

I tried to use Symfony\Component\Console\Application and register the \Symfony\Component\Messenger\Command\ConsumeMessagesCommand command in the console but there are many nested dependencies.我尝试使用Symfony\Component\Console\Application并在控制台中注册\Symfony\Component\Messenger\Command\ConsumeMessagesCommand命令,但有许多嵌套依赖项。

Do you have any idea?你有什么主意吗?

We actually do this in many projects, even WordPress CLI tools, and we use this library to do it along with this for the transport.实际上,我们在许多项目中都这样做了,甚至是 WordPress CLI 工具,我们使用这个这个库一起进行传输。 It doesn't require Symfony and can work with most queue systems that follow the general standard.它不需要 Symfony 并且可以与大多数遵循通用标准的队列系统一起使用。

The general idea is that you want something (probably a singleton) to return an instance of Interop\Queue\Context , and here's what we use:一般的想法是你想要一些东西(可能是一个单例)返回一个Interop\Queue\Context的实例,这就是我们使用的:

    function createContext(): \Interop\Queue\Context
    {
        $factory = new \Enqueue\Dbal\DbalConnectionFactory(
            sprintf(
                'mysql://%1$s:%2$s@%3$s/%4$s',
                DB_USER,
                DB_PASSWORD,
                DB_HOST,
                DB_NAME
            )
        );

        $context = $factory->createContext();
        $context->createDataBaseTable();
        return $context;
    }

You'll also want something to handle each message, and you'll want to pass the message and consumer to it:您还需要一些东西来处理每条消息,并且您需要将消息和使用者传递给它:

    function handleMessage($message, $consumer)
    {
        // Business logic here
        if($business_logic_failed) {
            $context = createContext();
            $failed_queue = $context->createQueue('FAILED_QUEUE_HERE');
            $context->createProducer()->send($failed_queue, $message);
        } else {
            $consumer->acknowledge($message);
        }
        
    }

Then to use it:然后使用它:

$context = createContext();
$queue = $context->createQueue('QUEUE_NAME_HERE');
$consumer = $context->createConsumer($queue);

// This can be an infinite loop, or a loop for 10 messages and exit, whatever your logic
while(true) {
    // This command will block unless you pass a timeout, so no sleep is needed
    $message = $consumer->receive(/* optional timeout here */);
    handleMessage($message, $consumer);

    // Do whatever you want with message
}

Sprinkle a lot of try/catch around that, too, and make sure that no matter what you acknowledge or fail the message in some way.也可以围绕它进行大量尝试/捕捉,并确保无论您以某种方式承认或失败消息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM