Java 如何在带有弹簧的被动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 -> {

我开始使用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);
}
@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订阅))…