Websockets with Spring WebFlux: properly mix authentication data with event treatment

135 views Asked by At

I develop an application where users connect via WebSocket and exchange messages. I use Spring WebFlux and Reactive WebSockets. Security component provide me with a Mono containing current Principal:

Mono<Principal> = session.getHandshakeInfo().getPrincipal()

I did not found any other solution than zip this mono with inbound message flux and outbound message flux. In my opinion this is quite cumbersome, repetitive and ugly.

public class ChatSocketHandler implements WebSocketHandler {

    private Flux<DownstreamMessage> outputEvents;

    public ChatSocketHandler(Sinks.Many<DownstreamMessage> downstreamPublisher) {
        this.outputEvents = downstreamPublisher.asFlux();
    }

    @Override
    public Mono<Void> handle(WebSocketSession session) {
        var input = session.receive()
                .map(WebSocketMessage::getPayloadAsText)
                .map(this::toEvent)
                .flatMap(event -> Mono.just(event).zipWith(session.getHandshakeInfo().getPrincipal()))
                .doOnNext(objects -> /* do something with objects.getT1() and objects.getT2()*/)
                .then();

        var output = session.send(
                outputEvents
                        .flatMap(event -> Mono.just(event).zipWith(session.getHandshakeInfo().getPrincipal()))
                        .filter(objects -> /* Filter events based on event objects.getT1() and Principal objects.getT2() */)
                        .map(Tuple2::getT1)
                        .map(this::toJSON)
                        .map(session::textMessage)
                )
                .then();

        return Mono.zip(input, output).then();
    }

In your opinion, are there any other elegant solutions ?

0

There are 0 answers