io.vertx.core.eventbus.package-info Maven / Gradle / Ivy
/**
* == The Event Bus
* :toc: left
*
* The {@link io.vertx.core.eventbus.EventBus 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 method {@link io.vertx.core.Vertx#eventBus}.
*
* 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 and
* sending 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 message
* to 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 to
* the 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 called *best-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 senders
* to retry after recovery.
*
* ==== Types of messages
*
* Out of the box Vert.x allows any primitive/simple type, String, or {@link io.vertx.core.buffer.Buffer buffers} to
* be sent as messages.
*
* However it's a convention and common practice in Vert.x to send messages as http://json.org/[JSON]
*
* JSON is very easy to create, read and parse in all the languages that Vert.x supports so it has become a kind of
* _lingua 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 a {@link io.vertx.core.eventbus.MessageCodec codec} 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:
*
* [source,$lang]
* ----
* {@link examples.EventBusExamples#example0_5}
* ----
*
* There is a single instance of the event bus per Vert.x instance.
*
* ==== Registering Handlers
*
* This simplest way to register a handler is using {@link io.vertx.core.eventbus.EventBus#consumer(String, io.vertx.core.Handler)}.
* Here's an example:
*
* [source,$lang]
* ----
* {@link examples.EventBusExamples#example1}
* ----
*
* When a message arrives for your handler, your handler will be called, passing in the {@link io.vertx.core.eventbus.Message message}.
*
* The object returned from call to +consumer()+ is an instance of {@link io.vertx.core.eventbus.MessageConsumer}
*
* This object can subsequently be used to unregister the handler, or use the handler as a stream.
*
* Alternatively you can use {@link io.vertx.core.eventbus.EventBus#consumer(String, io.vertx.core.Handler)} to
* to return a +MessageConsumer+ with no handler set, and then set the handler on that. For example:
*
* [source,$lang]
* ----
* {@link examples.EventBusExamples#example2}
* ----
*
* When registering a handler on a clustered event bus, it can take some time for the registration to reach all
* nodes of the cluster.
*
* If you want to be notified when this has completed, you can register a {@link io.vertx.core.eventbus.MessageConsumer#completionHandler completion handler}
* on the +MessageConsumer+ object.
*
* [source,$lang]
* ----
* {@link examples.EventBusExamples#example3}
* ----
*
* ==== Un-registering Handlers
*
* To unregister a handler, call {@link io.vertx.core.eventbus.MessageConsumer#unregister}.
*
* If you are on a clustered event bus, un-registering can take some time to propagate across the nodes, if you want to
* be notified when this is complete use {@link io.vertx.core.eventbus.MessageConsumer#unregister(io.vertx.core.Handler)}.
*
* [source,$lang]
* ----
* {@link examples.EventBusExamples#example4}
* ----
*
* ==== Publishing messages
*
* Publishing a message is simple. Just use {@link io.vertx.core.eventbus.EventBus#publish} specifying the
* address to publish it to.
*
* [source,$lang]
* ----
* {@link examples.EventBusExamples#example5}
* ----
*
* 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 {@link io.vertx.core.eventbus.EventBus#send}
*
* [source,$lang]
* ----
* {@link examples.EventBusExamples#example6}
* ----
*
* include::override/eventbus_headers.adoc[]
*
* ==== Message ordering
*
* Vert.x will deliver messages to any particular handler in the same order they were sent from any particular sender.
*
* ==== The Message object
*
* The object you receive in a message handler is a {@link io.vertx.core.eventbus.Message}.
*
* The {@link io.vertx.core.eventbus.Message#body} of the message corresponds to the object that was sent or published.
*
* The headers of the message are available with {@link io.vertx.core.eventbus.Message#headers}.
*
* ==== Acknowledging messages / sending replies
*
* When using {@link io.vertx.core.eventbus.EventBus#send} the event bus attempts to deliver the message to a
* {@link io.vertx.core.eventbus.MessageConsumer} registered with the event bus.
*
* In some cases it's useful for the sender to know when the consumer has received the message and "processed" it.
*
* To acknowledge that the message has been processed the consumer can reply to the message by calling {@link io.vertx.core.eventbus.Message#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:
*
* [source,$lang]
* ----
* {@link examples.EventBusExamples#example8}
* ----
*
* The sender:
*
* [source,$lang]
* ----
* {@link examples.EventBusExamples#example9}
* ----
*
* The reply can contain a message body which can contain useful information.
*
* What the "processing" actually means is application defined and depends entirely on what the message consumer does
* and is not something that the Vert.x event bus itself knows or cares about.
*
* Some examples:
*
* * A simple message consumer which implements a service which returns the time of the day would acknowledge with a message
* containing the time of day in the reply body
* * A message consumer which implements a persistent queue, might acknowledge with `true` if the message was successfully
* persisted in storage, or `false` if not.
* * A message consumer which processes an order might acknowledge with `true` when the order has been successfully processed
* so it can be deleted from the database
*
* ==== Sending with timeouts
*
* When sending a message with a reply handler you can specify a timeout in the {@link io.vertx.core.eventbus.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 {@link io.vertx.core.eventbus.Message#fail}
*
* In all cases the reply handler will be called with the specific failure.
*
* 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 on
* your 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.x
* instance as clustered;
*
* [source,$lang]
* ----
* {@link examples.EventBusExamples#example12}
* ----
*
* You should also make sure you have a {@link io.vertx.core.spi.cluster.ClusterManager} implementation on your classpath,
* for example the default {@code HazelcastClusterManager}.
*
* ==== 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 unregistered
* when the verticle is undeployed.
*
* == Configuring the event bus
*
* The event bus can be configured. It is particularly useful when the event bus is clustered. Under the hood
* the event bus uses TCP connections to send and receive message, so the
* {@link io.vertx.core.eventbus.EventBusOptions} let you configure all aspects of these TCP connections. As
* the event bus acts as a server and client, the configuration is close to
* {@link io.vertx.core.net.NetClientOptions} and {@link io.vertx.core.net.NetServerOptions}.
*
* [source,$lang]
* ----
* {@link examples.EventBusExamples#example13}
* ----
*
* The previous snippet depicts how you can use SSL connections for the event bus, instead of plain TCP
* connections.
*
* **WARNING**: to enforce the security in clustered mode, you **must** configure the
* cluster manager to use encryption or enforce security. Refer to the documentation of the cluster
* manager for further details.
*
* The event bus configuration needs to be consistent in all the cluster nodes.
*
* The {@link io.vertx.core.eventbus.EventBusOptions} also lets you specify whether or not the event bus is
* clustered, the port and host, as you would do with {@link io.vertx.core.VertxOptions#setClustered(boolean)},
* {@link io.vertx.core.VertxOptions#getClusterHost()} and {@link io.vertx.core.VertxOptions#getClusterPort()}.
*
* When used in containers, you can also configure the public host and port:
*
* [source,$lang]
* ----
* {@link examples.EventBusExamples#example14}
* ----
*/
@Document(fileName = "eventbus.adoc")
package io.vertx.core.eventbus;
import io.vertx.docgen.Document;
© 2015 - 2025 Weber Informatics LLC | Privacy Policy