akka入门系列-3. Actor进阶:创建带参数的actor和发送复杂的消息类型

本文讲解如何在Akka中扩展actor,使其接受带参数的创建和处理自定义消息类型,如DevicePropertyMessage。通过实例化FilterActor并定义接口和行为,提升actor的灵活性和实用性。
摘要由CSDN通过智能技术生成

3. Actor进阶:创建带参数的actor和发送复杂的消息类型

上一篇实现了actor的创建,但是这个actor并不能满足我们生产中的要求。主要有以下2点:

  1. 构建actor类时,需要带参数或配置
  2. 消息不会是String这种基本类型,会是一个自定义的类

针对上面的问题,我们扩展之前的HelloWorldActor,并引入akka的一些用法或思想。

定义带参数的actor

构建带参数的actor的方法,可以通过actor类的create()静态方法,传递到私有化的构造方法中,再在构造方法中赋值到actor类的内部变量就可以了。如下所示:

@Slf4j
public class FilterActor extends AbstractBehavior<IDeviceMessage> {

    private BehaviorConfig config;
    private ActorRef nextActorRef;

    private FilterActor(ActorContext<IDeviceMessage> context, BehaviorConfig behaviorConfig, ActorRef nextActor) {
        super(context);
        this.config = behaviorConfig;
        this.nextActorRef = nextActor;
    }

    //传2个参数,一个是自定义的配置类,一个是连接的下一个actor
    public static Behavior<IDeviceMessage> create(BehaviorConfig behaviorConfig, ActorRef nextActor) {
        return Behaviors.setup(context ->  new FilterActor(context, behaviorConfig, nextActor)
        );
    }

}

其中BehaviorConfig是我们自定义的配置类。创建actor实例的时候传入create()方法中,如下所示:

    // actor的配置
    BehaviorConfig filterConfig = new BehaviorConfig("$power > 2000");
    // 创建filter的behavior
    Behavior<IDeviceMessage> filterBehavior = FilterActor.create(filterConfig, null);
    // 实例化filter actor
    ActorRef<IDeviceMessage> filterActorRef = context.spawn(filterBehavior, "Filter");

自定义消息类型

我们通常要处理的数据/消息一般不会是基本类型,通常是我们自己定义的pojo类,而且也通常不会是同一种类型的消息,会处理多种类型的消息。
下面我们把上面例子里的消息类型改造成自定义的消息类型。

在改造之前,需要说明,在akka的规范中,一个actor只能接收并处理某一类的消息类型。也就是说在实现上,这些消息需要实现自同一个接口类。可以理解为,这个actor并不是什么都能拿来加工。比如说这个actor就是个木工,那只能接收各种木头进行加工,黑檀木、桃木、松木都可以,但是来块铁板就不行了。

因此,我们需要先定义一个基础消息接口,这个接口可以什么都没有,但这是常规操作。

public interface IDeviceMessage {
}

然后定义表示设备属性的消息类,其中包含电流、电压、功率等属性。

@Data
@Builder
public class DevicePropertyMessage implements IDeviceMessage {
    private int msgId;
    private String thingId;
    private double current;
    private double voltage;
    private double power;
}

定义完消息类后,需要修改Actor的定义,主要是修改Behavior、ActorContext、Receive后面泛型里的类,需要修改为上面定义的接口类。比如:

    //返回的Behavior限定了此actor可处理的消息类型
    public static Behavior<IDeviceMessage> create(BehaviorConfig behaviorConfig, ActorRef<IDeviceMessage> nextActor) {
        return Behaviors.setup(context ->  new FilterActor(context, behaviorConfig, nextActor));
    }

然后,在createReceive()方法中指定不同消息的处理方法。

    @Override
    public Receive<IDeviceMessage> createReceive() {
        return newReceiveBuilder()
                //不同类型的消息,指定不同的方法处理
                .onMessage(DevicePropertyMessage.class, this::onPropertyMessage)
                .onMessage(DeviceActionMessage.class, this::onActionMessage)
                .build();
    }

以上,我们实现了一个更实用的actor,可以接收自定义的消息类型,并按我们的配置的逻辑进行处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值