spring-rsocket 是否支持在 @ConnectMapping 注释方法中返回 RejectedSetupException?

问题描述

我按照 spring-rsocket-demo 项目来完成我的代码。我在服务器端代码添加了一些身份验证逻辑,如下所示。您可以看到我在身份验证逻辑“CLIENT.add(requester)”之后抛出异常。我在名为 'testRequestGetsResponse' 的 spring-rsocket-demo 项目中执行测试方法,我发现我无法收到异常。如何在@ConnectMapping 注释方法中处理设置有效负载并在需要时返回 RejectedSetupException。


        requester.rsocket()
                .onClose()
                .doFirst(() -> {
                    // Add all new clients to a client list
                    log.info("Client: {} CONNECTED.",client);
                    //throw Exception during process setup payload
                    //my authentication code.
                    try {
//                        CLIENTS.add(requester);
                        throw new RuntimeException();
                    } catch (Exception exception) {
                        throw exception;
                    }
                })
                .doOnError(error -> {
                    // Warn when channels are closed by clients
                    log.warn("Channel to client {} CLOSED",client);
                })
                .doFinally(consumer -> {
                    // Remove disconnected clients from the client list
                    CLIENTS.remove(requester);
                    log.info("Client {} disCONNECTED",client);
                })
                .subscribe();

解决方法

您应该将 @ConnectionMapping 方法定义如下:

@ConnectionMapping 
Mono<Void> handleSetup(@Payload String payload) {
   // Add all new clients to a client list
   log.info("Client: {} CONNECTED.",client);
   boolean isAuthenticated = ... //my authentication code.
   if (!isAuthenticated) {
     //throw Exception during process setup payload
     return Mono.error(new RejectedSetupException("connection is not authenticated"));
   }

   // add client if it is authenticated
   CLIENTS.add(requester);

   requester.rsocket()
            .onClose()
            .doFinally(consumer -> {
               // Remove disconnected clients from the client list
               CLIENTS.remove(requester);
               log.info("Client {} DISCONNECTED",client);
            })
            .subscribe();

   return Mono.empty();
}

从上面的代码可以看出,如果一个连接没有通过认证,它会返回一个带有适当错误的 Mono.error