@Override public ServerSentEvent<T> build() { return new ServerSentEvent<>(this.id, this.event, this.retry, this.comment, this.data); } }
private SseEmitter.SseEventBuilder adapt(ServerSentEvent<?> sse) { SseEmitter.SseEventBuilder builder = SseEmitter.event(); String id = sse.id(); String event = sse.event(); Duration retry = sse.retry(); String comment = sse.comment(); Object data = sse.data(); if (id != null) { builder.id(id); } if (event != null) { builder.name(event); } if (data != null) { builder.data(data); } if (retry != null) { builder.reconnectTime(retry.toMillis()); } if (comment != null) { builder.comment(comment); } return builder; } }
private Mono<?> buildEvent(List<String> lines, ResolvableType valueType, boolean shouldWrap, Map<String, Object> hints) { ServerSentEvent.Builder<Object> sseBuilder = shouldWrap ? ServerSentEvent.builder() : null; StringBuilder data = null; StringBuilder comment = null;
@GetMapping(path = "/instances/events", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public Flux<ServerSentEvent<InstanceEvent>> eventStream() { return Flux.from(eventStore).map(event -> ServerSentEvent.builder(event).build()).mergeWith(ping()); }
private Mono<?> buildEvent(List<String> lines, ResolvableType valueType, boolean shouldWrap, Map<String, Object> hints) { ServerSentEvent.Builder<Object> sseBuilder = shouldWrap ? ServerSentEvent.builder() : null; StringBuilder data = null; StringBuilder comment = null;
@Override public ServerSentEvent<T> build() { return new ServerSentEvent<>(this.id, this.event, this.retry, this.comment, this.data); } }
private SseEmitter.SseEventBuilder adapt(ServerSentEvent<?> sse) { SseEmitter.SseEventBuilder builder = SseEmitter.event(); String id = sse.id(); String event = sse.event(); Duration retry = sse.retry(); String comment = sse.comment(); Object data = sse.data(); if (id != null) { builder.id(id); } if (event != null) { builder.name(event); } if (data != null) { builder.data(data); } if (retry != null) { builder.reconnectTime(retry.toMillis()); } if (comment != null) { builder.comment(comment); } return builder; } }
@GetMapping("/event") Flux<ServerSentEvent<Person>> sse() { return INTERVAL.take(2).map(l -> ServerSentEvent.builder(new Person("foo " + l)) .id(Long.toString(l)) .comment("bar " + l) .build()); }
@Override public ServerSentEvent<T> build() { return new ServerSentEvent<>(this.id, this.event, this.retry, this.comment, this.data); } }
@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()); }
@Override public ServerSentEvent<T> build() { return new ServerSentEvent<>(this.id, this.event, this.retry, this.comment, this.data); } }
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)); }
@GetMapping(path = "/applications", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public Flux<ServerSentEvent<Application>> applicationsStream() { return Flux.from(eventPublisher) .flatMap(event -> registry.getInstance(event.getInstance())) .map(this::getApplicationForInstance) .flatMap(group -> toApplication(group.getT1(), group.getT2())) .map(application -> ServerSentEvent.builder(application).build()) .mergeWith(ping()); }
@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)); }
@RequestMapping("/sse/event") Flux<ServerSentEvent<String>> sse() { return INTERVAL.map(l -> ServerSentEvent.builder("foo") .id(Long.toString(l)) .comment("bar") .build()); }
@Test public void readServerSentEvents() { MockServerHttpRequest request = MockServerHttpRequest.post("/") .body(Mono.just(stringBuffer( "id:c42\nevent:foo\nretry:123\n:bla\n:bla bla\n:bla bla bla\ndata:bar\n\n" + "id:c43\nevent:bar\nretry:456\ndata:baz\n\n"))); Flux<ServerSentEvent> events = this.messageReader .read(ResolvableType.forClassWithGenerics(ServerSentEvent.class, String.class), request, Collections.emptyMap()).cast(ServerSentEvent.class); StepVerifier.create(events) .consumeNextWith(event -> { assertEquals("c42", event.id()); assertEquals("foo", event.event()); assertEquals(Duration.ofMillis(123), event.retry()); assertEquals("bla\nbla bla\nbla bla bla", event.comment()); assertEquals("bar", event.data()); }) .consumeNextWith(event -> { assertEquals("c43", event.id()); assertEquals("bar", event.event()); assertEquals(Duration.ofMillis(456), event.retry()); assertNull(event.comment()); assertEquals("baz", event.data()); }) .expectComplete() .verify(); }
Mono<ServerResponse> sse(ServerRequest request) { Flux<ServerSentEvent<String>> body = INTERVAL .map(aLong -> ServerSentEvent.builder("foo").id("" + aLong).comment("bar").build()); return ServerResponse.ok().body(fromServerSentEvents(body)); } }
@Test public void readServerSentEventsWithMultipleChunks() { MockServerHttpRequest request = MockServerHttpRequest.post("/") .body(Flux.just( stringBuffer("id:c42\nev"), stringBuffer("ent:foo\nretry:123\n:bla\n:bla bla\n:bla bla bla\ndata:"), stringBuffer("bar\n\nid:c43\nevent:bar\nretry:456\ndata:baz\n\n"))); Flux<ServerSentEvent> events = messageReader .read(ResolvableType.forClassWithGenerics(ServerSentEvent.class, String.class), request, Collections.emptyMap()).cast(ServerSentEvent.class); StepVerifier.create(events) .consumeNextWith(event -> { assertEquals("c42", event.id()); assertEquals("foo", event.event()); assertEquals(Duration.ofMillis(123), event.retry()); assertEquals("bla\nbla bla\nbla bla bla", event.comment()); assertEquals("bar", event.data()); }) .consumeNextWith(event -> { assertEquals("c43", event.id()); assertEquals("bar", event.event()); assertEquals(Duration.ofMillis(456), event.retry()); assertNull(event.comment()); assertEquals("baz", event.data()); }) .expectComplete() .verify(); }