org.springframework.http.codec.ServerSentEvent Java Examples

The following examples show how to use org.springframework.http.codec.ServerSentEvent. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: SseHandlerFunctionIntegrationTests.java    From spring-analysis-note with MIT License 6 votes vote down vote up
@Test
public void sseAsEvent() {
	Flux<ServerSentEvent<String>> result = this.webClient.get()
			.uri("/event")
			.accept(TEXT_EVENT_STREAM)
			.retrieve()
			.bodyToFlux(new ParameterizedTypeReference<ServerSentEvent<String>>() {});

	StepVerifier.create(result)
			.consumeNextWith( event -> {
				assertEquals("0", event.id());
				assertEquals("foo", event.data());
				assertEquals("bar", event.comment());
				assertNull(event.event());
				assertNull(event.retry());
			})
			.consumeNextWith( event -> {
				assertEquals("1", event.id());
				assertEquals("foo", event.data());
				assertEquals("bar", event.comment());
				assertNull(event.event());
				assertNull(event.retry());
			})
			.expectComplete()
			.verify(Duration.ofSeconds(5L));
}
 
Example #2
Source File: SseHandlerFunctionIntegrationTests.java    From java-technology-stack with MIT License 6 votes vote down vote up
@Test
public void sseAsEvent() {
	Flux<ServerSentEvent<String>> result = this.webClient.get()
			.uri("/event")
			.accept(TEXT_EVENT_STREAM)
			.retrieve()
			.bodyToFlux(new ParameterizedTypeReference<ServerSentEvent<String>>() {});

	StepVerifier.create(result)
			.consumeNextWith( event -> {
				assertEquals("0", event.id());
				assertEquals("foo", event.data());
				assertEquals("bar", event.comment());
				assertNull(event.event());
				assertNull(event.retry());
			})
			.consumeNextWith( event -> {
				assertEquals("1", event.id());
				assertEquals("foo", event.data());
				assertEquals("bar", event.comment());
				assertNull(event.event());
				assertNull(event.retry());
			})
			.expectComplete()
			.verify(Duration.ofSeconds(5L));
}
 
Example #3
Source File: HelloFluxApplicationTests.java    From Spring5Tutorial with GNU Lesser General Public License v3.0 6 votes vote down vote up
@Test
public void serverSentEvent() {
	 Flux<Long> numbers = 
	     WebClient.create("http://localhost:8080")
	              .get()
	              .uri("/randomNumber")
	              .accept(MediaType.TEXT_EVENT_STREAM)
	              .retrieve()
	              .bodyToFlux(new ParameterizedTypeReference<ServerSentEvent<String>>() {})
	              .map(event -> Long.parseLong(event.data()));

    StepVerifier.create(numbers)
                .expectNextCount(5)
                .expectComplete()
                .verify();
}
 
Example #4
Source File: ServerSentController.java    From Hands-On-Reactive-Programming-in-Spring-5 with MIT License 6 votes vote down vote up
@GetMapping("/sse/stocks")
public Flux<ServerSentEvent<?>> streamStocks() {
    return Flux
        .fromIterable(stringStocksServiceMap.values())
        .flatMap(StocksService::stream)
        .<ServerSentEvent<?>>map(item ->
            ServerSentEvent
                .builder(item)
                .event("StockItem")
                .id(item.getId())
                .build()
        )
        .startWith(
            ServerSentEvent
                .builder()
                .event("Stocks")
                .data(stringStocksServiceMap.keySet())
                .build()
        );
}
 
Example #5
Source File: SseIntegrationTests.java    From java-technology-stack with MIT License 6 votes vote down vote up
private void verifyPersonEvents(Flux<ServerSentEvent<Person>> result) {
	StepVerifier.create(result)
			.consumeNextWith( event -> {
				assertEquals("0", event.id());
				assertEquals(new Person("foo 0"), event.data());
				assertEquals("bar 0", event.comment());
				assertNull(event.event());
				assertNull(event.retry());
			})
			.consumeNextWith( event -> {
				assertEquals("1", event.id());
				assertEquals(new Person("foo 1"), event.data());
				assertEquals("bar 1", event.comment());
				assertNull(event.event());
				assertNull(event.retry());
			})
			.thenCancel()
			.verify(Duration.ofSeconds(5L));
}
 
