【问题标题】:Spring Boot RSocketRequester deal with server restartSpring Boot RSocketRequester 处理服务器重启
【发布时间】:2020-03-08 18:09:21
【问题描述】:

我有一个关于 Springs RSocketRequester 的问题。我有一个 rsocket 服务器和客户端。客户端连接到此服务器并请求 @MessageMapping 端点。它按预期工作。

但是如果我重新启动服务器会怎样。如何从客户端自动重新连接到 rsocket 服务器?谢谢

服务器:

@Controller
class RSC {

    @MessageMapping("pong")
    public Mono<String> pong(String m) {
        return Mono.just("PONG " + m);
    }
}

客户:

@Bean
    public RSocketRequester rSocketRequester() {
        return RSocketRequester
                .builder()
                .connectTcp("localhost", 7000)
                .block();

    }

@RestController
class RST {

    @Autowired
    private RSocketRequester requester;

    @GetMapping(path = "/ping")
    public Mono<String> ping(){
        return this.requester
                .route("pong")
                .data("TEST")
                .retrieveMono(String.class)
                .doOnNext(System.out::println);
    }
}

【问题讨论】:

  • 您能在这里分享您的解决方案吗?

标签: spring-boot reconnect rsocket


【解决方案1】:

针对 Spring Framework 5.2.6+ 更新

您可以通过io.rsocket.core.RSocketConnector#reconnect 实现它。

@Bean
Mono<RSocketRequester> rSocketRequester(RSocketRequester.Builder rSocketRequesterBuilder) {
    return rSocketRequesterBuilder
            .rsocketConnector(connector -> connector
                    .reconnect(Retry.fixedDelay(Integer.MAX_VALUE, Duration.ofSeconds(1))))
            .connectTcp("localhost", 7000);
}
@RestController
public class RST {
    @Autowired
    private Mono<RSocketRequester> rSocketRequesterMono;

    @GetMapping(path = "/ping")
    public Mono<String> ping() {
        return rSocketRequesterMono.flatMap(rSocketRequester ->
                rSocketRequester.route("pong")
                        .data("TEST")
                        .retrieveMono(String.class)
                        .doOnNext(System.out::println));
    }
}

【讨论】:

  • 感谢您的回答,我确实将这两种方法结合起来,并且我已经找到了可行的解决方案。感谢您的帮助。
  • @George,你能在这里分享你的解决方案吗?
  • 从 Spring 5.2.6 开始,RSocketRequester.Builder.rsocketFactory 方法已被弃用,因此上述解决方案不再有效。替换是使用 RSocketRequester.Builder.rsocketConnector。有没有人有一些使用 rsockeConnector 的示例代码?
  • @DavidV ,我更新了新 API 的答案。现在没那么难了
【解决方案2】:

我认为我不会在应用程序中创建RSocketRequester bean。与WebClient(有一个可重用连接池)不同,RSocket 请求者包装了一个 RSocket,即一个网络连接。

我认为最好存储 Mono&lt;RSocketRequester&gt; 并订阅它,以便在需要时获得实际的请求者。因为您不想为每个调用创建新连接,所以可以缓存结果。感谢Mono retryXYZ 运算符,您可以通过多种方式来优化重新连接行为。

您可以尝试以下方法:

@Service
public class RSocketPingService {

    private final Mono<RSocketRequester> requesterMono;

    // Spring Boot is creating an auto-configured RSocketRequester.Builder bean
    public RSocketPingService(RSocketRequester.Builder builder) {
        this.requesterMono = builder
                .dataMimeType(MediaType.APPLICATION_CBOR)
                .connectTcp("localhost", 7000).retry(5).cache();
    }

    public Mono<String> ping() {
        return this.requesterMono.flatMap(requester -> requester.route("pong")
                .data("TEST")
                .retrieveMono(String.class));
    }


}

【讨论】:

  • 当我使用你的代码时,结果是一样的。我得到异常 java.nio.channels.ClosedChannelException: null 这就是我想要解决的。当此与 rsocket 服务器的连接断开时,如何在服务器再次启动时自动修复。我正在调查更多 RSocketLoadBalancedMono 如果这可以解决我的问题或可能会重试。你怎么看?
  • 感谢您的回答。我对代码几乎没有改动,这就是为什么它在第一次运行时不起作用。因此,当服务器重新联机时,它会重新订阅此 Mono 并重新连接,这正是我所需要的。非常感谢。
  • @George 你能分享一个有效的答案吗?谢谢!
  • @George +1 您能否分享您的完整工作解决方案?我也需要它。谢谢大佬!
猜你喜欢
  • 2022-06-19
  • 1970-01-01
  • 1970-01-01
  • 2018-03-16
  • 2018-12-09
  • 2014-04-21
  • 2015-03-30
  • 2016-06-15
  • 1970-01-01
相关资源
最近更新 更多