TIGERXC 2018-10-06
我们已经完成了设备级别的注册支持,现在我们必须在组级别实现它。在注册时,小组成员还有更多工作要做,包括:
处理注册请求
设备组Actor必须将请求转发给现有子项,或者应创建一个。要通过设备ID查找子actor,我们将使用Map <String,ActorRef>。
我们还希望保留请求的原始发件人的ID,以便我们的设备角色可以直接回复。这可以通过使用forward而不是tell运算符来实现。两者之间的唯一区别是,forward会保留原始发件人,而tell会将发件人设置为当前的actor。就像我们的设备actor一样,我们确保不会响应错误的组ID。将以下内容添加到源文件中:


Full source at GitHub
正如我们对设备所做的那样,我们测试了这个新功能。我们还测试了返回两个不同ID的Actor实际上是不同的,我们还尝试记录每个设备的温度读数,以查看Actor是否正在响应。

Full source at GitHub
如果注册请求已存在设备actor,我们希望使用现有的actor而不是新的actor。我们还没有测试过,所以我们需要解决这个问题:

Full source at GitHub
跟踪组中的设备Actor
到目前为止,我们已经实现了在组中注册设备actor的逻辑。然而,设备来来去去,所以我们需要一种从Map <String,ActorRef>中删除设备actor的方法。我们将假设当移除设备时,其相应的设备actor将停止。正如我们前面讨论的那样,监督只处理错误情况 - 不是优雅的停止。因此,我们需要在其中一个设备actor停止时通知父级。
Akka提供死亡观察功能,允许Actor观看另一个Actor,并在其他Actor停止时收到通知。与监督不同,观看不仅限于父子关系,任何Actor都可以观看任何其他Actor,只要它知道ActorRef即可。在观看的Actor停止之后,观察者接收终止(actorRef)消息,该消息还包含对观看的Actor的引用。观察者可以显式处理此消息,也可以使用DeathPactException失败。如果Actor在观看Actor停止后不再履行自己的职责,后者就很有用。在我们的例子中,该组在一个设备停止后仍然应该起作用,因此我们需要处理Terminated(actorRef)消息。
我们的设备组Actor需要包含以下功能:
不幸的是,Terminated消息只包含子actor的ActorRef。我们需要actor的ID将其从现有设备的映射中移除到设备actor映射。为了能够执行此删除,我们需要引入另一个占位符Map <ActorRef,String>,它允许我们找出与给定ActorRef对应的设备ID。
添加识别actor的功能实现:



Full source at GitHub
到目前为止,我们无法获得组设备主体跟踪的设备,因此,我们无法测试我们的新功能。为了使其可测试,我们添加了一个新的查询功能(消息RequestDeviceList),列出了当前活动的设备ID:



Full source at GitHub
我们几乎准备好测试设备的移除。但是,我们仍然需要以下功能:
我们现在再添加两个测试用例。首先,我们测试一旦添加了几个设备,我们就会返回正确的ID列表。第二个测试用例确保在设备actor停止后正确删除设备ID:


Full source at GitHub
创建设备管理器角色
要进入层次结构中的下一个级别,我们需要在DeviceManager源文件中为设备管理器组件创建入口点。此actor与设备组actor非常相似,但是创建设备组actor而不是设备actor:


Full source at GitHub
我们将设备管理器的测试留作练习,因为它与我们为组Actor编写的测试非常相似
What’s next?
我们现在有一个分层组件,用于注册和跟踪设备和记录测量。我们已经了解了如何实现不同类型的会话模式,例如: