我正在尝试构建一个小的Spring Boot Reactive API。该API应该允许用户订阅一些以SSE形式返回的数据。
数据位于Kinesis主题上。
创建Reactive API和Kinesis的StreamListener相当简单-但我可以将它们组合在一起,因此Kinesis Topic被用作我的数据服务使用的事件流的生成器。
代码或多或少看起来像这样
//Kinesis binding, with listenerMode: rawRecords
@EnableBinding(Sink.class)
public class KinesisStreamListener {
@StreamListener(value = Sink.INPUT)
public void logger(List<Record> payload) throws Exception {
}
}
@RestController
@RequestMapping("/data")
public class DataResource {
@Autowired
DataService service;
@GetMapping(produces = {MediaType.TEXT_EVENT_STREAM_VALUE, MediaType.APPLICATION_STREAM_JSON_VALUE})
public Flux<EventObject> getData() {
return service.getData();
}
}
@Component
public class DataService {
Flux<EventObject> getData() {
Flux<Long> interval = Flux.interval(Duration.ofMillis(1000));
Flux<EventObject> dataFlux = Flux.fromStream(Stream.generate(() -> ???
));
return dataFlux.zip(interval, dataFlux).map(Tuple2::getT2);
}
}
答案 0 :(得分:0)
以下是我如何执行此操作的示例:https://github.com/artembilan/sandbox/tree/master/cloud-stream-kinesis-to-webflux。
一旦我们就细节和一些改进达成协议,就可以进入官方的Spring Cloud Stream Samples存储库:https://github.com/spring-cloud/spring-cloud-stream-samples
主要思想是通过Spring Cloud Stream Reactive Support重用Flux
提供的@StreamListener
。这已经是FluxPublish
,因此任何新的SSE连接都将作为普通的Reactive订户使用。
有两个技巧可以计数:
listenerMode: rawRecords
,我们还需要配置contentType: application/octet-stream
,以避免在Binder向Sink.INPUT
频道发送消息时进行任何转换尝试。listenerMode: rawRecords
返回了List<Record>
,因此我们在Flux
方法中的@StreamListener
应该完全是这种类型,而不是普通的Record
。这两个问题都被认为是对框架的改进。
所以,现在让我们看看它的外观和工作原理。