9. Tigase中的EventBus API
EventBus是一种自定义发布-订阅机制,它允许在Tigase服务器中使用事件监听器。有关EventBus及其功能的更详细概述,请访问 管理指南。
9.1. EventBus API
要创建EventBus的实例,请使用以下代码:
EventBus eventBus = EventBusFactory.getInstance();
备注
请记住,EventBus是异步的。所有处理程序都在与最初触发事件的线程不同的线程中调用。
9.1.1. 事件
事件可以用两种方式定义:作为一个类  或作为XML元素(自8.2版起已弃用基于XML/元素的事件,并将在9.0 版中删除). 
序列化事件类。
public class SampleSerializedEvent implements Serializable {
    private JID data;
    public JID getData() {
        return this.data;
    }
    public void setData(JID data) {
        this.data = data;
    }
}
事件类。
public class SampleEvent {
    private JID data;
    public JID getData() {
        return this.data;
    }
    public void setData(JID data) {
        this.data = data;
    }
}
 XML元素事件(已弃用)
<EventName xmlns="tigase:demo">
  <sample_value>1</sample_value>
</EventName>
备注
定义为XML元素和实现 Serializable 接口的类的事件将分发到集群中的所有服务器。事件 SampleEvent 将仅在触发事件的同一实例中广播。
9.1.2. 基于类的事件的要求
默认的、显式的、公共的、无参数的构造函数是强制性的。
如果事件应该被传递到所有集群节点,那么它 必须 实现
Serializable接口。变量序列化遵循
Serializable语义,这意味着final、static和transient字段将被跳过。更重要的是,具有null值的字段也不会被序列化。
9.1.3. 基于类的事件的序列化
基于类的事件被序列化(如果需要并且可能的话)到XML元素。 XML元素的名称取自类的全名:
基于类的事件序列化为XML。
<net.tigase.sample.SampleSerializedEvent>
    <data>[email protected]</data>
</net.tigase.sample.SampleSerializedEvent>
9.1.4. 触发事件
要触发事件,只需获取EventBus的实例并调用方法 fire()。
触发序列化事件。
EventBus eventBus = EventBusFactory.getInstance();
SampleSerializedEvent event = new SampleSerializedEvent();
eventBus.fire(event)
触发简单事件。
EventBus eventBus = EventBusFactory.getInstance();
SampleEvent event = new SampleEvent();
eventBus.fire(event)
 基于XML元素的触发事件(已弃用) 
EventBus eventBus = EventBusFactory.getInstance();
Element event = new Element("tigase.eventbus.impl.Event1");
eventBus.fire(event)
9.1.5. 处理事件
要处理触发的事件,我们必须在EventBus中注册监听器。注册监听器后,EventBus会自动在集群中的所有实例中订阅此类事件。
取决于预期的事件类型,我们必须决定我们应该注册哪种类型的监听器。
处理基于类的事件
此选项仅用于基于类的事件。是否是序列化类都没有关系。
eventBus.addListener(SampleEvent.class, new EventListener<SampleEvent>() {
    @Override
    public void onEvent(SampleEvent event) {
    }
});
为了使注册监听器更容易,您可以使用EventBus中的方法 registerAll()。此方法注册给定类的所有方法,由 @HandleEvent 注释为声明为方法参数的事件的侦听器。
public class SomeConsumer {
    @HandleEvent
    public void event1(Event12 e) {
    }
    public void initialize() {
        eventBus.registerAll(this);
    }
}
 处理XML事件 
要处理XML事件,我们必须为特定事件包和名称注册侦听器。在我们的示例中,包是空的,因为事件名称没有声明包(另请参阅 过滤事件)。
eventBus.addListener("", "EventName", new EventListener<Element>() {
    @Override
    public void onEvent(Element event) {
    }
});
eventBus.addListener("tigase.eventbus.impl", "Event1", new EventListener<Element>() {
    @Override
    public void onEvent(Element event) {
    }
});
因为序列化的类事件,ale转换为XML元素,所以我们能够侦听基于类的事件的XML表示。为此,我们必须为特定的包和类名注册监听器:
eventBus.addListener("net.tigase.sample", "SampleSerializedEvent", new EventListener<Element>() {
    @Override
    public void onEvent(Element event) {
    }
});
重要
在其他集群节点上创建的XML事件,将属性
remote设置为true,属性source设置为事件创建者节点名称:<EventName xmlns="tigase:demo" remote="true" source="node1.example"> <sample_value>1</sample_value> </EventName>
过滤事件
有时您可能希望使用同一个处理程序接收多种事件。 EventBus有非常简单的泛化机制:
eventBus.addListener("net.tigase.sample", null,  event -> {});
eventBus.addListener(null, null,  event -> {});
将为具有给定包名称(基于XML或基于序列化类)的每个事件调用此侦听器。
将为所有事件(基于XML或基于序列化类)调用此侦听器。
对于基于类的事件,EventBus正在检查类继承。
class MainEvent { }
class SpecificEvent extends MainEvent {}
eventBus.addListener(SpecificEvent.class, event -> {});
eventBus.addListener(MainEvent.class, event -> {});
eventBus.fire(new SpecificEvent());
将被调用,因为这是
SpecificEvent的严格监听器。将被调用,因为
SpecificEvent扩展了MainEvent。