繁体   English   中英

枚举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()消息发送给给定的actor来接收对该事件的引用来完成此操作。

问题是我似乎无法成功将消息发送回ActorA 实际上,在执行上述代码时(尽管我在ActorSelection方法中具有正确的引用),ActorIdentity消息是在ActorB而不是ActorA调用的。

我尝试处理ActorA中所有收到的消息,但似乎从未收到Identity消息。 但是,我可以使用相同的ActorSelection参考成功发送任何其他类型的消息ActorA。

谁能提供任何见解? 为什么我的身份信息永远无法到达目标演员?

ActorIdentity消息是在ActorB中而不是ActorA中调用的。

这是按预期方式工作的,因为您正在从ActorIdentity B→A发送Identify请求, ActorIdentity是响应消息(从A→B自动发送)。

您已经可以观察到这种行为,因为:

Context.ActorSelection(path).ResolveOne(timeout)

差不多等于

Context.ActorSelection(path).Ask<ActorIdentity>(new Identify(null), timeout: timeout)

Identify是系统消息,始终在调用任何程序员定义的消息处理程序之前进行处理-因此,您可能不会在自己的处理程序中捕获该消息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM