使用Spring WebFlux创建文本流

时间:2018-11-16 15:29:59

标签: java spring-boot spring-webflux

我一直在使用Spring WebFlux创建文本流,这是代码。

@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);

    }

}

当我在浏览器中访问/ events网址时,这几乎是我想要得到的:

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}

数据:{“ 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}

我需要做的是在两次迭代之间插入“ ping:”以获取:

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:

数据:{“ 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}

但是,我能得到的最好的是:

数据: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:

数据:{“ 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}

有人知道我需要的方式吗?

1 个答案:

答案 0 :(得分:0)

您可以尝试返回Flux<ServerSentEvent>并指定要发送的事件的类型。像这样:

@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);
    }
}

有了该代码段,我得到以下输出:

$ 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:

Server Sent Events一致。 ping:前缀是否特定于Hystrix?如果是这样,我认为这与SSE规范不一致,并且Spring Framework支持该功能。