/** * Get the new SSE message stream channel. * * @return new SSE message stream channel. */ @GET @Produces(SseFeature.SERVER_SENT_EVENTS) public EventOutput getMessageStream() { LOGGER.info("--> SSE connection received."); final EventOutput eventOutput = new EventOutput(); broadcaster.add(eventOutput); return eventOutput; }
/** * Put a new message to the stream. * * The message will be broadcast to all registered SSE clients. * * @param message message to be broadcast. */ @PUT @Consumes(MediaType.APPLICATION_JSON) public void putMessage(final Message message) { LOGGER.info("--> Message received."); final OutboundEvent event = new OutboundEvent.Builder() .id(String.valueOf(nextMessageId.getAndIncrement())) .mediaType(MediaType.APPLICATION_JSON_TYPE) .data(Message.class, message) .build(); broadcaster.broadcast(event); }
public void run() { try { if (latch != null) { // wait for all test EventSources to be registered latch.await(5, TimeUnit.SECONDS); } broadcaster.broadcast( new OutboundEvent.Builder().name("domain-progress").data(String.class, "starting domain " + id + " ...") .build()); broadcaster.broadcast(new OutboundEvent.Builder().name("domain-progress").data(String.class, "50%").build()); broadcaster.broadcast(new OutboundEvent.Builder().name("domain-progress").data(String.class, "60%").build()); broadcaster.broadcast(new OutboundEvent.Builder().name("domain-progress").data(String.class, "70%").build()); broadcaster.broadcast(new OutboundEvent.Builder().name("domain-progress").data(String.class, "99%").build()); broadcaster.broadcast(new OutboundEvent.Builder().name("domain-progress").data(String.class, "done").build()); broadcaster.closeAll(); } catch (InterruptedException e) { e.printStackTrace(); } } }
public class MessageBoardResource { private static SseBroadcaster broadcaster = new SseBroadcaster(); broadcaster.add(eventOutput); return eventOutput; broadcaster.broadcast(event); // invokes eventOutput.write(event);
protected void activate() { broadcaster = new SseBroadcaster(); broadcaster.add(this); }
public class TestServlet extends HttpServlet { SseBroadcaster broadcaster = new SseBroadcaster(); @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Scanner scanner = new Scanner(req.getInputStream()); StringBuilder sb = new StringBuilder(); while(scanner.hasNextLine()) { sb.append(scanner.nextLine()); } System.out.println("sb = " + sb); broadcaster.broadcast("message",sb.toString()); } //http://cjihrig.com/blog/the-server-side-of-server-sent-events/ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { broadcaster.addListener(req); } }
public SseResource() { this.executorService = Executors.newSingleThreadExecutor(); this.broadcaster = new SseBroadcaster(); }
protected void deactivate() { broadcaster.remove(this); broadcaster = null; }
@Activate protected void activate() { broadcaster = new SseBroadcaster(); broadcaster.add(this); // The clean SSE subscriptions job sends an ALIVE event to all subscribers. This will trigger // an exception when the subscriber is dead, leading to the release of the SSE subscription // on server side. // In practice, the exception occurs only after the sending of a second ALIVE event. So this // will require two runs of the job to release an SSE subscription. // The clean SSE subscriptions job is run every 5 minutes. cleanSubscriptionsJob = scheduler.scheduleAtFixedRate(() -> { logger.debug("Run clean SSE subscriptions job"); if (subscriptions != null) { subscriptions.checkAliveClients(); } }, 1, 5, TimeUnit.MINUTES); }
public SseResource() { this.executorService = Executors.newSingleThreadExecutor(); this.broadcaster = new SseBroadcaster(); }
@Override public void onRelease(String subscriptionId) { logger.debug("SSE connection for subscription {} has been released.", subscriptionId); EventOutput eventOutput = eventOutputs.remove(subscriptionId); if (eventOutput != null) { broadcaster.remove(eventOutput); } }
@Path("process/{id}") @Produces(SseFeature.SERVER_SENT_EVENTS) @GET public EventOutput getProgress(@PathParam("id") int id, @DefaultValue("false") @QueryParam("testSource") boolean testSource) { final Process process = processes.get(id); if (process != null) { if (testSource) { process.release(); } final EventOutput eventOutput = new EventOutput(); process.getBroadcaster().add(eventOutput); return eventOutput; } else { throw new NotFoundException(); } }
@Override public void run() { broadcaster.broadcast(SseUtil.buildEvent(event)); } });
@Deactivate protected void deactivate() { if (cleanSubscriptionsJob != null && !cleanSubscriptionsJob.isCancelled()) { logger.debug("Cancel clean SSE subscriptions job"); cleanSubscriptionsJob.cancel(true); cleanSubscriptionsJob = null; } broadcaster.remove(this); broadcaster = null; }
@GET @Path("/events.stream") @Produces(SseFeature.SERVER_SENT_EVENTS) @ApiOperation(value = "Get Event Stream of Application Events", notes = "Returns a continuous stream of application events using Server-Sent Events.") public EventOutput errors() { final EventOutput eventOutput = new EventOutput(); BROADCASTER.add(eventOutput); return eventOutput; }
@Override public void run() { broadcaster.broadcast(SseUtil.buildEvent(event)); } });
@Override public void onClose(ChunkedOutput<OutboundEvent> event) { if (event instanceof SitemapEventOutput) { SitemapEventOutput sitemapEvent = (SitemapEventOutput) event; logger.debug("SSE connection for subscription {} has been closed.", sitemapEvent.getSubscriptionId()); subscriptions.removeSubscription(sitemapEvent.getSubscriptionId()); EventOutput eventOutput = eventOutputs.remove(sitemapEvent.getSubscriptionId()); if (eventOutput != null) { broadcaster.remove(eventOutput); } } }
@Override public <OUT extends ChunkedOutput<OutboundEvent>> boolean add(OUT chunkedOutput) { outputs.put((TerracottaEventOutput) chunkedOutput, new TerracottaEventOutputFlushingMetadata()); return super.add(chunkedOutput); }
@Override public void update(Observable o, Object arg) { if (o instanceof StreamBroadcaster && arg != null) { EventEnvelope e = (EventEnvelope) arg; OutboundEvent.Builder eventBuilder = new OutboundEvent.Builder(); OutboundEvent event = eventBuilder .mediaType(MediaType.APPLICATION_JSON_TYPE) .id(e.eventId.orElse(null)) .name(e.eventType) .data(e.eventData) .build(); BROADCASTER.broadcast(event); } } }
/** * Creates a subscription for the stream of sitemap events. * * @return a subscription id */ @POST @Path(SEGMENT_EVENTS + "/subscribe") @ApiOperation(value = "Creates a sitemap event subscription.") @ApiResponses(value = { @ApiResponse(code = 201, message = "Subscription created.") }) public Object createEventSubscription() { String subscriptionId = subscriptions.createSubscription(this); final EventOutput eventOutput = new SitemapEventOutput(subscriptions, subscriptionId); broadcaster.add(eventOutput); eventOutputs.put(subscriptionId, eventOutput); URI uri = uriInfo.getBaseUriBuilder().path(PATH_SITEMAPS).path(SEGMENT_EVENTS).path(subscriptionId).build(); return Response.created(uri); }