跳到主要内容
版本:3.5.10

RSocket

QWen Max 中英对照 RSocket

RSocket 是一种用于字节流传输的二进制协议。它通过在单个连接上进行异步消息传递,支持对称的交互模型。

Spring Framework 的 spring-messaging 模块为 RSocket 请求方和响应方提供了支持,涵盖客户端和服务器端。更多详细信息(包括 RSocket 协议的概述)请参阅 Spring Framework 参考文档中的 RSocket 章节

RSocket 策略自动配置

Spring Boot 会自动配置一个 RSocketStrategies Bean,该 Bean 提供了编码和解码 RSocket 负载所需的所有基础设施。默认情况下,自动配置将按以下顺序尝试进行配置:

  1. 使用 Jackson 的 CBOR 编解码器

  2. 使用 Jackson 的 JSON 编解码器

spring-boot-starter-rsocket starter 提供了这两个依赖项。有关更多自定义可能性,请参阅 Jackson 支持部分

开发者可以通过创建实现 RSocketStrategiesCustomizer 接口的 Bean 来自定义 RSocketStrategies 组件。请注意,它们的 @Order 注解非常重要,因为它决定了编解码器(codecs)的顺序。

RSocket 服务器自动配置

Spring Boot 提供了 RSocket 服务器的自动配置。所需的依赖由 spring-boot-starter-rsocket 提供。

Spring Boot 允许通过 WebFlux 服务器将 RSocket 通过 WebSocket 暴露出来,或者启动一个独立的 RSocket 服务器。这取决于应用程序的类型及其配置。

对于 WebFlux 应用(其类型为 WebApplicationType.REACTIVE),只有在以下属性匹配时,RSocket 服务器才会被集成到 Web 服务器中:

spring.rsocket.server.mapping-path=/rsocket
spring.rsocket.server.transport=websocket
注意

将 RSocket 接入 Web 服务器仅支持使用 Reactor Netty,因为 RSocket 本身就是基于该库构建的。

或者,可以启动一个独立的嵌入式 RSocket TCP 或 WebSocket 服务器。除了依赖项要求外,唯一需要的配置是为该服务器定义一个端口:

spring.rsocket.server.port=9898

Spring Messaging RSocket 支持

Spring Boot 将自动配置用于 RSocket 的 Spring Messaging 基础设施。

这意味着 Spring Boot 将创建一个 RSocketMessageHandler Bean,用于处理发送到你的应用程序的 RSocket 请求。

使用 RSocketRequester 调用 RSocket 服务

一旦服务器和客户端之间建立了 RSocket 通道,任何一方都可以向另一方发送或接收请求。

作为服务器,你可以在 RSocket @Controller 的任意处理方法中注入一个 RSocketRequester 实例。作为客户端,你需要先配置并建立一个 RSocket 连接。Spring Boot 会自动配置一个 RSocketRequester.Builder,其中包含所需的编解码器,并应用所有 RSocketConnectorConfigurer Bean。

RSocketRequester.Builder 实例是一个原型(prototype)bean,这意味着每个注入点都会为你提供一个新的实例。这样设计是有意为之的,因为该构建器是有状态的,你不应该使用同一个实例来创建具有不同配置的请求器。

以下代码展示了一个典型示例:

import reactor.core.publisher.Mono;

import org.springframework.messaging.rsocket.RSocketRequester;
import org.springframework.stereotype.Service;

@Service
public class MyService {

private final RSocketRequester rsocketRequester;

public MyService(RSocketRequester.Builder rsocketRequesterBuilder) {
this.rsocketRequester = rsocketRequesterBuilder.tcp("example.org", 9898);
}

public Mono<User> someRSocketCall(String name) {
return this.rsocketRequester.route("user").data(name).retrieveMono(User.class);
}

}