从简单的角度来看,没有什么可以禁止您在没有其他参与者的情况下将远程参与者订阅到您的事件流。 Akka documentation 提到:
事件流是本地设施,这意味着它不会
将事件分发到集群环境中的其他节点(除非
显式订阅远程 Actor 到流)。如果你需要
在 Akka 集群中广播事件,而不知道你的接收者
明确地(即获取他们的 ActorRefs),你可能想看看
进入:集群中的分布式发布订阅。
出于说明目的,请考虑以下与您要订阅的远程系统相对应的代码片段:
class PublisherActor extends Actor with ActorLogging { // example publisher actor just to generate some logs
context.system.scheduler.schedule(1.second, 1.second, self, "echo")
def receive = {
case "echo" ⇒
val x = Random.nextInt(100)
log.info(s"I got a random number: $x")
}
}
def runPublisher() = {
println("=== running publisher node ===")
val system = ActorSystem("PublisherSystem")
val selection = system.actorSelection("akka.tcp://SubscriberSystem@127.0.0.1:2553/user/subscriber")
selection.resolveOne(10.seconds) onSuccess { // when the listener actor is available,
case listener ⇒ system.eventStream.subscribe(listener, classOf[LogEvent]) // subscribe it to the event stream
}
val publisher = system.actorOf(Props[PublisherActor], "publisher") // some example publisher
}
然后是“本地”节点中的相应订阅者,从那里您要显示日志:
class SubscriberActor extends Actor with ActorLogging {
log.info("subscriber listening...")
def receive = {
case msg ⇒ log.info(s"Got: $msg")
}
}
def runSubscriber() = {
println("=== running subscriber node ===")
val system = ActorSystem("SubscriberSystem")
val listener = system.actorOf(Props[SubscriberActor], "subscriber")
}
但是,此解决方案有几个注意事项,因为发布者必须在订阅者之前运行(或者订阅者在发布者启动之前实施一些重试策略),位置是硬编码的等等。如果您想拥有一个更健壮、更有弹性的系统并且这是允许的,请遵循文档中的建议,并在集群环境中使用 distributed publisher-subscriber,这具有类似数量的样板文件的几个优势。
希望对您有所帮助!