Server-sent events

Typically, every interaction between a web service and its client is initiated by the client; the client sends a request (GET, POST, PUT, or DELETE), then receives a response from the server. Server-sent events technology allows RESTful web services to "take the initiative" to send messages to a client, that is, to send data that is not a response to a client request. Server-sent events are useful for sending data continuously to a client, for applications such as stock tickers, news feeds, sports scores, and so on.

JAX-RS 2.1 introduces server-sent event support. The following example illustrates how to implement this functionality into our JAX-RS RESTful web services:

package net.ensode.javaee8book.jaxrs21sse; 
 
import java.util.List; 
import java.util.concurrent.Executor; 
import java.util.concurrent.Executors; 
import java.util.concurrent.TimeUnit; 
import java.util.stream.Collectors; 
import java.util.stream.Stream; 
import javax.ws.rs.GET; 
import javax.ws.rs.Path; 
import javax.ws.rs.Produces; 
import javax.ws.rs.core.Context; 
import javax.ws.rs.core.MediaType; 
import javax.ws.rs.sse.OutboundSseEvent; 
import javax.ws.rs.sse.Sse; 
import javax.ws.rs.sse.SseEventSink; 
 
@Path("serversentevents") 
public class SseResource { 
 
    List<Float> stockTickerValues = null; 
    Executor executor = Executors.newSingleThreadExecutor(); 
 
    @GET 
    @Produces(MediaType.SERVER_SENT_EVENTS) 
    public void sendEvents(@Context SseEventSink sseEventSink,        
@Context Sse sse) {
initializeStockTickerValues(); executor.execute(() -> { stockTickerValues.forEach(value -> { try { TimeUnit.SECONDS.sleep(5); System.out.println(String.format( "Sending the following value: %.2f", value)); final OutboundSseEvent outboundSseEvent =
sse.newEventBuilder()

.name("ENSD stock ticker value")

.data(String.class,
String.format("%.2f", value))

.build();

sseEventSink.send(outboundSseEvent);
} catch (InterruptedException ex) { ex.printStackTrace(); } }); }); } private void initializeStockTickerValues() { stockTickerValues = Stream.of(50.3f, 55.5f, 62.3f,
70.7f, 10.1f, 5.1f).collect(Collectors.toList()); } }

The preceding example simulates sending stock prices for a fictitious company to the client. To send server-sent events to the client, we need to utilize instances of the SseEventSink and Sse classes, as illustrated in our example. Both of these classes are injected into our RESTful web service via the @Context annotation.

To send an event, we first need to build an instance of OutboundSseEvent via the newEventBuilder() method of our Sse instance. This method creates an instance of OutboundSseEvent.Builder, which is then used to create the necessary OutboundSseEvent instance.

We give our event a name by invoking the name() method on our OutboundSseEvent.Builder instance, then set the data to be sent to the client via its data() method. The data() method takes two arguments: the first one is the type of data we are sending to the client (String, in our case), and the second one is the actual data we send to the client.

Once we have set our event's name and data via the corresponding method, we build an instance of OutboundSseEvent by invoking the build() method on OutboundSseEvent.Builder.

Once we have built our instance of OutboundSseEvent, we send it to the client by passing it as a parameter to the send() method of SseEventSink. In our example, we loop through the simulated stock prices and send it to the client.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.223.239.226