使用Akka classic,可以轻松实现服务(作为参与者:ServiceActor),
- 接收来自不同参与者的请求(即,不同类型的参与者:请求者A、请求者B等),
- 处理该请求,
- 向请求者发回确认。
请求者A向ServiceActor发送RequestMessage,ServiceActor向请求者A发回Acknowledgement
类似地,RequestorB向ServiceActor发送RequestMessage,ServiceActor向RequestorB发回Acknowledgement
无论请求是什么,都只有一种类型的RequestMessage和Acknowledgement,所有RequestMessage都由ServiceActor以相同的方式处理。
如何使用Akka Typed实现类似的功能?现在请求消息必须包含显式的replyTo:ActorRef[RequestorA.Message],有没有一种方法可以避免为每个请求者实现不同的RequestMessage?
- RequestFromRequestorA(replyTo:ActorRef[请求者A.消息])
- RequestFromRequestorB(replyTo:ActorRef[请求者B.消息])
类似地,有没有一种方法可以避免向每种类型的请求者发回不同类型的确认?
1条答案
按热度按时间ftf50wuq1#
通常在Akka Typed中,响应消息由处理请求的Actor的协议定义,例如(在Scala中):
然后,发送
Request
的参与者有责任安排处理Response
。如果发出请求的参与者只是为了发送请求而存在,它可以将自己定义为Behavior[Response]
,但在更一般的情况下,可以使用几种策略。参与者可以设置消息适配器:
如果这样做,通常最好只设置一次
responseRef
(例如,以Behaviors.setup
为单位)。如果参与者只执行一次请求,或者只期望每个请求有一个响应(并且期望在有限的时间内得到响应),那么“ask模式”可能更清晰:
这确实需要您定义一个显式的超时,并处理没有及时收到响应的情况。注入到
Request
消息中的ActorRef
是短暂的:它将不会接收到发送给它的第一消息之外的任何消息,也不会接收到超时之后的消息。还可以将参与者的行为定义为
Behavior[Any]
(类似于“经典”无类型参与者),但不将该事实暴露在参与者之外。在Scala中,这是相当简单和安全的,这要归功于逆变:派生的
ActorRef
将是一个ActorRef[Command]
(即仅承诺处理Command
),但参与者能够决定承诺处理它想要处理的任何消息(即使不是Command
)。当这个参与者向它自己发送消息时,这确实会使你退出编译器的帮助;此外,这可能是一个有点模糊的模式,所以它的使用应该得到很好的注解。