- What you’ll learn
- Additional prerequisites
- Getting started
- Setting up SSE in the bff service
- Configuring the Kafka connector for the bff service
- Configuring the frontend service to subscribe to and consume events
- Building and running the application
- Tearing down the environment
- Great work! You’re done!
- Related Links
- Guide Attribution
Streaming updates to a client using Server-Sent Events
Learn how to stream updates from a MicroProfile Reactive Messaging service to a front-end client by using Server-Sent Events (SSE).
What you’ll learn
You will learn how to stream messages from a MicroProfile Reactive Messaging service to a front-end client by using Server-Sent Events (SSE).
MicroProfile Reactive Messaging provides an easy way for Java services to send requests to other Java services, and asynchronously receive and process the responses as a stream of events. SSE provides a framework to stream the data in these events to a browser client.
What is SSE?
Server-Sent Events is an API that allows clients to subscribe to a stream of events that is pushed from a server. First, the client makes a connection with the server over HTTP. The server continuously pushes events to the client as long as the connection persists. SSE differs from traditional HTTP requests, which use one request for one response. SSE also differs from Web Sockets in that SSE is unidirectional from the server to the client, and Web Sockets allow for bidirectional communication.
For example, an application that provides real-time stock quotes might use SSE to push price updates from the server to the browser as soon as the server receives them. Such an application wouldn’t need Web Sockets because the data travels in only one direction, and polling the server by using HTTP requests wouldn’t provide real-time updates.
The application that you will build in this guide consists of a
bff (backend for frontend) service, and three instances of a
system service. The
system services periodically publish messages that
contain their hostname and current system load. The
bff service receives the
messages from the
client in the
frontend service. This client uses the events to update a table
in the UI that displays each system’s hostname and its periodically updating
load. The following diagram depicts the application that is used in this guide:
In this guide, you will set up the
bff service by creating an endpoint that
clients can use to subscribe to events. You will also enable the service to read
from the reactive messaging channel and push the contents to subscribers via
SSE. After that, you will configure the Kafka connectors to allow the
service to receive messages from the
system services. Finally, you will
configure the client in the
frontend service to subscribe to these events,
consume them, and display them in the UI.
To learn more about the reactive Java services that are used in this guide, check out the Creating reactive Java microservices guide.
The fastest way to work through this guide is to clone the Git repository and use the projects that are provided inside:
git clone https://github.com/openliberty/guide-reactive-messaging-sse.git cd guide-reactive-messaging-sse
start directory contains the starting project that you will build upon.
finish directory contains the finished project that you will build.
Before you begin, make sure you have all the necessary prerequisites.
Setting up SSE in the bff service
In this section, you will create a REST API for SSE in the
bff service. When a
client makes a request to this endpoint, the initial connection between the
client and server is established and the client is subscribed to receive events
that are pushed from the server. Later in this guide, the client in the
service uses this endpoint to subscribe to the events that are pushed from the
Additionally, you will enable the
bff service to read messages from the
incoming stream and push the contents as events to subscribers via SSE.
Navigate to the
start directory to begin.
Create the BFFResource class.
Creating the SSE API endpoint
subscribeToSystem() method allows
clients to subscribe to events via an HTTP
GET request to the
@Produces(MediaType.SERVER_SENT_EVENTS) annotation sets the
Content-Type in the
response header to
text/event-stream. This content type indicates that client requests that are made
to this endpoint are to receive Server-Sent Events. Additionally, the method
parameters take in an instance of the
SseEventSink class and
Sse class, both of which are injected using the
annotation. First, the method checks if the
broadcaster instance variables are assigned.
If these variables aren’t assigned, the
sse variable is obtained from the
@Context injection and the
is obtained by using the
method. Then, the
register() method is called to
SseEventSink instance to the
SseBroadcaster instance to subscribe to events.
Reading from the reactive messaging channel
receives the message that contains the hostname and the average system load. The
@Incoming("systemLoad") annotation indicates that
the method retrieves the message by connecting to the
systemLoad channel in
Kafka, which you configure in the next section.
Each time a message is received, the
getSystemLoadMessage() method is called, and the hostname and system
load contained in that message are broadcasted in an event to all subscribers.
Broadcasting events is handled in the
broadcastData() method. First, it checks whether the
broadcaster value is
There must be at least one subscriber or there’s no
client to send the event to. If the
broadcaster value is specified, the
OutboundSseEvent interface is created by using the
Sse.newEventBuilder() method, where the
name of the
data it contains, and the
mediaType are set. The
OutboundSseEvent interface is then
broadcasted, or sent to all registered sinks, by invoking the
You just set up an endpoint in the
bff service that the client in the
frontend service can use to subscribe to events. You also enabled the
service to read from the reactive messaging channel and broadcast the
information as events to subscribers via SSE.
Configuring the Kafka connector for the bff service
system service is provided for you in the
system service is the producer of the messages that are
published to the Kafka messaging system. The periodically
published messages contain the system’s hostname and a calculation of the
average system load (its CPU usage) for the last minute.
Configure the Kafka connector in the
bff service to receive the messages from the
Create the microprofile-config.properties file.
bff service uses an incoming connector to receive messages through
systemLoad channel. The messages are
then published by the
system service to the
system.load topic in the Kafka message broker. The
value.deserializer properties define how to
deserialize the messages. The
defines a unique name for the consumer group. All of these properties are
required by the Apache
Kafka Consumer Configs documentation.
Configuring the frontend service to subscribe to and consume events
In this section, you will configure the client in the
frontend service to subscribe to events
and display their contents in a table in the UI.
The front-end UI is a table where each row contains the hostname and load of one of the three
The HTML and styling for the UI is provided for you but you must populate the table with
information that is received from the Server-Sent Events.
Create the index.js file.
Subscribing to SSE
initSSE() method is called when the page first
loads. This method subscribes the client to the SSE by creating a new instance of the
EventSource interface and specifying the
http://localhost:9084/bff/sse URL in the parameters. The
EventSource interface makes a
GET request to this endpoint with a
request header of
Accept: text/event-stream to connect to the server.
Because this request comes from
localhost:9080 and is made to
localhost:9084, it must follow the Cross-Origin Resource Sharing (CORS)
specification to avoid being blocked by the browser. To enable CORS for the
client, set the
withCredentials configuration element to true in the
parameters of the
EventSource interface. CORS is
already enabled for you in the
bff service. To learn more about CORS, check out
the CORS guide.
Consuming the SSE
EventSource.addEventListener() method is
called to add an event listener. This event listener listens for events with
the name of
systemLoadHandler() function is set as the
handler function, and each time an event is received, this function is called.
systemLoadHandler() function will take the event
object. The contents of this object are used to
update the table with the system hostname and load. If a system is already present in the table, the load is
updated, otherwise a new row is added for the system.
Building and running the application
To build the application, navigate to the
start directory and run the following Maven
package goals from the command line:
mvn -pl models install mvn package
Run the following command to download or update to the latest Open Liberty Docker image:
docker pull openliberty/open-liberty:full-java11-openj9-ubi
Run the following commands to containerize the
docker build -t frontend:1.0-SNAPSHOT frontend/. docker build -t bff:1.0-SNAPSHOT bff/. docker build -t system:1.0-SNAPSHOT system/.
Next, use the following
startContainers.sh script to start the application in Docker containers:
This script creates a network for the containers to communicate with each other. It
also creates containers for Kafka, Zookeeper, the
frontend service, the
bff service , and three
instances of the
Once your application is up and running, open your browser and check out your service by visiting http://localhost:9080. The application might take some time to get ready. The latest version of most modern web browsers supports Server-Sent Events. The exception is Internet Explorer, which does not support SSE.
When you visit the URL, look for a table similar to the following example:
The table contains three rows, one for each of the running
containers. If you can see the loads updating, you know that your
is successfully receiving messages and broadcasting them as SSE to the client in the
Tearing down the environment
Run the following script to stop the application:
Great work! You’re done!
You developed an application that subscribes to Server-Sent Events by using MicroProfile Reactive Messaging, Open Liberty, and Kafka.
Streaming updates to a client using Server-Sent Events by Open Liberty is licensed under CC BY-ND 4.0
Nice work! Where to next?
What did you think of this guide?
Thank you for your feedback!
Thank you for your feedback!
Would you like to open an issue in GitHub?Yes
What could make this guide better?
Raise an issue to share feedback
Create a pull request to contribute to this guide