引入异步事件主要是为了各模块的解耦,每当完成一个动作时,向系统发布一个事件,由关心的模块自己监听处理,可选择同步处理,异步处理,延迟处理。

何时发布事件,当其他模块关心此动作时

比如击杀一只怪物,成就模块需要统计击杀进度,便可监听怪物死亡事件。
比如获得道具时,任务系统模块要判定完成进度,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入门之异步事件/