Java 如何在带有弹簧的被动websocket上推送数据以响应请求?
我开始使用Spring Boot 2.1.3的被动WebSocket。我创建了一个Java 如何在带有弹簧的被动websocket上推送数据以响应请求?,java,websocket,spring-webflux,project-reactor,Java,Websocket,Spring Webflux,Project Reactor,我开始使用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 -> {
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);
}
@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
}));
现在我不知道如何组合这两个实现
我希望做这样的事情:
@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);
}
@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
}));
但这只会立即断开websocket客户端的连接,而不做任何操作。使用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;
})
);
}
@覆盖
公共单声道句柄(WebSocketSession会话){
返回会话.send(
session.receive()
.flatMap(webSocketMessage->{
int id=Integer.parseInt(webSocketMessage.getPayloadAsText());
流量=服务。订阅效率数据(id);
变量发布者=流量
.手柄((o,水槽)->{
试一试{
next(objectMapper.writeValueAsString(o));
}捕获(JsonProcessingException e){
e、 printStackTrace();
return;//在反应流中禁止null
}
})
.map(会话::文本消息)
.延迟元素(持续时间为秒(1));
返回出版商;
})
);
}
关键外卖
flatMap
或concatMap
(请参见差异Null
。在反应流中,禁止使用Null
值(参见规范规则null
->结束时,请使用handle
运算符。有关详细信息,请参阅@OlehDokuka的可能重复我以前看到过这个链接问题,但我看不出这有什么帮助。对。我看到了问题。非常感谢你。在catch块中使用
sink.error(e);
是否好?如何添加会话.textMessage(“使用id订阅”+id)
在连接websocket时?是否希望在发送任何消息之前发送它?>非常感谢。使用sink.error(e)是否合适;在catch块中?
如果您想关闭连接->,那么它就是。否则,将其转换为特定的用户可读消息并通过WS-connectionAnyway发送是有意义的,您可以这样做->session.receive().startsWith(Flux.just(session.textMessage(“使用id”+id订阅))…