icehawk/pubsub

IceHawk 框架的发布-订阅组件

v1.0.1 2016-10-07 00:02 UTC

This package is auto-updated.

Last update: 2024-09-22 04:19:23 UTC


README

Join the chat at https://gitter.im/icehawk/pubsub Build Status Coverage Status Latest Stable Version Total Downloads Latest Unstable Version License

IceHawk Framework

IceHawk\PubSub

IceHawk 框架提供的发布-订阅组件。

需求

  • PHP >= 7.0

安装

composer require "icehawk/pubsub:^1.0"

使用

创建一个消息

请注意

  • 消息始终应该是不可变的。
  • 每个消息必须有一个
    • 消息 ID
    • 消息名称

... 当然还有用户定义的内容,即所谓的有效负载。

IceHawk/PubSub 提供了两种/值对象用于消息 ID 和消息名称。如果您出于任何原因不希望/不能使用它们,您可以选择实现它们的接口。

消息本身必须实现以下接口

IceHawk\PubSub\Interfaces\CarriesInformation

因此,消息实现可能如下所示

<?php

namespace MyVendor\MyNamespace;

use IceHawk\PubSub\Interfaces\CarriesInformation;
use IceHawk\PubSub\Interfaces\IdentifiesMessage;
use IceHawk\PubSub\Interfaces\NamesMessage;

final class MyMessage implements CarriesInformation
{
	/** @var IdentifiesMessage */
	private $messageId;
	
	/** @var NamesMessage */
	private $messageName;
	
	/** @var string */
	private $content;
	
	public function __construct( IdentifiesMessage $messageId, NamesMessage $messageName, string $content ) 
	{
		$this->messageId    = $messageId;
		$this->messageName  = $messageName;
		$this->content      = $content;
	}
	
	public function getMessageId() : IdentifiesMessage 
	{
		return $this->messageId;
	}
	
	public function getMessageName() : NamesMessage 
	{
        return $this->messageName;
	}
	
	public function getContent() : string
	{
		return $this->content;
	}
}

创建此消息的新实例如下

<?php

namespace MyVendor\MyNamespace;

use IceHawk\PubSub\Types\MessageId;
use IceHawk\PubSub\Types\MessageName;

$myMessage = new MyMessage( 
    new MessageId( '123456-ABC-789' ),
    new MessageName( 'Something had happened' ),
    'Hello World!' 
);

创建消息订阅者

要实现一个订阅者,它将通知有关其订阅的通道发布的所有消息,您可以通过扩展 IceHawk\PubSub 中的 AbstractMessageSubscriber 类来实现。

AbstractMessageSubscriber 类自动将消息名称转换为处理方法名称,通过在消息名称前添加 when 并将其转换为驼峰命名法。 (所有非字母数字字符都将被删除。) 在此示例中:消息名称 "Something had happened" 转换为处理方法名称 "whenSomethingHadHappened"。

由于对处理方法的调用是由抽象父类触发的,因此该方法必须至少具有受保护(或公共)可见性。私有方法不可调用,因为它们会超出父类的范围。

处理方法使用两个参数调用

  1. 发布的消息实例
  2. 发布消息的通道实例

IceHawk\PubSub 提供了一个类型/值对象用于通道。如果您出于任何原因不希望/不能使用它,您可以选择实现其接口。

扩展 AbstractMessageSubscriber 类的另一种方法是实现以下接口

IceHawk\PubSub\Interfaces\SubscribesToMessages

一个基本的订阅者实现,通知有关之前创建的消息,可能如下所示

<?php

namespace MyVendor\MyNamespace;

use IceHawk\PubSub\AbstractMessageSubscriber;
use IceHawk\PubSub\Types\Channel;

final class MySubscriber extends AbstractMessageSubscriber
{
	protected function whenSomethingHadHappened( MyMessage $myMessage, Channel $channel )
	{
		printf(
		    'Message named "%s" with ID "%s" was published on channel "%" with content: "%s"',
		    $myMessage->getMessageName(),
		    $myMessage->getMessageId(),
		    $channel,
		    $myMessage->getContent()
		);
	}
}

订阅通道

<?php

namespace MyVendor\MyNamespace;

use IceHawk\PubSub\MessageBus;
use IceHawk\PubSub\Types\Channel;

// ...

$messageBus = new MessageBus();
$messageBus->subscribe( new Channel( 'ListenToMe' ), new MySubscriber() );

注意: MessageBus 类自动防止将相同的订阅者订阅到同一通道。但一个订阅者可以订阅多个通道。

发布消息

与订阅通道的方式相同,您将像这样向通道发布消息

<?php

namespace MyVendor\MyNamespace;

use IceHawk\PubSub\Types\Channel;

// ...

$messageBus->publish( new Channel('ListenToMe'), $message );

打印

Message named "Something had happened" with ID "123456-ABC-789" was published on channel "ListenToMe" with content: "Hello World!"'