WebClient 与 WebSocketClient

WebClient vs WebSocketClient

我正在尝试 spring webflux。当我们有 WebClient 时,我对为什么我们需要 WebSocketClient 感到有点困惑。

在 Spring 5 之前,我们遇到了两个问题
1. REST 调用是阻塞调用,因为我们使用的是 HttpClient。 并且
2. 主要是需要数据的时候从客户端拉取机制。

但是有了 Spring 5 和 web flux 模块,我们可以在服务器端有这样的东西

@Bean
    public RouterFunction<ServerResponse> routerFunction () {
        return
                route(
                        GET("/streaming"),  serverRequest -> {

                            Flux<Integer> flow = Flux.just(1, 2, 3, 4, 5).delayElements(Duration.ofSeconds(2)).doOnEach(entry -> System.out.println(entry.get()));
                            return ServerResponse.ok().contentType(MediaType.APPLICATION_STREAM_JSON).body(BodyInserters.fromPublisher(flow, Integer.class));
                        }
                )
        ;
    }

我们可以从客户端使用 WebClient 解决上述两个问题

WebClient.create("http://localhost:8080")
        .get()
        .uri("/streaming")
        .accept(MediaType.APPLICATION_STREAM_JSON)
        .exchange()
        .flatMap(response -> response.bodyToMono(String.class))
        .subscribe(System.out::println);

    IntStream.range(0,10).forEach(i -> {
      try {
        Thread.sleep(2000);
        System.out.println("non blocking");
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    });

在这种情况下,首先,REST 调用是非阻塞的,这可以通过立即执行下一条语句这一事实来验证。而且数据是从服务器端推送的,而不是从客户端拉取的。

所以如果我们可以使用 WebClient 做到这一点,那么我需要 WebSocketClient 的地方。

WebSocketClientWebClient

相比有两个主要区别
  1. 它不提供反应式而是异步 API

  2. 它在较低的抽象级别上运行,对连接关闭等事件做出反应。

  3. 它使用双向的 WebSockets。

所以 WebSocketClient 的用例是:

  • 你想要双向通信,而不是 request/response(响应可能很大,而且一点一点地到达。

  • 您想对低级协议事件做出反应

  • 您不想依赖 Project Reactor