Java Server Sent Event – Automatically update web pages
source link: https://marco.dev/2016/04/17/java-server-sent-event-automatically-update-web-pages/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Code source here: https://github.com/marco76/javaSSE
How a client (ex. web browser) can get updates from a server? Here some options:
1. Polling
The client regularly request to the server new data using a simple request/response via HTTP.
2. Websocket
Java EE 7 and Spring 4 implemented the WebSocket protocol that allows a bi-directional communication between a client and a server using TCP. The HTTP is used only for the handshake. WebSockets are the appropriate solution for application that need frequent exchange of small chunks of data at high speed (ex. trading, videogames, …).
3. Server-side events
HTML5 allows an unidirectional communication similar to the publish/subscribe model in JMS. The protocol used is HTTP and is described in the W3C documentation (note than IE is not compatible).
The events can be broadcasted multiple clients:
This solution is appropriate for application that require to be notified about new events (newsfeed, twitter-like, stock market etc.)
In Java the support for SSE is not yet a standard (it should be in Java EE 8). You can implement it using a Servlet or use some of the libraries that already support it : Jersey and Spring.
The following example uses Jersey in a Java EE environment (Weblogic).
Example
In this example we simulate the ‘live’ visualisation of a simple running competition. The result time (and the time of appearance) is randomly defined.
The class that produces the result is a standard REST java class. The resource must produce a SERVER_SENT_EVENTS type. The method return an EventOutput class. This object maintain the connection with the client and send the results with the write() method
@Path("competition") public class SseEventOutput { static Logger logger = Logger.getLogger("HelloSse.class"); // EventOutput is created when the client open this resource // the method return the object EventOutput to the client (http) // until when the EventOutput is not closed it can send data to the client using write() EventOutput eventOutput = new EventOutput(); @Path("results") @GET @Produces(SseFeature.SERVER_SENT_EVENTS) public EventOutput getServerSentEvents() {
In the next fragment of code we show when the new data is sent to the client browser using the write method:
// prepare the OutboundEvent to send to the client browser OutboundEvent event = buildOutboundEvent(runner); logger.log(Level.INFO, "writing the result for the participant in position: " + position); // the event is sent to the client // the EventOutput is already returned to the client but until when is not closed it can send messages to the client eventOutput.write(event); // waiting for the next runner position++;
The data to send is created and stored in the OutboundEvent object. In the object is defined in which format the data will be sent (JSON).
private OutboundEvent buildOutboundEvent(final Runner runner){ OutboundEvent.Builder eventBuilder = new OutboundEvent.Builder(); eventBuilder.name(LocalTime.now() + " - runner at the finish ... "); // the runner object will be converted to JSON eventBuilder.data(Runner.class, runner); eventBuilder.mediaType(MediaType.APPLICATION_JSON_TYPE); return eventBuilder.build(); }
Here the result of the execution:
and the log:
While the connection was open Chrome showed the ‘working in progress’ icon:
Broadcast
In the class SSEBroadcast you can find an example of how the broadcast implementation works.
In the image you can see the result of sending 3 messages using post (green terminal) to the resource /api/hello_sse_broadcast/send.
The black terminal and chrome opened the page /api/hello_sse_broadcast/listen and they received the messages (chrome connected later and received only 2 messages).
The implementation of the broadcast require a Singleton:
@Path("hello_sse_broadcast") @Singleton // singleton, one producer and multiple listener public class SseBroadcast { SseBroadcaster broadcaster = new SseBroadcaster();
We implemented one resource that return an EventOutput object. This object allows the communication between the server and the client. This resource is called by the client that subscribe the notifications/events :
/** * When a client connect to this resource it opens a communication channel. * @return */ @Path("listen") @GET @Produces(SseFeature.SERVER_SENT_EVENTS) public EventOutput listenData() { final EventOutput eventOutput = new EventOutput(); this.broadcaster.add(eventOutput); return eventOutput; }
Another resource receive the POST messages and create an event to send to the subscribers:
/** * For each call to this method some data is broadcasted to the listeners * @return */ @POST @Path("send") public String sendData(@FormParam(value = "text") String text) { OutboundEvent.Builder builder = new OutboundEvent.Builder(); builder.comment("optional comment: " + text); builder.data(Calendar.getInstance().getTime().toString()); builder.mediaType(MediaType.APPLICATION_JSON_TYPE); broadcaster.broadcast(builder.build()); return "date sent"; } }
Interesting references:
Recommend
-
33
Server Sent Events with Spring Boot and ReactJS Spring • Jan 16, 2021
-
11
Tutorial How To Use Server-Sent Events in Node.js to Build a Realtime App Node.js ...
-
7
hello! Yesterday I learned about a cool new way of streaming events from a server I hadn’t heard of before: server-sent events! They seem like a simpler alternative...
-
6
-
6
TechApple sends invites for Oct. 18 launch event, where new MacBooks are expectedPublished Tue, Oct 12 202112:13 PM EDTUpdated Tue, Oct 12 20211:39...
-
5
Change the time of the server to the local time sent by Facebook advertisements I am using Facebook C# SDK to get some data from my Facebook p...
-
3
One of the common requests for my Server-Sent Events library is the ability to disconnect clients from a server. My usual answer was that this is best to be implemented...
-
10
Important note It's all free. The idea here is to get a working solution without spending a penny. Introduction I've already talked about GitHub Pages a long while ago when I first c...
-
2
TechApple sends invites for Sept. 7 launch event, new iPhone 14 expected
-
0
Customer Statement/ Vendor Invoices/ & Dunning sent automatically by BTE Implementation Introduction – A typical Business requirement in today’s world is to send certain Finance Outputs via email au...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK