枚举 Akka.NET 集群中的可用参与者
Enumerating available actors in Akka.NET cluster
我有两个演员,我们称他们为 ActorA 和 ActorB。作为基于 Topshelf 的 Windows 服务,两个参与者都驻留在自己单独的进程中。
基本上他们看起来像这样。
public class ActorA : ReceiveActor
{
public ActorA()
{
this.Receive<ActorIdentity>(this.IdentifyMessageReceived);
}
private bool IdentifyMessageReceived(ActorIdentity obj)
{
return true;
}
}
public class ActorB : ReceiveActor
{
private readonly Cluster Cluster = Akka.Cluster.Cluster.Get(Context.System);
public ActorB()
{
this.Receive<ActorIdentity>(this.IdentifyMessageReceived);
this.ReceiveAsync<ClusterEvent.MemberUp>(this.MemberUpReceived);
}
protected override void PreStart()
{
this.Cluster.Subscribe(this.Self, ClusterEvent.InitialStateAsEvents, new[]
{
typeof(ClusterEvent.IMemberEvent),
typeof(ClusterEvent.UnreachableMember)
});
}
protected override void PostStop()
{
this.Cluster.Unsubscribe(this.Self);
}
private async Task<bool> MemberUpReceived(ClusterEvent.MemberUp obj)
{
if (obj.Member.HasRole("actora"))
{
IActorRef actorSelection = await Context.ActorSelection("akka.tcp://mycluster@localhost:666/user/actora").ResolveOne(TimeSpan.FromSeconds(1));
actorSelection.Tell(new Identify(1));
}
return true;
}
private bool IdentifyMessageReceived(ActorIdentity obj)
{
return true;
}
}
我的配置文件超级简单
演员A:
akka {
log-config-on-start = on
stdout-loglevel = DEBUG
loglevel = DEBUG
actor.provider = cluster
remote {
dot-netty.tcp {
port = 666
hostname = localhost
}
}
cluster {
seed-nodes = ["akka.tcp://mycluster@localhost:666"]
roles = [actora]
}
}
演员B:
akka {
log-config-on-start = on
stdout-loglevel = DEBUG
loglevel = DEBUG
actor.provider = cluster
remote {
dot-netty.tcp {
port = 0
hostname = localhost
}
}
cluster {
seed-nodes = ["akka.tcp://mycluster@localhost:666"]
roles = [actorb]
}
}
我现在想识别附加到我的集群的所有给定参与者。我通过等待集群节点 MEMBER UP
事件并尝试向给定的参与者发送 Identify()
消息以接收对它的引用来做到这一点。
问题是我似乎无法将消息成功发送回 ActorA
。事实上,在执行上述代码时(尽管我在 ActorSelection 方法中有正确的引用),ActorIdentity 消息是在 ActorB
而不是 ActorA
.
中调用的
我已经尝试处理所有在 ActorA 中收到的消息,但似乎我从未收到 Identity
消息。但是,我可以使用相同的 ActorSelection 引用成功发送任何其他类型的消息 ActorA。
所以任何人都可以提供任何见解吗?为什么我的身份信息永远无法到达我的目标演员?
ActorIdentity message is invoked in ActorB rather than ActorA.
这按预期工作,因为您正在从参与者 B → A 发送 Identify
请求,ActorIdentity
是响应消息(从 A → B 自动发送)。
您已经可以观察到这种行为,因为:
Context.ActorSelection(path).ResolveOne(timeout)
或多或少相当于
Context.ActorSelection(path).Ask<ActorIdentity>(new Identify(null), timeout: timeout)
Identify
是系统消息,它总是在调用任何程序员定义的消息处理程序之前处理 - 因此您可能不会在自己的处理程序中捕获它。
我有两个演员,我们称他们为 ActorA 和 ActorB。作为基于 Topshelf 的 Windows 服务,两个参与者都驻留在自己单独的进程中。
基本上他们看起来像这样。
public class ActorA : ReceiveActor
{
public ActorA()
{
this.Receive<ActorIdentity>(this.IdentifyMessageReceived);
}
private bool IdentifyMessageReceived(ActorIdentity obj)
{
return true;
}
}
public class ActorB : ReceiveActor
{
private readonly Cluster Cluster = Akka.Cluster.Cluster.Get(Context.System);
public ActorB()
{
this.Receive<ActorIdentity>(this.IdentifyMessageReceived);
this.ReceiveAsync<ClusterEvent.MemberUp>(this.MemberUpReceived);
}
protected override void PreStart()
{
this.Cluster.Subscribe(this.Self, ClusterEvent.InitialStateAsEvents, new[]
{
typeof(ClusterEvent.IMemberEvent),
typeof(ClusterEvent.UnreachableMember)
});
}
protected override void PostStop()
{
this.Cluster.Unsubscribe(this.Self);
}
private async Task<bool> MemberUpReceived(ClusterEvent.MemberUp obj)
{
if (obj.Member.HasRole("actora"))
{
IActorRef actorSelection = await Context.ActorSelection("akka.tcp://mycluster@localhost:666/user/actora").ResolveOne(TimeSpan.FromSeconds(1));
actorSelection.Tell(new Identify(1));
}
return true;
}
private bool IdentifyMessageReceived(ActorIdentity obj)
{
return true;
}
}
我的配置文件超级简单
演员A:
akka {
log-config-on-start = on
stdout-loglevel = DEBUG
loglevel = DEBUG
actor.provider = cluster
remote {
dot-netty.tcp {
port = 666
hostname = localhost
}
}
cluster {
seed-nodes = ["akka.tcp://mycluster@localhost:666"]
roles = [actora]
}
}
演员B:
akka {
log-config-on-start = on
stdout-loglevel = DEBUG
loglevel = DEBUG
actor.provider = cluster
remote {
dot-netty.tcp {
port = 0
hostname = localhost
}
}
cluster {
seed-nodes = ["akka.tcp://mycluster@localhost:666"]
roles = [actorb]
}
}
我现在想识别附加到我的集群的所有给定参与者。我通过等待集群节点 MEMBER UP
事件并尝试向给定的参与者发送 Identify()
消息以接收对它的引用来做到这一点。
问题是我似乎无法将消息成功发送回 ActorA
。事实上,在执行上述代码时(尽管我在 ActorSelection 方法中有正确的引用),ActorIdentity 消息是在 ActorB
而不是 ActorA
.
我已经尝试处理所有在 ActorA 中收到的消息,但似乎我从未收到 Identity
消息。但是,我可以使用相同的 ActorSelection 引用成功发送任何其他类型的消息 ActorA。
所以任何人都可以提供任何见解吗?为什么我的身份信息永远无法到达我的目标演员?
ActorIdentity message is invoked in ActorB rather than ActorA.
这按预期工作,因为您正在从参与者 B → A 发送 Identify
请求,ActorIdentity
是响应消息(从 A → B 自动发送)。
您已经可以观察到这种行为,因为:
Context.ActorSelection(path).ResolveOne(timeout)
或多或少相当于
Context.ActorSelection(path).Ask<ActorIdentity>(new Identify(null), timeout: timeout)
Identify
是系统消息,它总是在调用任何程序员定义的消息处理程序之前处理 - 因此您可能不会在自己的处理程序中捕获它。