vert.x event bus
来源:互联网 发布:知乎 太空旅行 编辑:程序博客网 时间:2024/05/04 20:44
The Event Bus
The event bus
is the nervous system of Vert.x.
There is a single event bus instance for every Vert.x instance and it is obtained using the methodeventBus
.
The event bus allows different parts of your application to communicate with each other irrespective of what language they are written in,and whether they’re in the same Vert.x instance, or in a different Vert.x instance.
It can even be bridged to allow client side JavaScript running in a browser to communicate on the same event bus.
The event bus forms a distributed peer-to-peer messaging system spanning multiple server nodes and multiple browsers.
The event bus supports publish/subscribe, point to point, and request-response messaging.
The event bus API is very simple. It basically involves registering handlers, unregistering handlers andsending and publishing messages.
First some theory:
The Theory
Addressing
Messages are sent on the event bus to an address.
Vert.x doesn’t bother with any fancy addressing schemes. In Vert.x an address is simply a string.Any string is valid. However it is wise to use some kind of scheme, e.g. using periods to demarcate a namespace.
Some examples of valid addresses are europe.news.feed1, acme.games.pacman, sausages, and X.
Handlers
Messages are received in handlers. You register a handler at an address.
Many different handlers can be registered at the same address.
A single handler can be registered at many different addresses.
Publish / subscribe messaging
The event bus supports publishing messages.
Messages are published to an address. Publishing means delivering the messageto all handlers that are registered at that address.
This is the familiar publish/subscribe messaging pattern.
Point to point and Request-Response messaging
The event bus also supports point to point messaging.
Messages are sent to an address. Vert.x will then route it to just one of the handlers registered at that address.
If there is more than one handler registered at the address,one will be chosen using a non-strict round-robin algorithm.
With point to point messaging, an optional reply handler can be specified when sending the message.
When a message is received by a recipient, and has been handled, the recipient can optionally decide to reply tothe message. If they do so the reply handler will be called.
When the reply is received back at the sender, it too can be replied to. This can be repeated ad-infinitum,and allows a dialog to be set-up between two different verticles.
This is a common messaging pattern called the request-response pattern.
Best-effort delivery
Vert.x does it’s best to deliver messages and won’t consciously throw them away. This is calledbest-effort delivery.
However, in case of failure of all or parts of the event bus, there is a possibility messages will be lost.
If your application cares about lost messages, you should code your handlers to be idempotent, and your sendersto retry after recovery.
Types of messages
Out of the box Vert.x allows any primitive/simple type, String, or buffers
tobe sent as messages.
However it’s a convention and common practice in Vert.x to send messages as JSON
JSON is very easy to create, read and parse in all the languages that Vert.x supports so it has become a kind oflingua franca for Vert.x.
However you are not forced to use JSON if you don’t want to.
The event bus is very flexible and also supports sending arbitrary objects over the event bus.You do this by defining acodec
for the objects you want to send.
The Event Bus API
Let’s jump into the API
Getting the event bus
You get a reference to the event bus as follows:
EventBus eb = vertx.eventBus();
There is a single instance of the event bus per Vert.x instance.
Registering Handlers
This simplest way to register a handler is using consumer
.Here’s an example:
EventBus eb = vertx.eventBus();eb.consumer("news.uk.sport", message -> { System.out.println("I have received a message: " + message.body());});
When a message arrives for your handler, your handler will be called, passing in themessage
.
The object returned from call to consumer() is an instance of MessageConsumer
This object can subsequently be used to unregister the handler, or use the handler as a stream.
Alternatively you can use consumer
toto return a MessageConsumer with no handler set, and then set the handler on that. For example:
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());});
When registering a handler on a clustered event bus, it can take some time for the registration to reach allnodes of the cluster.
If you want to be notified when this has completed, you can register a completion handler
on the MessageConsumer object.
consumer.completionHandler(res -> { if (res.succeeded()) { System.out.println("The handler registration has reached all nodes"); } else { System.out.println("Registration failed!"); }});
Un-registering Handlers
To unregister a handler, call unregister
.
If you are on a clustered event bus, un-registering can take some time to propagate across the nodes, if you want tobe notified when this is complete useunregister
.
consumer.unregister(res -> { if (res.succeeded()) { System.out.println("The handler un-registration has reached all nodes"); } else { System.out.println("Un-registration failed!"); }});
Publishing messages
Publishing a message is simple. Just use publish
specifying theaddress to publish it to.
eventBus.publish("news.uk.sport", "Yay! Someone kicked a ball");
That message will then be delivered to all handlers registered against the address news.uk.sport.
Sending messages
Sending a message will result in only one handler registered at the address receiving the message.This is the point to point messaging pattern. The handler is chosen in a non-strict round-robin fashion.
You can send a message with send
eventBus.send("news.uk.sport", "Yay! Someone kicked a ball");
Unresolved directive in <stdin> - include::override/eventbus_headers.adoc[]==== The Message object
The object you receive in a message handler is a Message
.
The body
of the message corresponds to the object that was sent or published.
The headers of the message are available with headers
.
Replying to messages
Sometimes after you send a message you want to receive a reply from the recipient.This is known as therequest-response pattern.
To do this you can specify a reply handler when sending the message.
When the receiver receives the message they can reply to it by calling reply
.
When this happens it causes a reply to be sent back to the sender and the reply handler is invoked with the reply.
An example will make this clear:
The receiver:
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!");});
The sender:
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()); }});
The replies themselves can also be replied to so you can create a dialog between two different partiesconsisting of multiple rounds.
Sending with timeouts
When sending a message with a reply handler you can specify a timeout in the DeliveryOptions
.
If a reply is not received within that time, the reply handler will be called with a failure.
The default timeout is 30 seconds.
Send Failures
Message sends can fail for other reasons, including:
There are no handlers available to send the message to
The recipient has explicitly failed the message using
fail
In all cases the reply handler will be called with the specific failure.
Unresolved directive in <stdin> - include::override/eventbus.adoc[]==== Clustered Event Bus
The event bus doesn’t just exist in a single Vert.x instance. By clustering different Vert.x instances together onyour network they can form a single, distributed, event bus.
Clustering programmatically
If you’re creating your Vert.x instance programmatically you get a clustered event bus by configuring the Vert.xinstance as clustered;
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()); }});
You should also make sure you have a ClusterManager
implementation on your classpath,for example the defaultHazelcastClusterManager
.
Clustering on the command line
You can run Vert.x clustered on the command line with
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.
- vert.x event bus
- Vert.x 技术内幕|Event Bus源码分析(Local 模式)
- Vert.x
- Vert.x
- event-bus
- Vert.x 3---Vert.x 实现REST
- vert.x笔记:1.vert.x介绍
- Vert.x开发指南
- Vert.x安装指南
- Vert.x特性
- vert.x入门
- Verticle in Vert.x
- Vert.x一些概念
- Vert.x module概念
- # vert.x学习笔记
- Vert.x开篇
- Vert.x入门实例
- Vert.x开发指南
- monkeytalk命令行格式
- 以AFNetwoking为例讲解如何利用CocoaPod导入第三方类库
- Ant 风格
- 权限管理 思路
- java反射机制
- vert.x event bus
- combobox 加载数据后,点不动的原因 是因为没有 设置 valueField 和 textField
- c++的进程和线程【windows】
- c++链表实例与链表基本知识
- 简易click事件判断取代toggle
- 打造你的专属工具包之Android篇
- 关于类变量的加载顺序问题
- leetcode Two Sum 不采用hash,一种取巧的暴力方法(不推荐)
- js中子窗口与父窗口的互操作