Vert.x中EventBus中的使用


注意:使用的是vert.x3.0 仅支持到java8当中有一些lambda表达式。如不明确请自补java8新特性。java

The Event Busnode

event bus 是vert.x的神经系统。算法

每一个vert.x的实例都有一个单一的event bus 实例。它是使用vertx.eventBus()方法得到的。编程

event bus 赞成程序中的不一样语言编写的模块进行通讯。不论他们是一样的vert.x实例。仍是不一样的vert.x实例。浏览器

它甚至可以桥接浏览器中执行的Javascript通讯。编程语言

event bus可以在分布式系统中的多个server节点之间进行点对点通讯和多个浏览器。分布式

event bus支持公布/订阅模式。点对点模式,和请求/响应模式。ide

event bus的API是很easy的。它主要包含注冊消息处理事件。取消处理事件。发送和公布消息。spa

首先理论命令行

寻址

event bus上的消息被发送到一个地址。

vert.x不包括不论什么花哨的寻址方案。

在vert.x中,一个地址就是一个简单的String字符串。不论什么字符串都是有效的。只是最好的方法是使用某种有计划或者有规则的方案,比方使用一个私有的空间名称。

一些有參考价值的样例:europe.news.feed1, acme.games.pacman, sausages, and X。

事件-消息的处理程序

收到消息的处理程序,你在一个地址上注冊一个处理程序,来消息后将触发这个处理程序。

同一个消息处理程序可以注冊到不一样的地址上,相同同一个地址也能注冊多个处理程序。

公布/订阅模式

event bus 支持公布消息

消息被公布到一个地址。公布意味着将消息交给所有订阅并注冊处理程序的地址来处理。

这跟你们熟悉的公布/订阅模式没有什么不一样。

点对点和请求/响应模式

event bus 支持点对点消息传递。

消息被发送到一个地址。

vert.x将发送它到一个注冊消息处理程序的地址。

假设有多个处理程序注冊地址,vert.x将选择一个来处理(採用非严格循环算法)。

强烈不推荐。

当接收到消息的程序处理完毕后,可以决定是否回复。发送程序接到回复后也可以进行响应回复,假设他们这样作应答处理程序将被调用。

当接收方到返回发送方。这样可以无限反复,这又是一种常见的消息传递模式:请求/响应模式

最优传输

vert.x能够作到最优传输。不会有意识的丢失消息。这是很重要的。

然而,event bus的部分或全部失败仍是有可能形成消息丢失的。

假设你的应用程序很在意消息的完整性和时序性。那么你的代码处理应该是幂等的。以便在消息处理程序复苏后又一次发送消息。

消息类型

开箱赞成vert.x使用不论什么的原始/简单类型,字符串或者缓冲区发送消息。

然而这里有一个不成文的规定或者说建议。那就是最好使用JSON格式的子串来进行消息的传递。

JSON字串在所有的编程语言中都是很easy建立。读取和解析的。在vert.x下它已经变成一种通用语言了。

假设你不是必需使用JSON或者说你不想。

event bus 很灵活。

它还支持发送随意对象。还可以定义您想要发送的对象的编解码器。

EVENT BUS 的API

让咱们跳进event bus的API。

得到event bus 的对象

你可以经过例如如下代码得到event bus的单一对象:

EventBus eb = vertx.eventBus();

注冊处理事件

使用如下这个简单方法注冊一个消费处理程序:

EventBus eb = vertx.eventBus();

eb.consumer("news.uk.sport", message -> {

System.out.println("I have received a message: " + message.body());

});

当一个消息到达你的处理事件是。你的事件将被激活。并处理这个消息。

consumer()方法返回一个MessageConsumer的对象实例。这个对象随后用于注销处理程序,或者用处理程序做为流。

然而您也可以使用consumer()返回MessageConsumer没有处理程序,而后单独设置处理程序。好比:

EventBus eb = vertx.eventBus();

