【问题标题】:with spring boot rsocket capture the cancel frame type使用 spring boot rsocket 捕获取消帧类型
【发布时间】:2020-06-21 12:39:26
【问题描述】:

我有一个 spring boot rsocket 实现,如果客户端取消或关闭他们的 rsocket 请求,那么我想取消服务器上的其他订阅注册。

在 spring boot 服务器的日志中,我可以看到发送或接收到一条取消消息:

WARN i.r.t.n.s.WebsocketServerTransport$1 [reactor-http-nio-3] received WebSocket Close Frame - connection is closing
INFO r.u.Loggers$Slf4JLogger [reactor-http-nio-3] cancel()

如何捕捉和处理这个取消信号?

我尝试取消端点,但这些端点没有捕获信号:

@MessageMapping("cancel")
Flux<Object> onCancel() {
    log.info("Captured cancel signal");
}

@ConnectMapping("cancel")
Flux<Object> onCancel2() {
    log.info("Captured cancel2 signal");
}

cancel subscriptions上的这个问题可能是相关的,detecting websocket disconnection上的这个问题

【问题讨论】:

    标签: spring-boot websocket reactor-netty rsocket


    【解决方案1】:

    这不是一个很好的问题。答案是

    INFO r.u.Loggers$Slf4JLogger [reactor-http-nio-3] cancel()

    被从原始@MessageMapping 端点设置的FluxSink 看到。

    例如:

    @MessageMapping("hello")
    Flux<Object> hello(@Payload String message) {       
        return myService.generateWorld(message);
    }
    

    myService 类中

    public Flux<Object> generateWorld(String hello) {
        EmitterProcessor<Object> emitter = EmitterProcessor.create();
        FluxSink<Object> sink = emitter.sink(FluxSink.OverflowStrategy.LATEST);
    
        // doing stuff with sink here
        sink.next(stuff());
    
        // This part will handle a cancel from the client
        sink.onCancel(() -> {log.info("********** SINK.onCancel ***********");});
    
        return Flux.from(emitter));  
    }
    

    sink.onCancel() 将处理从客户端到hello 端点的通量取消。

    【讨论】:

    • 以后的版本和Sink.Many()使用this
    【解决方案2】:

    要捕获取消信号,您可以使用订阅onClose() 事件。

    在你的控制器中

    @Controller
    class RSocketConnectionController {
    
        @ConnectMapping("client-id")
        fun onConnect(rSocketRequester: RSocketRequester, clientId: String) {
    //        rSocketRequester.rsocket().dispose()   //to reject connection
            rSocketRequester
                    .rsocket()
                    .onClose()
                    .subscribe(null, null, {
                        log.info("{} just disconnected", clientId)
    
                        //TODO here whatever you want
                    })
        }
    }
    

    您的客户端需要正确发送 SETUP 帧才能调用此@ConnectMapping。如果你使用rsocket-js,你需要像这样添加一个payload:

    const client = new RSocketClient({
            // send/receive JSON objects instead of strings/buffers
            serializers: {
              data: JsonSerializer,
              metadata: IdentitySerializer
            },
            setup: {
              //for connection mapping on server
              payload: {
                data: 'unique-client-id',   //TODO you can receive this data on server side
                metadata: String.fromCharCode("client-id".length) + "client-id"
              },
              // ms btw sending keepalive to server
              keepAlive: 60000,
    .....
            }
    });
    
    

    【讨论】:

    • 谢谢,我不能完全让它工作,但回答了下面cancel() 的问题。还是不知道WebSocket Close Frame
    猜你喜欢
    • 1970-01-01
    • 2021-05-10
    • 1970-01-01
    • 2020-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-13
    相关资源
    最近更新 更多