Example #6
Source File: ViewController.java    From service-block-samples with Apache License 2.0 6 votes vote down vote up
@GetMapping(value = "/projects/{projectId}/tightCouplingEvents", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<ServerSentEvent<TightCouplingEvent>> streamTightCouplingEvents(@PathVariable Long projectId,
                                                                           HttpServletRequest request) {
    // Stream the events from MongoDB
    Flux<TightCouplingEvent> events = eventRepository.findByProjectId(projectId);

    // Check if this is an SSE reconnection from a client
    String lastEventId = request.getHeader("Last-Event-Id");

    // On SSE client reconnect, skip ahead in the stream to play back only new events
    if (lastEventId != null)
        events = events.skipUntil(e -> e.getId().equals(lastEventId)).skip(1);

    // Subscribe to the tailing events from the reactive repository query
    return events.map(s -> ServerSentEvent.builder(s)
            .event(s.getCreatedDate().toString())
            .id(s.getId())
            .build())
            .delayElements(Duration.ofMillis(100));
}
 
Example #7
Source File: ReactiveTypeHandlerTests.java    From spring-analysis-note with MIT License 6 votes vote down vote up
@Test
public void writeServerSentEventsWithBuilder() throws Exception {

	ResolvableType type = ResolvableType.forClassWithGenerics(ServerSentEvent.class, String.class);

	EmitterProcessor<ServerSentEvent<?>> processor = EmitterProcessor.create();
	SseEmitter sseEmitter = (SseEmitter) handleValue(processor, Flux.class, type);

	EmitterHandler emitterHandler = new EmitterHandler();
	sseEmitter.initialize(emitterHandler);

	processor.onNext(ServerSentEvent.builder("foo").id("1").build());
	processor.onNext(ServerSentEvent.builder("bar").id("2").build());
	processor.onNext(ServerSentEvent.builder("baz").id("3").build());
	processor.onComplete();

	assertEquals("id:1\ndata:foo\n\nid:2\ndata:bar\n\nid:3\ndata:baz\n\n",
			emitterHandler.getValuesAsText());
}
 
Example #8
Source File: SseIntegrationTests.java    From spring-cloud-gateway with Apache License 2.0 6 votes vote down vote up
@Test
@SuppressWarnings("Duplicates")
public void sseAsEvent() {
	ResolvableType type = forClassWithGenerics(ServerSentEvent.class, String.class);
	Flux<ServerSentEvent<String>> result = this.webClient.get().uri("/event")
			.accept(TEXT_EVENT_STREAM).exchange()
			.flatMapMany(response -> response.body(
					toFlux(new ParameterizedTypeReference<ServerSentEvent<String>>() {
					})));

	StepVerifier.create(result).consumeNextWith(event -> {
		assertThat(event.id()).isEqualTo("0");
		assertThat(event.data()).isEqualTo("foo");
		assertThat(event.comment()).isEqualTo("bar");
		assertThat(event.event()).isNull();
		assertThat(event.retry()).isNull();
	}).consumeNextWith(event -> {
		assertThat(event.id()).isEqualTo("1");
		assertThat(event.data()).isEqualTo("foo");
		assertThat(event.comment()).isEqualTo("bar");
		assertThat(event.event()).isNull();
		assertThat(event.retry()).isNull();
	}).thenCancel().verify(Duration.ofSeconds(5L));
}
 
Example #9
Source File: SseIntegrationTests.java    From spring-cloud-gateway with Apache License 2.0 6 votes vote down vote up
@Test
@SuppressWarnings("Duplicates")
public void sseAsEventWithoutAcceptHeader() {
	Flux<ServerSentEvent<String>> result = this.webClient.get().uri("/event")
			.accept(TEXT_EVENT_STREAM).exchange()
			.flatMapMany(response -> response.body(
					toFlux(new ParameterizedTypeReference<ServerSentEvent<String>>() {
					})));

	StepVerifier.create(result).consumeNextWith(event -> {
		assertThat(event.id()).isEqualTo("0");
		assertThat(event.data()).isEqualTo("foo");
		assertThat(event.comment()).isEqualTo("bar");
		assertThat(event.event()).isNull();
		assertThat(event.retry()).isNull();
	}).consumeNextWith(event -> {
		assertThat(event.id()).isEqualTo("1");
		assertThat(event.data()).isEqualTo("foo");
		assertThat(event.comment()).isEqualTo("bar");
		assertThat(event.event()).isNull();
		assertThat(event.retry()).isNull();
	}).thenCancel().verify(Duration.ofSeconds(5L));
}
 
Example #10
Source File: SseIntegrationTests.java    From spring-analysis-note with MIT License 6 votes vote down vote up
private void verifyPersonEvents(Flux<ServerSentEvent<Person>> result) {
	StepVerifier.create(result)
			.consumeNextWith( event -> {
				assertEquals("0", event.id());
				assertEquals(new Person("foo 0"), event.data());
				assertEquals("bar 0", event.comment());
				assertNull(event.event());
				assertNull(event.retry());
			})
			.consumeNextWith( event -> {
				assertEquals("1", event.id());
				assertEquals(new Person("foo 1"), event.data());
				assertEquals("bar 1", event.comment());
				assertNull(event.event());
				assertNull(event.retry());
			})
			.thenCancel()
			.verify(Duration.ofSeconds(5L));
}
 
Example #11
Source File: ReactiveTypeHandlerTests.java    From java-technology-stack with MIT License 6 votes vote down vote up
@Test
public void writeServerSentEventsWithBuilder() throws Exception {

	ResolvableType type = ResolvableType.forClassWithGenerics(ServerSentEvent.class, String.class);

	EmitterProcessor<ServerSentEvent<?>> processor = EmitterProcessor.create();
	SseEmitter sseEmitter = (SseEmitter) handleValue(processor, Flux.class, type);

	EmitterHandler emitterHandler = new EmitterHandler();
	sseEmitter.initialize(emitterHandler);

	processor.onNext(ServerSentEvent.builder("foo").id("1").build());
	processor.onNext(ServerSentEvent.builder("bar").id("2").build());
	processor.onNext(ServerSentEvent.builder("baz").id("3").build());
	processor.onComplete();

	assertEquals("id:1\ndata:foo\n\nid:2\ndata:bar\n\nid:3\ndata:baz\n\n",
			emitterHandler.getValuesAsText());
}
 
Example #12
Source File: Jackson2JsonEncoderTests.java    From java-technology-stack with MIT License 5 votes vote down vote up
@Test
public void canNotEncode() {
	assertFalse(this.encoder.canEncode(ResolvableType.forClass(String.class), null));
	assertFalse(this.encoder.canEncode(ResolvableType.forClass(Pojo.class), APPLICATION_XML));

	ResolvableType sseType = ResolvableType.forClass(ServerSentEvent.class);
	assertFalse(this.encoder.canEncode(sseType, APPLICATION_JSON));
}
 
Example #13
Source File: Jackson2SmileEncoderTests.java    From java-technology-stack with MIT License 5 votes vote down vote up
@Test
public void canNotEncode() {
	assertFalse(this.encoder.canEncode(ResolvableType.forClass(String.class), null));
	assertFalse(this.encoder.canEncode(ResolvableType.forClass(Pojo.class), APPLICATION_XML));

	ResolvableType sseType = ResolvableType.forClass(ServerSentEvent.class);
	assertFalse(this.encoder.canEncode(sseType, SMILE_MIME_TYPE));
}
 
Example #14
Source File: HttpIT.java    From vertx-spring-boot with Apache License 2.0 5 votes vote down vote up
@GetMapping
public Flux<ServerSentEvent<String>> sse() {
    return Flux.just("first", "second", "third")
        .map(s -> ServerSentEvent.<String>builder()
            .data(s)
            .build());
}
 
Example #15
Source File: QueryController.java    From ESarch with Apache License 2.0 5 votes vote down vote up
@GetMapping("/subscribe/order-book/{orderBookId}")
public Flux<ServerSentEvent<OrderBookView>> subscribeToOrderBook(@PathVariable String orderBookId) {
    SubscriptionQueryResult<OrderBookView, OrderBookView> subscription = queryGateway
            .subscriptionQuery(new OrderBookByIdQuery(new OrderBookId(orderBookId)),
                               ResponseTypes.instanceOf(OrderBookView.class),
                               ResponseTypes.instanceOf(OrderBookView.class));
    return subscription.initialResult().concatWith(subscription.updates())
                       .map(ob -> ServerSentEvent.builder(ob).build());
}
 
Example #16
Source File: InstancesController.java    From Moss with Apache License 2.0 5 votes vote down vote up
@GetMapping(path = "/instances/{id}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<ServerSentEvent<Instance>> instanceStream(@PathVariable String id) {
    return Flux.from(eventStore)
               .filter(event -> event.getInstance().equals(InstanceId.of(id)))
               .flatMap(event -> registry.getInstance(event.getInstance()))
               .map(event -> ServerSentEvent.builder(event).build())
               .mergeWith(ping());
}
 
Example #17
Source File: ServerController.java    From tutorials with MIT License 5 votes vote down vote up
@GetMapping("/stream-sse")
public Flux<ServerSentEvent<String>> streamEvents() {
    return Flux.interval(Duration.ofSeconds(1))
        .map(sequence -> ServerSentEvent.<String> builder()
            .id(String.valueOf(sequence))
            .event("periodic-event")
            .data("SSE - " + LocalTime.now()
                .toString())
            .build());
}
 
Example #18
Source File: Jackson2JsonEncoderTests.java    From spring-analysis-note with MIT License 5 votes vote down vote up
@Test
public void canNotEncode() {
	assertFalse(this.encoder.canEncode(ResolvableType.forClass(String.class), null));
	assertFalse(this.encoder.canEncode(ResolvableType.forClass(Pojo.class), APPLICATION_XML));

	ResolvableType sseType = ResolvableType.forClass(ServerSentEvent.class);
	assertFalse(this.encoder.canEncode(sseType, APPLICATION_JSON));
}
 
Example #19
Source File: EmojiController.java    From reactor-workshop with GNU General Public License v3.0 5 votes vote down vote up
@GetMapping(value = "/emojis/raw", produces = TEXT_EVENT_STREAM_VALUE)
Flux<ServerSentEvent> raw() {
    return webClient
            .get()
            .uri(emojiTrackerUrl)
            .retrieve()
            .bodyToFlux(ServerSentEvent.class);
}
 
Example #20
Source File: HelloFluxApplication.java    From Spring5Tutorial with GNU Lesser General Public License v3.0 5 votes vote down vote up
@GetMapping("/randomNumber")
@ResponseBody
   public Flux<ServerSentEvent<Long>> randomNumbers() {
	return Flux.interval(Duration.ofSeconds(1))
			   .map(tick -> Tuples.of(tick, ThreadLocalRandom.current().nextLong()))
			   .map(this::randomNumberEvent)
			   .take(5);
}
 
Example #21
Source File: HelloFluxApplication.java    From Spring5Tutorial with GNU Lesser General Public License v3.0 5 votes vote down vote up
public ServerSentEvent<Long> randomNumberEvent(Tuple2<Long, Long> data) {
	return ServerSentEvent.<Long>builder()
					      .event("randomNumber")
					      .id(Long.toString(data.getT1()))
					      .data(data.getT2())
					      .build();
}
 
Example #22
Source File: FluxSinkApplication.java    From spring-5-examples with MIT License 5 votes vote down vote up
@Bean
Flux<ServerSentEvent<Map>> processor(final List<FluxSink<ServerSentEvent<Map>>> subscribers) {
  return Flux.create(
      fluxSink -> subscribers.add(
          fluxSink.onCancel(() -> subscribers.remove(fluxSink))
                  .onDispose(() -> log.debug("disposing..."))
                  .onRequest(i -> log.debug("{} subscribers on request", subscribers.size()))));
}
 
Example #23
Source File: FluxSinkApplication.java    From spring-5-examples with MIT License 5 votes vote down vote up
@Bean
Consumer<String> distributeEvent(final List<FluxSink<ServerSentEvent<Map>>> subscribers) {
  return message -> subscribers.forEach(fluxSink -> fluxSink.next(ServerSentEvent.<Map>builder()
                                                                      .id(UUID.randomUUID().toString())
                                                                      .data(singletonMap("payload", message))
                                                                      //.data(HashMap.of(
                                                                      //    "payload", message,
                                                                      //    "at", Instant.now()
                                                                      //).toJavaMap())
                                                                      .event("message")
                                                                      .build()));
}
 
Example #24
Source File: FluxSinkApplication.java    From spring-5-examples with MIT License 5 votes vote down vote up
@Bean
ApplicationRunner handler(final Flux<ServerSentEvent<Map>> processor,
                          final Consumer<ServerSentEvent<Map>> onNextConsumer,
                          final Consumer<Throwable> onErrorConsumer,
                          final Runnable completeConsumer) {

  return args -> processor.subscribe(
      onNextConsumer,
      onErrorConsumer,
      completeConsumer
  );
}
 
Example #25
Source File: FluxSinkApplication.java    From spring-5-examples with MIT License 5 votes vote down vote up
@Bean
RouterFunction<ServerResponse> routes(final Flux<ServerSentEvent<Map>> processor,
                                      final Consumer<String> distributeEvent) {

  final ParameterizedTypeReference<Map<String, String>> type
      = new ParameterizedTypeReference<Map<String, String>>() {};

  return

      route(GET("/**"),
            request -> ok().contentType(request.headers().accept().contains(TEXT_EVENT_STREAM)
                                            ? TEXT_EVENT_STREAM : APPLICATION_STREAM_JSON)
                           .body(processor.map(s -> s), ServerSentEvent.class))

          .andRoute(POST("/**"),
                    request -> accepted().body(request.bodyToMono(type)
                                                      .map(map -> map.getOrDefault("message", ""))
                                                      .map(String::valueOf)
                                                      .map(String::trim)
                                                      .filter(s -> s.length() > 0)
                                                      .doOnNext(distributeEvent)
                                                      .map(m -> format("message '%s' accepted.", m))
                                                      .map(message -> singletonMap("response", message))
                                                      .subscribeOn(Schedulers.elastic())
                                                      .flatMap(Mono::just), Map.class))
      ;
}
 
Example #26
Source File: SSEController.java    From tools-journey with Apache License 2.0 5 votes vote down vote up
@GetMapping("/randomNumbers")
public Flux<ServerSentEvent<Integer>> randomNumbers() {
    return Flux.interval(Duration.ofSeconds(1))
            .map(seq -> Tuples.of(seq, ThreadLocalRandom.current().nextInt()))
            .map(data -> ServerSentEvent.<Integer>builder()
                    .event("random")
                    .id(Long.toString(data.getT1()))
                    .data(data.getT2())
                    .build()
            );
}
 
Example #27
Source File: SseController.java    From spring-reactive-playground with Apache License 2.0 5 votes vote down vote up
@GetMapping("/sse/event")
Flux<ServerSentEvent<String>> event() {
	return Flux
		.interval(Duration.ofSeconds(1))
		.map(l -> ServerSentEvent
				.builder("foo\nbar")
				.comment("bar\nbaz")
				.id(Long.toString(l))
				.build());
}
 
Example #28
Source File: ClientController.java    From tutorials with MIT License 5 votes vote down vote up
@Async
public void consumeSSE() {
    ParameterizedTypeReference<ServerSentEvent<String>> type = new ParameterizedTypeReference<ServerSentEvent<String>>() {
    };

    Flux<ServerSentEvent<String>> eventStream = client.get()
        .uri("/stream-sse")
        .retrieve()
        .bodyToFlux(type);

    eventStream.subscribe(content -> logger.info("Current time: {} - Received SSE: name[{}], id [{}], content[{}] ", LocalTime.now(), content.event(), content.id(), content.data()), error -> logger.error("Error receiving SSE: {}", error),
        () -> logger.info("Completed!!!"));
}
 
Example #29
Source File: ClientController.java    From tutorials with MIT License 5 votes vote down vote up
@Async
public void consumeSSEFromFluxEndpoint() {
    ParameterizedTypeReference<ServerSentEvent<String>> type = new ParameterizedTypeReference<ServerSentEvent<String>>() {
    };

    Flux<ServerSentEvent<String>> eventStream = client.get()
        .uri("/stream-flux")
        .accept(MediaType.TEXT_EVENT_STREAM)
        .retrieve()
        .bodyToFlux(type);

    eventStream.subscribe(content -> logger.info("Current time: {} - Received SSE: name[{}], id [{}], content[{}] ", LocalTime.now(), content.event(), content.id(), content.data()), error -> logger.error("Error receiving SSE: {}", error),
        () -> logger.info("Completed!!!"));
}
 
Example #30
Source File: BodyInserters.java    From spring-analysis-note with MIT License 5 votes vote down vote up
/**
 * Inserter to write the given {@code ServerSentEvent} publisher.
 * <p>Alternatively, you can provide event data objects via
 * {@link #fromPublisher(Publisher, Class)}, and set the "Content-Type" to
 * {@link MediaType#TEXT_EVENT_STREAM text/event-stream}.
 * @param eventsPublisher the {@code ServerSentEvent} publisher to write to the response body
 * @param <T> the type of the data elements in the {@link ServerSentEvent}
 * @return the inserter to write a {@code ServerSentEvent} publisher
 * @see <a href="https://www.w3.org/TR/eventsource/">Server-Sent Events W3C recommendation</a>
 */
// Parameterized for server-side use
public static <T, S extends Publisher<ServerSentEvent<T>>> BodyInserter<S, ServerHttpResponse> fromServerSentEvents(
		S eventsPublisher) {

	Assert.notNull(eventsPublisher, "Publisher must not be null");
	return (serverResponse, context) -> {
		ResolvableType elementType = SSE_TYPE;
		MediaType mediaType = MediaType.TEXT_EVENT_STREAM;
		HttpMessageWriter<ServerSentEvent<T>> writer = findWriter(context, elementType, mediaType);
		return write(eventsPublisher, elementType, mediaType, serverResponse, context, writer);
	};
}