MessageConsumer<String> consumer = eb.consumer("news.uk.sport");consumer.handler(message -> {

System.out.println("I have received a message: " + message.body());

});

当在集群事件总线上注冊一个处理程序时,它可以花一些时间登记到集群的所有节点上。

假设你但愿在注冊完毕时获得通知的话,你可以在MessageConsumer上注冊一个注冊完毕的处理程序:

consumer.completionHandler(res -> {

if (res.succeeded()) {

System.out.println("The handler registration has reached all nodes");

} else {

System.out.println("Registration failed!");

}

});

注销处理事件

去除处理事件。叫作注销。

假设你是集群事件总线, 假设你想当这个过程完毕时通知注销,你可以使用如下的方法:

consumer.unregister(res -> {

if (res.succeeded()) {

System.out.println("The handler un-registration has reached all nodes");

} else {

System.out.println("Un-registration failed!");

}

});

公布消息

公布消息很easy。仅仅需要把它公布到指定地址就能够:

eventBus.publish("news.uk.sport", "Yay! Someone kicked a ball");

这一消息将被交付所有订阅news.uk.sport地址处理。

发送消息

发送消息将致使仅仅有一个注冊地址的处理程序接收到消息(多个注冊地址也仅仅有一个能收到)。

这就是点对点模式,选择处理程序的方法採用非严格循环方式。

你可用用send()方法发送一条消息。

eventBus.send("news.uk.sport", "Yay! Someone kicked a ball");

未解决的指令包含在<stdiin>-include::override/eventbus_headers.adoc[] ==== The Message object

你的消息处理程序收到的是一个Message。

消息的body相应着是应该发送仍是应该公布。

消息的headers是可用的。

回复消息

有时你发送消息后但愿获得接收到消息的人的回复。

这就需要你使用请求-响应模式。

要作到这一点,在消息发送的时候,你可以指定一个回复事件。

当你接收到消息的时候,你可以经过调用reply()方法来应答。

当这一切发生的时候它会致使一个答复发送回发送方,发送方收到应答消息再作处理。

接收方:

MessageConsumer<String> consumer = eventBus.consumer("news.uk.sport");

consumer.handler(message -> {

System.out.println("I have received a message: " + message.body());

message.reply("how interesting!");

});

发送方:

eventBus.send("news.uk.sport", "Yay! Someone kicked a ball across a patch of grass", ar -> {

if (ar.succeeded()) {

 System.out.println("Received reply: " + ar.result().body());
 }
 });

相应答也可以作应答。这样你就可以在两个不一样的程序中建立一个包括多个回合的对话。

发送超时

当你发送消息时和指定应答事件时你可以经过DeliveryOptions指定超时时间。

假设应答事件很多于超时时间,这个应答事件将失败。

默认的超时时间是30S。

发送失败

消息发送失败的其它缘由,包含:

没有可用的事件去发送消息

接收者已经明白使用失败:失败的消息

在所有状况下。应答事件将回复特定的失败。

未解决的指令包括在<stdin> - include::override/eventbus.adoc[]==== Clustered Event Bus

event bus 不仅存在于一个单一的Vert.x实例中,在一个集群中不一样的Vert.x实例也可以造成一个单一的,分布的事件总线。

集群编程

假设你建立一个Vert.x实例用于集群编程。你需要的获得一个关于集群事件总线配置

VertxOptions options = new VertxOptions();

Vertx.clusteredVertx(options, res -> {

if (res.succeeded()) {

Vertx vertx = res.result();

EventBus eventBus = vertx.eventBus();

System.out.println("We now have a clustered event bus: " + eventBus);

} else {

System.out.println("Failed: " + res.cause());

}});

你应该确保在你的类路径中实现了一个ClusterManager,好比默认的:HazelcastClusterManager。

使用命令集群

你可以使用命令行执行集群:vertx run my-verticle.js -cluster

Automatic clean-up in verticles

If you’re registering event bus handlers from inside verticles, those handlers will be automatically unregisteredwhen the verticle is undeployed.

相关文章
相关标签/搜索