Creating Text Stream Using Spring WebFlux











up vote
0
down vote

favorite












I've been using Spring WebFlux to create a text stream, here is the code.



@SpringBootApplication
@RestController
public class ReactiveServer {

private static final String FILE_PATH = "c:/test/";


@GetMapping(produces = MediaType.TEXT_EVENT_STREAM_VALUE, value = "/events")
Flux<String> events() {

Flux<String> eventFlux = Flux.fromStream(Stream.generate(() -> FileReader.readFile()));

Flux<Long> durationFlux = Flux.interval(Duration.ofMillis(500));

return Flux.zip(eventFlux, durationFlux).map(Tuple2::getT1);

}

public static void main(String args) {

SpringApplication.run(ReactiveServer.class, args);

}

}


When I access the /events url on the browser I get this, that's almost what I want to get:



data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379993662,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":0,"rollingCountBadRequests":0}



data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379994203,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":2,"rollingCountBadRequests":0}



data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379994706,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":2,"rollingCountBadRequests":0}



data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379995213,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":3,"rollingCountBadRequests":0}



What I need to do is to insert a "ping:" in between iterations to get:



ping:



data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379993662,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":0,"rollingCountBadRequests":0}



data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379994203,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":2,"rollingCountBadRequests":0}



ping:



data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379994706,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":2,"rollingCountBadRequests":0}



data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379995213,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":3,"rollingCountBadRequests":0}



But, the best I could get was:



data: ping:



data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379993662,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":0,"rollingCountBadRequests":0}



data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379994203,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":2,"rollingCountBadRequests":0}



data: ping:



data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379994706,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":2,"rollingCountBadRequests":0}



data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379995213,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":3,"rollingCountBadRequests":0}



Does anyone know of a way to what I need?










