spring-projects / spring-boot

Spring Boot helps you to create Spring-powered, production-grade applications and services with absolute minimum fuss.
https://spring.io/projects/spring-boot
Apache License 2.0
75.13k stars 40.68k forks source link

springboo-rsocket how to use contextView #39855

Closed MrWangGang closed 8 months ago

MrWangGang commented 8 months ago

I have an interceptor:

public class RSocketMetadataInterceptor implements SocketAcceptorInterceptor {
    @Override
    public SocketAcceptor apply(SocketAcceptor socketAcceptor) {
        return (setup, sendingSocket) -> {
            ByteBuf byteBuf = setup.metadata();
            SecurityStash securityStash = getValueFromMetadata(byteBuf);
            String authToken = securityStash.getAuthToken();
            String principal = securityStash.getPrincipal();
            return socketAcceptor.accept(setup, sendingSocket)
                    .contextWrite(Context.of(AUTHTOKEN_STASH_NAMING, authToken))
                    .contextWrite(Context.of(AUTHTOKEN_STASH_NAMING, principal));
        };
    }
}

In the interceptor, I put variables into the contextView. Consequently, in the following method:

@MessageMapping(LOGIN + "/test")
public Flux<String> test(@Payload SmsLoginDTO dto, @Headers Map<String, Object> metadata){
    //return Flux.just("1","2","3");
    rsocketPrincipalFactory.fetchPrincipal().subscribe();
    int i = 0;
    throw new EventException(EB_USER_000);
}

I attempt to retrieve the contextView through fetchPrincipal:

private Mono<String> fetchPrincipal() {
    return Mono.deferContextual(Mono::just)
            .map(contextView -> {
                Object o = contextView.get(PRINCIPAL_STASH_NAMING);
                return o.toString();
            });  
}

However, the contextView I obtain is empty. Why is this happening? Could it be that the interceptor is not propagating the context to the subsequent methods?"

MrWangGang commented 8 months ago

Is there any alternative solution, similar to serviceExchange in WebFlux, where I can retrieve it from anywhere using Mono.deferContextual?

MrWangGang commented 8 months ago
public class RSocketMetadata2Interceptor implements RSocketInterceptor {

    @Override
    public RSocket apply(RSocket rSocket) {
        rSocket.getClass();
        return new RSocket() {
            @Override
            public Flux<Payload> requestStream(Payload payload) {
                return rSocket.requestStream(payload).contextWrite(Context.of("ddd","ddd"));
            }
        };
    }

use RSocketInterceptor is ok. why

wilkinsona commented 8 months ago

RSocket support is a Spring Framework feature. Furthermore, as mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements. Stack Overflow is a better place for questions like this.