Event Bus Point to Point Messaging

Event Bus Point to Point Messaging

In this tutorial, we are going to discuss about the Event Bus Point to Point Messaging. The second possibility of communicating over the event bus is point to point communication.

Event Bus Point to Point Messaging in the Vert.x refers to sending a message to a specific handler, where only one recipient (verticle) processes the message. This contrasts with publish/subscribe messaging, where multiple listeners can receive the same message.

In Event bus point to point messaging, Vert.x uses the send() method, which sends a message to a single consumer (or handler) listening on a given address. If multiple consumers are listening on the same address, Vert.x uses a round-robin mechanism to distribute the messages among the consumers.

One verticle is sending a message to another one without any response. Additionally, we will see how the behavior is when scaling the receiver. For our example, we are creating a new class with the name PointToPointExample where we do the usual setup on creating a vertx instance, deploying sender and receiver verticles similar to the previous example.

package com.ashok.vertx.vertx_starter.eventbus;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.vertx.core.AbstractVerticle;
import io.vertx.core.Promise;
import io.vertx.core.Vertx;

/**
 *
 * @author ashok.mariyala
 *
 */
public class PointToPointExample {

  public static void main(String[] args) {
    var vertx = Vertx.vertx();
    vertx.deployVerticle(new Sender());
    vertx.deployVerticle(new Receiver());
  }

  public static class Sender extends AbstractVerticle {
    @Override
    public void start(final Promise<Void> startPromise) throws Exception {
      startPromise.complete();
      vertx.setPeriodic(1000, id -> {
        // Send a message every second
        vertx.eventBus().send(Sender.class.getName(), "Sending a message...");
      });
    }
  }

  public static class Receiver extends AbstractVerticle {

    private static final Logger LOG = LoggerFactory.getLogger(Receiver.class);

    @Override
    public void start(final Promise<Void> startPromise) throws Exception {
      startPromise.complete();
      vertx.eventBus().<String>consumer(Sender.class.getName(), message -> {
        LOG.debug("Received: {}", message.body());
      });
    }
  }
}

Please note that in Event Bus Point to Point Messaging, we are using vertx.eventBus().send() method to send messages. Where as in Request and Response, we used vertx.eventBus().request() method to send messages.

As we discussed previous tutorial, Vertx does not enforce an address schema so you can use any address you want. Personally, I established a best practice to use the full name of the sender class to keep the address unique and make debugging easier. Therefore, the first parameter will get the content sender class name.

And similar to the previous example second parameter we are passing a message with the content sending a message.

In the receiver verticle we are consuming the message by calling vertx.eventBus().consumer() same like previous example To see the message we added the logger statement. So lets execute our code.

11:35:49 am: Executing ':PointToPointExample.main()'...

Starting Gradle Daemon...
Gradle Daemon started in 1 s 871 ms
> Task :compileJava
> Task :processResources UP-TO-DATE
> Task :classes

> Task :PointToPointExample.main()
[vert.x-eventloop-thread-1] DEBUG com.ashok.vertx.vertx_starter.eventbus.PointToPointExample$Receiver - Received: Sending a message...
[vert.x-eventloop-thread-1] DEBUG com.ashok.vertx.vertx_starter.eventbus.PointToPointExample$Receiver - Received: Sending a message...
[vert.x-eventloop-thread-1] DEBUG com.ashok.vertx.vertx_starter.eventbus.PointToPointExample$Receiver - Received: Sending a message...
[vert.x-eventloop-thread-1] DEBUG com.ashok.vertx.vertx_starter.eventbus.PointToPointExample$Receiver - Received: Sending a message...
[vert.x-eventloop-thread-1] DEBUG com.ashok.vertx.vertx_starter.eventbus.PointToPointExample$Receiver - Received: Sending a message...
[vert.x-eventloop-thread-1] DEBUG com.ashok.vertx.vertx_starter.eventbus.PointToPointExample$Receiver - Received: Sending a message...
[vert.x-eventloop-thread-1] DEBUG com.ashok.vertx.vertx_starter.eventbus.PointToPointExample$Receiver - Received: Sending a message...

