引入异步事件主要是为了各模块的解耦,每当完成一个动作时,向系统发布一个事件,由关心的模块自己监听处理,可选择同步处理,异步处理,延迟处理。
何时发布事件,当其他模块关心此动作时
比如击杀一只怪物,成就模块需要统计击杀进度,便可监听怪物死亡事件。
比如获得道具时,任务系统模块要判定完成进度,BI模块需要上报等等都可以监听此事件,已达模块解耦
0x00事件源
一个实现xyz.noark.core.event.Event接口的实现类
public class ItemIncrEvent extends AbstractPlayerEvent {
private String itemcode;
private int count;
private IncrSource source;
public ItemIncrEvent(long playerId, String itemcode, int count, IncrSource source) {
super(playerId);
this.itemcode = itemcode;
this.count = count;
this.source = source;
}
}
0x01发布事件
在我们获得道具逻辑下面发布此事件
@Autowired
private EventManager eventManager;
eventManager.publish(new ItemIncrEvent(playerId, item.getTemplateId(), e.getValue(), source));
0x02处理事件
在对应的模块入口类中,也就是前面提到的Controller类.
@EventListener(ItemIncrEvent.class)
public void handleItemIncrEvent(ItemIncrEvent event) {}
这样便完成的事件处理逻辑.
0x03同步处理
注解@xyz.noark.core.annotation.controller.EventListener#async标识是否异步执行,默认为true
如果设置为false,此处理事件的逻辑将同步进行,如果有需要的话
如果要关闭事件显示的话,可以设置printLog=false
@EventListener(value = ItemIncrEvent.class, printLog = false)
0x04多事件异步有序执行
一个很无理又急需要用的需求,请在监听处理方法上添加@Order,值越小就越先执行.
0x05线程模型
在这里有必要聊一下线程问题,大多数异步事件功能的实现,都是在独立的线程池中执行的,这是一个区别
在0x02处理事件提到的Controller类,是不是我们的事件处理线程也遵循线程模型的划分呢,答案是肯定的
由于ItemIncrEvent实现了xyz.noark.core.event.PlayerEvent接口,如果Controller类上的标识为玩家线程组执行,则会自动派发给此玩家ID所对应的线程来执行.
eventManager在这里仅仅是一个调度者的身份,正式执行的任务线程是取决于Controller入口注解的线程组。
事件功能在冥冥之中响应了前面的线程模型的规划…
转载请注明原地址:
http://blog.noark.xyz/article/2018/5/21/noark入门之异步事件/