How to do it...

Perform the following steps to try this recipe:

  1. First, we build a REST endpoint to manage the server events we are going to use, and to use REST, we should start by properly configuring it:
@ApplicationPath("webresources")
public class ApplicationConfig extends Application {

}
  1. The following is quite a big chunk of code, but don't worry, we are going to split it up and understand each piece:
@Path("serverSentService")
@RequestScoped
public class ServerSentService {

private static final Map<Long, UserEvent> POOL =
new ConcurrentHashMap<>();

@Resource(name = "LocalManagedExecutorService")
private ManagedExecutorService executor;

@Path("start")
@POST
public Response start(@Context Sse sse) {

final UserEvent process = new UserEvent(sse);

POOL.put(process.getId(), process);
executor.submit(process);

final URI uri = UriBuilder.fromResource(ServerSentService.class).path
("register/{id}").build(process.getId());
return Response.created(uri).build();
}

@Path("register/{id}")
@Produces(MediaType.SERVER_SENT_EVENTS)
@GET
public void register(@PathParam("id") Long id,
@Context SseEventSink sseEventSink) {
final UserEvent process = POOL.get(id);

if (process != null) {
process.getSseBroadcaster().register(sseEventSink);
} else {
throw new NotFoundException();
}
}

static class UserEvent implements Runnable {

private final Long id;
private final SseBroadcaster sseBroadcaster;
private final Sse sse;

UserEvent(Sse sse) {
this.sse = sse;
this.sseBroadcaster = sse.newBroadcaster();
id = System.currentTimeMillis();
}

Long getId() {
return id;
}

SseBroadcaster getSseBroadcaster() {
return sseBroadcaster;
}

@Override
public void run() {
try {
TimeUnit.SECONDS.sleep(5);
sseBroadcaster.broadcast(sse.newEventBuilder().
name("register").data(String.class, "Text from event "
+ id).build());
sseBroadcaster.close();
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}
}
}
}
  1. Here, we have a bean to manage the UI and help us with a better view of what is happening in the server:
@ViewScoped
@Named
public class SseBean implements Serializable {

@NotNull
@Positive
private Integer countClient;

private Client client;

@PostConstruct
public void init(){
client = ClientBuilder.newClient();
}

@PreDestroy
public void destroy(){
client.close();
}

public void sendEvent() throws URISyntaxException, InterruptedException {
WebTarget target = client.target(URI.create("http://localhost:8080/
ch03-sse/"));
Response response =
target.path("webresources/serverSentService/start")
.request()
.post(Entity.json(""), Response.class);

FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage("Sse Endpoint: " +
response.getLocation()));

final Map<Integer, String> messageMap = new ConcurrentHashMap<>
(countClient);
final SseEventSource[] sources = new
SseEventSource[countClient];

final String processUriString =
target.getUri().relativize(response.getLocation()).
toString();
final WebTarget sseTarget = target.path(processUriString);

for (int i = 0; i < countClient; i++) {
final int id = i;
sources[id] = SseEventSource.target(sseTarget).build();
sources[id].register((event) -> {
final String message = event.readData(String.class);

if (message.contains("Text")) {
messageMap.put(id, message);
}
});
sources[i].open();
}

TimeUnit.SECONDS.sleep(10);

for (SseEventSource source : sources) {
source.close();
}

for (int i = 0; i < countClient; i++) {
final String message = messageMap.get(i);

FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage("Message sent to client " +
(i + 1) + ": " + message));
}
}

public Integer getCountClient() {
return countClient;
}

public void setCountClient(Integer countClient) {
this.countClient = countClient;
}

}
  1. And finally, the UI is a code with a simple JSF (short for JavaServer Faces) page:
<h:body>
<h:form>
<h:outputLabel for="countClient" value="Number of Clients" />
<h:inputText id="countClient" value="#{sseBean.countClient}" />

<br />
<h:commandButton type="submit" action="#{sseBean.sendEvent()}"
value="Send Events" />
</h:form>
</h:body>
..................Content has been hidden....................

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