share|improve this question




























    up vote
    0
    down vote

    favorite












    I've been using Spring WebFlux to create a text stream, here is the code.



    @SpringBootApplication
    @RestController
    public class ReactiveServer {

    private static final String FILE_PATH = "c:/test/";


    @GetMapping(produces = MediaType.TEXT_EVENT_STREAM_VALUE, value = "/events")
    Flux<String> events() {

    Flux<String> eventFlux = Flux.fromStream(Stream.generate(() -> FileReader.readFile()));

    Flux<Long> durationFlux = Flux.interval(Duration.ofMillis(500));

    return Flux.zip(eventFlux, durationFlux).map(Tuple2::getT1);

    }

    public static void main(String args) {

    SpringApplication.run(ReactiveServer.class, args);

    }

    }


    When I access the /events url on the browser I get this, that's almost what I want to get:



    data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379993662,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":0,"rollingCountBadRequests":0}



    data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379994203,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":2,"rollingCountBadRequests":0}



    data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379994706,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":2,"rollingCountBadRequests":0}



    data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379995213,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":3,"rollingCountBadRequests":0}



    What I need to do is to insert a "ping:" in between iterations to get:



    ping:



    data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379993662,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":0,"rollingCountBadRequests":0}



    data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379994203,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":2,"rollingCountBadRequests":0}



    ping:



    data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379994706,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":2,"rollingCountBadRequests":0}



    data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379995213,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":3,"rollingCountBadRequests":0}



    But, the best I could get was:



    data: ping:



    data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379993662,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":0,"rollingCountBadRequests":0}



    data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379994203,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":2,"rollingCountBadRequests":0}



    data: ping:



    data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379994706,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":2,"rollingCountBadRequests":0}



    data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379995213,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":3,"rollingCountBadRequests":0}



    Does anyone know of a way to what I need?










    share|improve this question


























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      I've been using Spring WebFlux to create a text stream, here is the code.



      @SpringBootApplication
      @RestController
      public class ReactiveServer {

      private static final String FILE_PATH = "c:/test/";


      @GetMapping(produces = MediaType.TEXT_EVENT_STREAM_VALUE, value = "/events")
      Flux<String> events() {

      Flux<String> eventFlux = Flux.fromStream(Stream.generate(() -> FileReader.readFile()));

      Flux<Long> durationFlux = Flux.interval(Duration.ofMillis(500));

      return Flux.zip(eventFlux, durationFlux).map(Tuple2::getT1);

      }

      public static void main(String args) {

      SpringApplication.run(ReactiveServer.class, args);

      }

      }


      When I access the /events url on the browser I get this, that's almost what I want to get:



      data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379993662,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":0,"rollingCountBadRequests":0}



      data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379994203,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":2,"rollingCountBadRequests":0}



      data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379994706,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":2,"rollingCountBadRequests":0}



      data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379995213,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":3,"rollingCountBadRequests":0}



      What I need to do is to insert a "ping:" in between iterations to get:



      ping:



      data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379993662,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":0,"rollingCountBadRequests":0}



      data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379994203,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":2,"rollingCountBadRequests":0}



      ping:



      data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379994706,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":2,"rollingCountBadRequests":0}



      data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379995213,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":3,"rollingCountBadRequests":0}



      But, the best I could get was:



      data: ping:



      data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379993662,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":0,"rollingCountBadRequests":0}



      data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379994203,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":2,"rollingCountBadRequests":0}



      data: ping:



      data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379994706,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":2,"rollingCountBadRequests":0}



      data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379995213,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":3,"rollingCountBadRequests":0}



      Does anyone know of a way to what I need?










      share|improve this question















      I've been using Spring WebFlux to create a text stream, here is the code.



      @SpringBootApplication
      @RestController
      public class ReactiveServer {

      private static final String FILE_PATH = "c:/test/";


      @GetMapping(produces = MediaType.TEXT_EVENT_STREAM_VALUE, value = "/events")
      Flux<String> events() {

      Flux<String> eventFlux = Flux.fromStream(Stream.generate(() -> FileReader.readFile()));

      Flux<Long> durationFlux = Flux.interval(Duration.ofMillis(500));

      return Flux.zip(eventFlux, durationFlux).map(Tuple2::getT1);

      }

      public static void main(String args) {

      SpringApplication.run(ReactiveServer.class, args);

      }

      }


      When I access the /events url on the browser I get this, that's almost what I want to get:



      data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379993662,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":0,"rollingCountBadRequests":0}



      data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379994203,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":2,"rollingCountBadRequests":0}



      data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379994706,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":2,"rollingCountBadRequests":0}



      data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379995213,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":3,"rollingCountBadRequests":0}



      What I need to do is to insert a "ping:" in between iterations to get:



      ping:



      data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379993662,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":0,"rollingCountBadRequests":0}



      data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379994203,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":2,"rollingCountBadRequests":0}



      ping:



      data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379994706,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":2,"rollingCountBadRequests":0}



      data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379995213,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":3,"rollingCountBadRequests":0}



      But, the best I could get was:



      data: ping:



      data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379993662,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":0,"rollingCountBadRequests":0}



      data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379994203,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":2,"rollingCountBadRequests":0}



      data: ping:



      data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379994706,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":2,"rollingCountBadRequests":0}



      data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542379995213,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":3,"rollingCountBadRequests":0}



      Does anyone know of a way to what I need?







      java spring-boot spring-webflux






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited yesterday

























      asked Nov 16 at 15:29









      Nelson Larios

      286




      286
























          1 Answer
          1






          active

          oldest

          votes

















          up vote
          0
          down vote













          You could try returning a Flux<ServerSentEvent> and specify the type of event you're trying to send. Like this:



          @RestController
          public class TestController {

          @GetMapping(produces = MediaType.TEXT_EVENT_STREAM_VALUE, path = "/events")
          Flux<ServerSentEvent> events() {
          Flux<String> events = Flux.interval(Duration.ofMillis(200)).map(String::valueOf);
          Flux<ServerSentEvent<String>> sseData = events.map(event -> ServerSentEvent.builder(event).build());
          Flux<ServerSentEvent<String>> ping = Flux.interval(Duration.ofMillis(500))
          .map(l -> ServerSentEvent.builder("").event("ping").build());
          return Flux.merge(sseData, ping);
          }
          }


          With that code snippet, I'm getting the following output:



          $ http --stream :8080/events
          HTTP/1.1 200 OK
          Content-Type: text/event-stream;charset=UTF-8
          transfer-encoding: chunked

          data:0

          data:1

          event:ping
          data:

          data:2

          data:3

          data:4

          event:ping
          data:


          Which is consistent with Server Sent Events. Is the ping: prefix something specific to Hystrix? If it is, I don't think this is consistent with the SSE spec and that it's something supported in Spring Framework.






          share|improve this answer























          • HI, Brian, thanks for you answer. What I'm trying to do is to create a data stream in exactly the way the Hystrix Dashboard expects it to be. I think it uses the "ping:" String between events as a kind of separation. So your answer gives me something like: So what I really need is just to print that "ping:" at the beginning of an event. But without the "data:". Like this: ping: Not like this: data:ping:
            – Nelson Larios
            yesterday












          • that's what my sample is doing: sending SSE events of type data (the default) and ping. They're currently just interleaved and the ping events are scheduled with a specific duration between them.
            – Brian Clozel
            yesterday










          • When I run your code "ping:" doesn't print. I get this: data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542382826545} data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542382827046} data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542382827547} data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542382828049}
            – Nelson Larios
            yesterday












          • I've edited my answer
            – Brian Clozel
            yesterday










          • Hi Brian, it's specific to Hystrix. It's a shame I can't do it with WebFlux. I close to a solution using reactivex. Thank you very much for you efforts.
            – Nelson Larios
            19 hours ago











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














           

          draft saved


          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53340867%2fcreating-text-stream-using-spring-webflux%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          0
          down vote













          You could try returning a Flux<ServerSentEvent> and specify the type of event you're trying to send. Like this:



          @RestController
          public class TestController {

          @GetMapping(produces = MediaType.TEXT_EVENT_STREAM_VALUE, path = "/events")
          Flux<ServerSentEvent> events() {
          Flux<String> events = Flux.interval(Duration.ofMillis(200)).map(String::valueOf);
          Flux<ServerSentEvent<String>> sseData = events.map(event -> ServerSentEvent.builder(event).build());
          Flux<ServerSentEvent<String>> ping = Flux.interval(Duration.ofMillis(500))
          .map(l -> ServerSentEvent.builder("").event("ping").build());
          return Flux.merge(sseData, ping);
          }
          }


          With that code snippet, I'm getting the following output:



          $ http --stream :8080/events
          HTTP/1.1 200 OK
          Content-Type: text/event-stream;charset=UTF-8
          transfer-encoding: chunked

          data:0

          data:1

          event:ping
          data:

          data:2

          data:3

          data:4

          event:ping
          data:


          Which is consistent with Server Sent Events. Is the ping: prefix something specific to Hystrix? If it is, I don't think this is consistent with the SSE spec and that it's something supported in Spring Framework.






          share|improve this answer























          • HI, Brian, thanks for you answer. What I'm trying to do is to create a data stream in exactly the way the Hystrix Dashboard expects it to be. I think it uses the "ping:" String between events as a kind of separation. So your answer gives me something like: So what I really need is just to print that "ping:" at the beginning of an event. But without the "data:". Like this: ping: Not like this: data:ping:
            – Nelson Larios
            yesterday












          • that's what my sample is doing: sending SSE events of type data (the default) and ping. They're currently just interleaved and the ping events are scheduled with a specific duration between them.
            – Brian Clozel
            yesterday










          • When I run your code "ping:" doesn't print. I get this: data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542382826545} data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542382827046} data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542382827547} data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542382828049}
            – Nelson Larios
            yesterday












          • I've edited my answer
            – Brian Clozel
            yesterday










          • Hi Brian, it's specific to Hystrix. It's a shame I can't do it with WebFlux. I close to a solution using reactivex. Thank you very much for you efforts.
            – Nelson Larios
            19 hours ago















          up vote
          0
          down vote













          You could try returning a Flux<ServerSentEvent> and specify the type of event you're trying to send. Like this:



          @RestController
          public class TestController {

          @GetMapping(produces = MediaType.TEXT_EVENT_STREAM_VALUE, path = "/events")
          Flux<ServerSentEvent> events() {
          Flux<String> events = Flux.interval(Duration.ofMillis(200)).map(String::valueOf);
          Flux<ServerSentEvent<String>> sseData = events.map(event -> ServerSentEvent.builder(event).build());
          Flux<ServerSentEvent<String>> ping = Flux.interval(Duration.ofMillis(500))
          .map(l -> ServerSentEvent.builder("").event("ping").build());
          return Flux.merge(sseData, ping);
          }
          }


          With that code snippet, I'm getting the following output:



          $ http --stream :8080/events
          HTTP/1.1 200 OK
          Content-Type: text/event-stream;charset=UTF-8
          transfer-encoding: chunked

          data:0

          data:1

          event:ping
          data:

          data:2

          data:3

          data:4

          event:ping
          data:


          Which is consistent with Server Sent Events. Is the ping: prefix something specific to Hystrix? If it is, I don't think this is consistent with the SSE spec and that it's something supported in Spring Framework.






          share|improve this answer























          • HI, Brian, thanks for you answer. What I'm trying to do is to create a data stream in exactly the way the Hystrix Dashboard expects it to be. I think it uses the "ping:" String between events as a kind of separation. So your answer gives me something like: So what I really need is just to print that "ping:" at the beginning of an event. But without the "data:". Like this: ping: Not like this: data:ping:
            – Nelson Larios
            yesterday












          • that's what my sample is doing: sending SSE events of type data (the default) and ping. They're currently just interleaved and the ping events are scheduled with a specific duration between them.
            – Brian Clozel
            yesterday










          • When I run your code "ping:" doesn't print. I get this: data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542382826545} data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542382827046} data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542382827547} data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542382828049}
            – Nelson Larios
            yesterday












          • I've edited my answer
            – Brian Clozel
            yesterday










          • Hi Brian, it's specific to Hystrix. It's a shame I can't do it with WebFlux. I close to a solution using reactivex. Thank you very much for you efforts.
            – Nelson Larios
            19 hours ago













          up vote
          0
          down vote










          up vote
          0
          down vote









          You could try returning a Flux<ServerSentEvent> and specify the type of event you're trying to send. Like this:



          @RestController
          public class TestController {

          @GetMapping(produces = MediaType.TEXT_EVENT_STREAM_VALUE, path = "/events")
          Flux<ServerSentEvent> events() {
          Flux<String> events = Flux.interval(Duration.ofMillis(200)).map(String::valueOf);
          Flux<ServerSentEvent<String>> sseData = events.map(event -> ServerSentEvent.builder(event).build());
          Flux<ServerSentEvent<String>> ping = Flux.interval(Duration.ofMillis(500))
          .map(l -> ServerSentEvent.builder("").event("ping").build());
          return Flux.merge(sseData, ping);
          }
          }


          With that code snippet, I'm getting the following output:



          $ http --stream :8080/events
          HTTP/1.1 200 OK
          Content-Type: text/event-stream;charset=UTF-8
          transfer-encoding: chunked

          data:0

          data:1

          event:ping
          data:

          data:2

          data:3

          data:4

          event:ping
          data:


          Which is consistent with Server Sent Events. Is the ping: prefix something specific to Hystrix? If it is, I don't think this is consistent with the SSE spec and that it's something supported in Spring Framework.






          share|improve this answer














          You could try returning a Flux<ServerSentEvent> and specify the type of event you're trying to send. Like this:



          @RestController
          public class TestController {

          @GetMapping(produces = MediaType.TEXT_EVENT_STREAM_VALUE, path = "/events")
          Flux<ServerSentEvent> events() {
          Flux<String> events = Flux.interval(Duration.ofMillis(200)).map(String::valueOf);
          Flux<ServerSentEvent<String>> sseData = events.map(event -> ServerSentEvent.builder(event).build());
          Flux<ServerSentEvent<String>> ping = Flux.interval(Duration.ofMillis(500))
          .map(l -> ServerSentEvent.builder("").event("ping").build());
          return Flux.merge(sseData, ping);
          }
          }


          With that code snippet, I'm getting the following output:



          $ http --stream :8080/events
          HTTP/1.1 200 OK
          Content-Type: text/event-stream;charset=UTF-8
          transfer-encoding: chunked

          data:0

          data:1

          event:ping
          data:

          data:2

          data:3

          data:4

          event:ping
          data:


          Which is consistent with Server Sent Events. Is the ping: prefix something specific to Hystrix? If it is, I don't think this is consistent with the SSE spec and that it's something supported in Spring Framework.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited yesterday

























          answered 2 days ago









          Brian Clozel

          28.9k67097




          28.9k67097












          • HI, Brian, thanks for you answer. What I'm trying to do is to create a data stream in exactly the way the Hystrix Dashboard expects it to be. I think it uses the "ping:" String between events as a kind of separation. So your answer gives me something like: So what I really need is just to print that "ping:" at the beginning of an event. But without the "data:". Like this: ping: Not like this: data:ping:
            – Nelson Larios
            yesterday












          • that's what my sample is doing: sending SSE events of type data (the default) and ping. They're currently just interleaved and the ping events are scheduled with a specific duration between them.
            – Brian Clozel
            yesterday










          • When I run your code "ping:" doesn't print. I get this: data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542382826545} data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542382827046} data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542382827547} data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542382828049}
            – Nelson Larios
            yesterday












          • I've edited my answer
            – Brian Clozel
            yesterday










          • Hi Brian, it's specific to Hystrix. It's a shame I can't do it with WebFlux. I close to a solution using reactivex. Thank you very much for you efforts.
            – Nelson Larios
            19 hours ago


















          • HI, Brian, thanks for you answer. What I'm trying to do is to create a data stream in exactly the way the Hystrix Dashboard expects it to be. I think it uses the "ping:" String between events as a kind of separation. So your answer gives me something like: So what I really need is just to print that "ping:" at the beginning of an event. But without the "data:". Like this: ping: Not like this: data:ping:
            – Nelson Larios
            yesterday












          • that's what my sample is doing: sending SSE events of type data (the default) and ping. They're currently just interleaved and the ping events are scheduled with a specific duration between them.
            – Brian Clozel
            yesterday










          • When I run your code "ping:" doesn't print. I get this: data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542382826545} data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542382827046} data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542382827547} data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542382828049}
            – Nelson Larios
            yesterday












          • I've edited my answer
            – Brian Clozel
            yesterday










          • Hi Brian, it's specific to Hystrix. It's a shame I can't do it with WebFlux. I close to a solution using reactivex. Thank you very much for you efforts.
            – Nelson Larios
            19 hours ago
















          HI, Brian, thanks for you answer. What I'm trying to do is to create a data stream in exactly the way the Hystrix Dashboard expects it to be. I think it uses the "ping:" String between events as a kind of separation. So your answer gives me something like: So what I really need is just to print that "ping:" at the beginning of an event. But without the "data:". Like this: ping: Not like this: data:ping:
          – Nelson Larios
          yesterday






          HI, Brian, thanks for you answer. What I'm trying to do is to create a data stream in exactly the way the Hystrix Dashboard expects it to be. I think it uses the "ping:" String between events as a kind of separation. So your answer gives me something like: So what I really need is just to print that "ping:" at the beginning of an event. But without the "data:". Like this: ping: Not like this: data:ping:
          – Nelson Larios
          yesterday














          that's what my sample is doing: sending SSE events of type data (the default) and ping. They're currently just interleaved and the ping events are scheduled with a specific duration between them.
          – Brian Clozel
          yesterday




          that's what my sample is doing: sending SSE events of type data (the default) and ping. They're currently just interleaved and the ping events are scheduled with a specific duration between them.
          – Brian Clozel
          yesterday












          When I run your code "ping:" doesn't print. I get this: data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542382826545} data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542382827046} data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542382827547} data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542382828049}
          – Nelson Larios
          yesterday






          When I run your code "ping:" doesn't print. I get this: data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542382826545} data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542382827046} data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542382827547} data:{"type":"HystrixCommand","name":"GetConsumerCommand","group":"ConsumerRemoteGroup","currentTime":1542382828049}
          – Nelson Larios
          yesterday














          I've edited my answer
          – Brian Clozel
          yesterday




          I've edited my answer
          – Brian Clozel
          yesterday












          Hi Brian, it's specific to Hystrix. It's a shame I can't do it with WebFlux. I close to a solution using reactivex. Thank you very much for you efforts.
          – Nelson Larios
          19 hours ago




          Hi Brian, it's specific to Hystrix. It's a shame I can't do it with WebFlux. I close to a solution using reactivex. Thank you very much for you efforts.
          – Nelson Larios
          19 hours ago


















           

          draft saved


          draft discarded



















































           


          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53340867%2fcreating-text-stream-using-spring-webflux%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          'app-layout' is not a known element: how to share Component with different Modules

          android studio warns about leanback feature tag usage required on manifest while using Unity exported app?

          WPF add header to Image with URL pettitions [duplicate]