Java 在reactor Mono.defer调用上未更新时间戳
我有一个服务,它提供数据库中所有当前股票符号的汇率列表。 调用非常简单,当调用服务的Java 在reactor Mono.defer调用上未更新时间戳,java,spring,spring-boot,reactive-programming,project-reactor,Java,Spring,Spring Boot,Reactive Programming,Project Reactor,我有一个服务,它提供数据库中所有当前股票符号的汇率列表。 调用非常简单,当调用服务的rates()方法时,将以以下类的形式给出一个随机速率: public class Rate { private final long timestamp = Instant.now().toEpochMilli(); private String symbol; private final double rate = (Math.random() * 100).toBigDecimal().setS
rates()
方法时,将以以下类的形式给出一个随机速率:
public class Rate {
private final long timestamp = Instant.now().toEpochMilli();
private String symbol;
private final double rate = (Math.random() * 100).toBigDecimal().setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
// getters and setters
}
服务方法的实现是:
public Flux<Rate> rates() {
return service.findAll();
}
公共流量率(){
return service.findAll();
}
我有一个反应式WebSocketHandler,看起来像这样:
@Service
public class MyHandler implements WebSocketHandler {
private final ObjectMapper objectMapper;
private final RateService service;
private final ApplicationProperties applicationProperties;
public MyHandler(ObjectMapper objectMapper, RateService service, ApplicationProperties applicationProperties) {
this.objectMapper = objectMapper;
this.service = service;
this.applicationProperties = applicationProperties;
}
@Override
public Mono<Void> handle(WebSocketSession session) {
return session.send(
Mono.defer(() -> service.rates().collectList())
.repeat()
.delayElements(Duration.ofSeconds(applicationProperties.getInterval()))
.map(value -> {
try {
return objectMapper.writeValueAsString(value);
} catch (JsonProcessingException e) {
return null;
}
})
.map(session::textMessage)
);
}
}
@服务
公共类MyHandler实现WebSocketHandler{
私有最终ObjectMapper ObjectMapper;
私人最终收费服务;
私有最终应用程序属性应用程序属性;
公共MyHandler(ObjectMapper ObjectMapper、RateService服务、ApplicationProperties ApplicationProperties){
this.objectMapper=objectMapper;
服务=服务;
this.applicationProperties=applicationProperties;
}
@凌驾
公共单声道句柄(WebSocketSession会话){
返回会话.send(
Mono.defer(()->service.rates().collectList())
.重复
.delayElements(持续时间.of秒(applicationProperties.getInterval())
.map(值->{
试一试{
返回objectMapper.writeValueAsString(值);
}捕获(JsonProcessingException e){
返回null;
}
})
.map(会话::文本消息)
);
}
}
当我通过客户端连接到WebSocket时,我每5秒就会得到一个速率列表,这很好。我唯一的问题是timestamp
属性每5秒就有一个完全相同的时间戳。所以我通过WebSocket的第一个响应是这样的:[{“timestamp”:“2018-10-08T09:52:51.387Z”,“symbol”:“GOOG”,“rate”:33.91}]
,第二个响应是[{“timestamp”:“2018-10-08T09:52:51.387Z”,“symbol”:“GOOG”,“rate”:51.43}
。所以速率改变了,但时间戳没有改变
但是,我可以通过重写
rate
字段的getter来解决这个问题,但我不希望在该层中解决它。我只希望getter返回值而不进行任何操作。几乎正确,为了理解,请运行下面的内容,有一些东西放错了位置,我建议您从查看使用'Creating Rate'发出的时间戳开始。
在创建列表之前,重复、重复、重复,因此在将其发送到客户端之前创建并存储该列表,因此如果延迟创建过程而不是发送过程,则速率将每5秒创建一次并发出
public class MyHandler {
private final ObjectMapper objectMapper = new ObjectMapper();
public Flux<String> handle() {
return Mono.defer(() -> rates().delayElements(Duration.ofSeconds(5)).collectList())
.repeat()
.map(value -> {
try {
return objectMapper.writeValueAsString(value);
} catch (JsonProcessingException e) {
return null;
}
});
}
private Flux<Rate> rates() {
return Flux.just(new Rate("a"), new Rate("b"), new Rate("c"));
}
public static void main(String[] args) {
new MyHandler().handle()
.subscribe(str -> System.out.println(str + ", time now - " + Instant.now().toEpochMilli()));
try {
Thread.sleep(60_000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
static class Rate {
private final long timestamp;
private String symbol;
private final double rate;
public Rate(String symbol) {
this.symbol = symbol;
timestamp = Instant.now().toEpochMilli();
rate = new BigDecimal(Math.random() * 100).setScale(2, RoundingMode.HALF_UP).doubleValue();
System.out.println("Creating Rate " + timestamp);
}
// getters and setters
public long getTimestamp() {
return timestamp;
}
public String getSymbol() {
return symbol;
}
public void setSymbol(String symbol) {
this.symbol = symbol;
}
public double getRate() {
return rate;
}
}
}
公共类MyHandler{
私有最终ObjectMapper ObjectMapper=新ObjectMapper();
公共流量句柄(){
返回Mono.defer(()->rates().delayElements(持续时间为秒(5)).collectList())
.重复
.map(值->{
试一试{
返回objectMapper.writeValueAsString(值);
}捕获(JsonProcessingException e){
返回null;
}
});
}
私人流量率(){
收益流量。刚刚(新利率(“a”)、新利率(“b”)、新利率(“c”);
}
公共静态void main(字符串[]args){
新建MyHandler().handle()
.subscribe(str->System.out.println(str+”,time now-“+Instant.now().toEpochMilli());
试一试{
睡眠(60_000);
}捕捉(中断异常e){
e、 printStackTrace();
}
}
静态课率{
私有最终长时间戳;
私有字符串符号;
私人最终双倍费率;
公共费率(字符串符号){
这个符号=符号;
timestamp=Instant.now().toEpochMilli();
rate=新的BigDecimal(Math.random()*100).setScale(2,舍入模式.HALF_UP).doubleValue();
System.out.println(“创建速率”+时间戳);
}
//接球手和接球手
公共长getTimestamp(){
返回时间戳;
}
公共字符串getSymbol(){
返回符号;
}
公共无效集合符号(字符串符号){
这个符号=符号;
}
公共双速率(){
回报率;
}
}
}
几乎正确,为了理解,请运行下面的内容,有一些东西放错了位置,我建议您从查看'Creating Rate'
发出的时间戳开始
在创建列表之前,重复、重复、重复,因此在将其发送到客户端之前创建并存储该列表,因此如果延迟创建过程而不是发送过程,则速率将每5秒创建一次并发出
public class MyHandler {
private final ObjectMapper objectMapper = new ObjectMapper();
public Flux<String> handle() {
return Mono.defer(() -> rates().delayElements(Duration.ofSeconds(5)).collectList())
.repeat()
.map(value -> {
try {
return objectMapper.writeValueAsString(value);
} catch (JsonProcessingException e) {
return null;
}
});
}
private Flux<Rate> rates() {
return Flux.just(new Rate("a"), new Rate("b"), new Rate("c"));
}
public static void main(String[] args) {
new MyHandler().handle()
.subscribe(str -> System.out.println(str + ", time now - " + Instant.now().toEpochMilli()));
try {
Thread.sleep(60_000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
static class Rate {
private final long timestamp;
private String symbol;
private final double rate;
public Rate(String symbol) {
this.symbol = symbol;
timestamp = Instant.now().toEpochMilli();
rate = new BigDecimal(Math.random() * 100).setScale(2, RoundingMode.HALF_UP).doubleValue();
System.out.println("Creating Rate " + timestamp);
}
// getters and setters
public long getTimestamp() {
return timestamp;
}
public String getSymbol() {
return symbol;
}
public void setSymbol(String symbol) {
this.symbol = symbol;
}
public double getRate() {
return rate;
}
}
}
公共类MyHandler{
私有最终ObjectMapper ObjectMapper=新ObjectMapper();
公共流量句柄(){
返回Mono.defer(()->rates().delayElements(持续时间为秒(5)).collectList())
.重复
.map(值->{
试一试{
返回objectMapper.writeValueAsString(值);
}捕获(JsonProcessingException e){
返回null;
}
});
}
私人流量率(){
收益流量。刚刚(新利率(“a”)、新利率(“b”)、新利率(“c”);
}
公共静态void main(字符串[]args){
新建MyHandler().handle()
.subscribe(str->System.out.println(str+”,time now-“+Instant.now().toEpochMilli());
试一试{
睡眠(60_000);
}捕捉(中断异常e){
e、 printStackTrace();