We’re not just sending one message, but we’re adding a periodic timer that will send a message each second. So for every second sender verticle is sending the message and receiver verticle receiving the messages.

This every second because the timer is firing every second and our receiver is logging the received message. With this approach, we can communicate in a thread safe way between verticles and we don’t have to worry about concurrency issues.

Key Concepts of Event Bus Point to Point Messaging in Vert.x
  1. Single Consumer: The message is received and processed by only one verticle, even if multiple verticles are listening on the same address.
  2. Asynchronous Messaging: The communication is non-blocking, so the sender sends the message and moves on without waiting for the consumer to finish its processing.
  3. Round-Robin Distribution: If multiple consumers are registered on the same address, Vert.x distributes the messages in a round-robin manner.
  4. Send and Forget: The sender can choose to send a message without expecting any response or acknowledgment from the recipient.
Round-Robin Distribution in Point to Point Messaging

If multiple consumers are registered on the same address, Vert.x will automatically distribute messages in a round-robin fashion. This is useful for load balancing.

Let’s assume we have two consumers listening on the same address. Vert.x will alternate between them when messages are sent.

public class ConsumerVerticle1 extends AbstractVerticle {
    @Override
    public void start(final Promise<Void> startPromise) {
        startPromise.complete();
        vertx.eventBus().consumer("point-to-point-address", message -> {
            LOG.debug("Consumer 1 received: {} " , message.body());
        });
    }
}

public class ConsumerVerticle2 extends AbstractVerticle {
    @Override
    public void start(final Promise<Void> startPromise) {
        startPromise.complete();
        vertx.eventBus().consumer("point-to-point-address", message -> {
            LOG.debug("Consumer 2 received: {} " , message.body());
        });
    }
}

If you send multiple messages from the sender:

public class PointToPointSenderVerticle extends AbstractVerticle {
    @Override
    public void start(final Promise<Void> startPromise) {
        startPromise.complete();
        for (int i = 1; i <= 5; i++) {
            vertx.eventBus().send("point-to-point-address", "Message " + i);
        }
    }
}

The output might look like this:

[vert.x-eventloop-thread-1] DEBUG com.ashok.vertx.vertx_starter.eventbus.ConsumerVerticle1 - Consumer 1 received: Message 1
[vert.x-eventloop-thread-1] DEBUG com.ashok.vertx.vertx_starter.eventbus.ConsumerVerticle1 - Consumer 2 received: Message 2
[vert.x-eventloop-thread-1] DEBUG com.ashok.vertx.vertx_starter.eventbus.ConsumerVerticle1 - Consumer 1 received: Message 3
[vert.x-eventloop-thread-1] DEBUG com.ashok.vertx.vertx_starter.eventbus.ConsumerVerticle1 - Consumer 2 received: Message 4
[vert.x-eventloop-thread-1] DEBUG com.ashok.vertx.vertx_starter.eventbus.ConsumerVerticle1 - Consumer 1 received: Message 5

Here Vert.x distributes messages evenly between the consumers using the round-robin strategy.

Asynchronous Reply in Event Bus Point to Point Messaging

In addition to simple “fire-and-forget” messaging, you can use the request/response pattern within point-to-point messaging, where the sender expects a reply from the receiver.

vertx.eventBus().send("point-to-point-address", "Hello", reply -> {
    if (reply.succeeded()) {
        System.out.println("Reply received: " + reply.result().body());
    } else {
        System.out.println("No reply received");
    }
});
Advantages of Point-to-Point Messaging

1. Resource Efficiency

  • Only one verticle (or handler) processes each message, making point to point messaging more efficient for scenarios where multiple consumers don’t need to handle the same message.

2. Load Balancing

  • When multiple consumers are registered on the same address, Vert.x distributes the load among them, which is useful for distributing work.

That’s all about the Event Bus Point to Point Messaging. If you have any queries or feedback, please write us email at contact@waytoeasylearn.com. Enjoy learning, Enjoy Vert.x tutorials..!!

Event Bus Point to Point Messaging
Scroll to top