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
。