jimphle/messaging

Jimdo PHP 库中消息组件的提取

v1.2.1 2017-08-24 09:18 UTC

README

Jimdo PHP 库中消息组件的提取。

消息组件基于实现 MessageHandler 接口的消息处理器。

处理命令和事件

让我们从发送一个命令 say-hello 开始

use Jimphle\Example\MessageHandler\SayHelloHandler;

use Jimphle\Messaging\MessageHandler\HandleMessage;
use Jimphle\Messaging\MessageHandlerProvider;
use Jimphle\Messaging\Command;

$messageHandlerDefinitions = array(
    'say-hello' => new SayHelloHandler(),
);
$messagingContext = new HandleMessage(
    new MessageHandlerProvider(
        new ArrayObject(
            $messageHandlerDefinitions
        )
    )
);

$response = $messagingContext->handle(
    Command::generate(
        'say-hello',
        array(
            'name' => 'World'
        )
    )
);
echo $response->answer;

# => Hello World!

好的,这里发生了什么?我们传递了命令 say-hello 和它的有效载荷到 messagingContext。messagingContext 在注册了 say-hello 的 MessageHandler 中进行了查找。

更有趣的是。如果你查看 SayHelloHandler,你会看到处理器本身生成了一个新的事件,该事件由调用上下文直接返回作为 MessageResponse "待处理"。为了让我们的 messagingContext 能够处理这类消息,我们必须添加另一种类型的处理器。

use Jimphle\Example\MessageHandler\BeObsceneHandler;
use Jimphle\Example\MessageHandler\SayHelloHandler;

use Jimphle\Messaging\MessageHandler\HandleMessagesToProcessDirectly;
use Jimphle\Messaging\MessageHandler\HandleMessage;
use Jimphle\Messaging\MessageHandlerProvider;
use Jimphle\Messaging\Command;

$messageHandlerDefinitions = array(
    'say-hello' => new SayHelloHandler(),
    'said-hello' => array(
        new BeObsceneHandler()
    )
);
$messagingContext = new HandleMessagesToProcessDirectly(
    new HandleMessage(
        new MessageHandlerProvider(
            new ArrayObject(
                $messageHandlerDefinitions
            )
        )
    )
);

$response = $messagingContext->handle(
    Command::generate(
        'say-hello',
        array(
            'name' => 'World'
        )
    )
);
echo $response->answer . "\n";

# => GTFO Joscha!
# => Hello World!

正如你所看到的,我们的 said-hello 事件现在由 messagingContext 处理。这意味着 messagingContext 处理了 SayHelloHandler,它遍历返回的 "待直接处理" 事件并尝试处理它们。正如你可能注意到的,打印消息的顺序与调用打印处理器的顺序相反。这是因为第一个调用的 message-handler 的响应是这里返回的。

消息过滤器与消息处理器注解

如果你将 ApplyFilter MessageHandler 添加到 messagingContext,你可以在将消息传递给下一个消息处理器之前对其进行过滤。

$messageFilterDefinitions = array(new SomeMessageFilter());
$messagingContext = new HandleMessagesToProcessDirectly(
    new ApplyFilter(
        $messageFilterDefinitions,
        new HandleMessage(
            new MessageHandlerProvider(
                new ArrayObject(
                    $messageHandlerDefinitions
                )
            )
        )
    )
);

但是,这里有两种预定义的过滤器我们可以使用

  • 基于 Symfony-Validation-Component 的验证过滤器
  • 另一天再解释的授权过滤器

在 PDO 事务中处理消息

要处理 PDO 事务中的消息,我们可以将 TransactionalMessageHandler 添加到 messagingContext。

$messagingContext = new HandleMessagesToProcessDirectly(
    new TransactionalMessageHandler(
        new PDO('some-dsn'),
        new ApplyFilter(
            $messageFilterDefinitions,
            new HandleMessage(
                new MessageHandlerProvider(
                    new ArrayObject(
                        $messageHandlerDefinitions
                    )
                )
            )
        )
    )
);

要在一个 pdo 事务中执行消息处理器,只需添加一个注解即可。

use Jimphle\Messaging\Plugin\Pdo\TransactionalAnnotation as withPdoTransaction;

/**
 * @withPdoTransaction
 */
class SayHelloHandler extends AbstractMessageHandler
{
    public function handle(Message $message)
    {
        return $this->response(
            array('answer' => sprintf("Hello %s!", $message->name))
        )
            ->addMessageToProcessDirectly(
                $this->event('said-hello', array('name' => 'Joscha'))
            );
    }
}