Contributed by
Samuel Roze
in #24411.

在 Symfony 4.1 中我们添加了全新的 Messenger 组件,帮助程序 向/从 其他的程序或是消息队列,发送/接收信息。它提供了一个 message bus 以及一些路由控制能力,可在任何你需要的服务中来发送消息,就像在控制器中一样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// src/Controller/DefaultController.php
namespace App\Controller;
 
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Routing\Annotation\Route;
 
class DefaultController extends Controller
{
    /**
     * @Route("/", name="homepage")
     */
    public function index(MessageBusInterface $bus)
    {
        // ...
 
        $bus->dispatch(new MyMessage());
    }
}

发送信息,是过程的第一部分。 然后您需要创建一个 "message handler",并把它注册为带有 messenger.message_handler 标签的服务,来接收信息,或用它做一些事情:

1
2
3
4
5
6
7
8
9
10
// src/MessageHandler/MyMessageHandler.php
namespace App\MessageHandler;
 
class MyMessageHandler
{
    public function __invoke(MyMessage $message)
    {
        // do something with the message
    }
}

Queues and AMQP adapters(队列和AMQP适配器)

本组件包括了一个 AMQP adapter,可以同多数人气 AMQP brokers 进行通信,比如 RabbitMQ。与查询系统或第三方(Kafka, Amazon SQS, Google Pub/sub) 的通信是委托给 Enqueue's adapter 这样的类库来完成的:

1
2
3
4
5
# config/packages/messenger.yaml
framework:
    messenger:
        adapters:
            default: "amqp://guest:guest@localhost:5672/%2f/messages"

上面的配置允许把消信给派到 messenger.default_adapter,同时还配置了一个 messenger.default_sendermessenger.default_receiver 以便在发送和消耗 messages 的时候用到。

Routing(路由)

毋须调用handler,你也可以把自己的信息派给一个或多个sender发送者:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# config/packages/messenger.yaml
framework:
    messenger:
        routing:
            # route this message to a single sender
            # 把这消息派给一个sender
            'My\Message\Message':  messenger.default_sender
 
            # route this message to multiple senders
            # 把这消息派给多个sender
            'My\Message\ToBeSentToTwoSenders': [messenger.default_sender, messenger.audit_sender]
 
            # route the rest of messages to the default sender
            # 把剩下的消息派给默认的sender
            '*': messenger.default_sender

一旦你的消息被指派出去,你可以用 messenger:consume-messages 命令来消费它们:

1
 bin/console messenger:consume-messages messenger.default_receiver

Messenger组件定义的 message bus 是基于中间件的。关于 Messenger 剩余功能,可以去 它的文档 的最新草稿中做进一步阅读。