我正在使用Spring Boot 2.1.3开始使用反应式Websocket。我创建了一个WebSocketHandler
实现,如下所示:
@Override
public Mono<Void> handle(WebSocketSession session) {
Flux<EfficiencyData> flux = service.subscribeToEfficiencyData(1);
var publisher = flux.map( o -> {
try {
return objectMapper.writeValueAsString(o);
} catch (JsonProcessingException e) {
e.printStackTrace();
return null;
}
}).map(session::textMessage)
.delayElements(Duration.ofSeconds(1));
return session.send(publisher);
}
这有效,如果我连接,则每秒在我的websocket客户端中序列化EfficiencyData
。
但是,我想响应来自websocket的请求,告诉service
我想要数据的ID。我设法获得了这样的请求信息:
@Override
public Mono<Void> handle(WebSocketSession session) {
return session.send(session.receive().map(webSocketMessage -> {
int id = Integer.parseInt(webSocketMessage.getPayloadAsText());
return session.textMessage("Subscribing with id " + id);
}));
现在我不知道如何结合这两个实现?
我希望做这样的事情:
@Override
public Mono<Void> handle(WebSocketSession session) {
return session.send(session.receive().map(webSocketMessage -> {
int id = Integer.parseInt(webSocketMessage.getPayloadAsText());
Flux<EfficiencyData> flux = service.subscribeToEfficiencyData(id);
var publisher = flux.map( o -> {
try {
return objectMapper.writeValueAsString(o);
} catch (JsonProcessingException e) {
e.printStackTrace();
return null;
}
}).map(session::textMessage)
.delayElements(Duration.ofSeconds(1));
return publisher; //Does not compile
}));
但是,由于publisher
是Flux<WebSocketMessage>
,并且应该是Publisher<WebSocketMessage>
,因此无法编译。应该如何处理?
编辑:
在WebSocketHandler
的Javadoc示例之后,我尝试了以下方法:
@Override
public Mono<Void> handle(WebSocketSession session) {
Flux<EfficiencyData> flux =
session.receive()
.map(webSocketMessage -> Integer.parseInt(webSocketMessage.getPayloadAsText()))
.concatMap(service::subscribeToEfficiencyData);
Mono<Void> input = flux.then();
Mono<Void> output = session.send(flux.map(data -> session.textMessage(data.toString()))).then();
return Mono.zip(input, output).then();
}
但这只是立即断开websocket客户端的连接,而无需执行任何操作。
答案 0 :(得分:0)
flatMap
或concatMap
来平整返回的发布者要解决您的问题,您必须使用允许平整返回值的运算符。例如
@Override
public Mono<Void> handle(WebSocketSession session) {
return session.send(
session.receive()
.flatMap(webSocketMessage -> {
int id = Integer.parseInt(webSocketMessage.getPayloadAsText());
Flux<EfficiencyData> flux = service.subscribeToEfficiencyData(id);
var publisher = flux
.<String>handle((o, sink) -> {
try {
sink.next(objectMapper.writeValueAsString(o));
} catch (JsonProcessingException e) {
e.printStackTrace();
return; // null is prohibited in reactive-streams
}
})
.map(session::textMessage)
.delayElements(Duration.ofSeconds(1));
return publisher;
})
);
}