web-dev-qa-db-fra.com

Webflux websocketclient, Comment envoyer plusieurs requêtes au cours d'une même session [bibliothèque du client de conception]

TL; DR;

Nous essayons de concevoir un serveur WebSocket en utilisant l’implémentation Webflux Webflux de Spring. Le serveur a des opérations de serveur HTTP habituelles, par exemple. create/fetch/update/fetchall. À l'aide de WebSockets, nous avons essayé d'exposer un point de terminaison de sorte que les clients puissent exploiter une seule connexion pour toutes sortes d'opérations, car les WebSockets sont conçus à cet effet. Est-ce un bon design avec webflux et WebSockets?

Version longue

Nous commençons un projet qui utilisera des sockets web réactifs à partir de spring-webflux. Nous devons créer une bibliothèque client réactive pouvant être utilisée par les consommateurs pour se connecter au serveur.

Sur le serveur, nous recevons une demande, lisons un message, l'enregistrons et renvoyons une réponse statique:

public Mono<Void> handle(WebSocketSession webSocketSession) {
    Flux<WebSocketMessage> response = webSocketSession.receive()
            .map(WebSocketMessage::retain)
            .concatMap(webSocketMessage -> Mono.just(webSocketMessage)
                    .map(parseBinaryToEvent) //logic to get domain object
                    .flatMap(e -> service.save(e))
                    .thenReturn(webSocketSession.textMessage(SAVE_SUCCESSFUL))
            );

    return webSocketSession.send(response);
}

Sur le client , nous voulons passer un appel lorsque quelqu'un appelle la méthode save et renvoyer la réponse de server.

public Mono<String> save(Event message) {
    new ReactorNettyWebSocketClient().execute(uri, session -> {
      session
              .send(Mono.just(session.binaryMessage(formatEventToMessage)))
              .then(session.receive()
                      .map(WebSocketMessage::getPayloadAsText)
                      .doOnNext(System.out::println).then()); //how to return this to client
    });
    return null;
}

Nous ne savons pas exactement comment procéder. Idéalement, nous pensons qu'il devrait y avoir

1) client.execute ne devrait être appelé qu'une seule fois et tenir d'une manière ou d'une autre la session. La même session devrait être utilisée pour envoyer des données lors d'appels ultérieurs.

2) Comment renvoyer la réponse du serveur que nous obtenons dans session.receive?

3) Que faire dans le cas de fetch lorsque la réponse est énorme (pas simplement une chaîne statique mais une liste d'événements) dans session.receive?

Nous menons des recherches mais nous sommes incapables de trouver les ressources appropriées pour la documentation/la mise en œuvre webflux-websocket-client en ligne. Tous les indicateurs sur la façon d'aller de l'avant.

8
Mritunjay

Pas sûr que ce soit votre cas ?? Je vois que vous envoyez une réponse de flux statique (c'est un flux qui peut être fermé) Vous avez besoin d'un flux ouvert pour envoyer des messages à cette session, vous pouvez par exemple créer un processeur 

public class SocketMessageComponent {
private DirectProcessor<String> emitterProcessor;
private Flux<String> subscriber;

public SocketMessageComponent() {
    emitterProcessor = DirectProcessor.create();
    subscriber = emitterProcessor.share();
}

public Flux<String> getSubscriber() {
    return subscriber;
}

public void sendMessage(String mesage) {
    emitterProcessor.onNext(mesage);
}

}

et ensuite vous pouvez envoyer 

 public Mono<Void> handle(WebSocketSession webSocketSession) {
    this.webSocketSession = webSocketSession;
    return webSocketSession.send(socketMessageComponent.getSubscriber()
            .map(webSocketSession::textMessage))
            .and(webSocketSession.receive()
                    .map(WebSocketMessage::getPayloadAsText).log());
}
2
Ricard Kollcaku