这段内容是 Spring Boot 官方文档中关于 RSocket 的章节(5.9 节) ,它介绍了 Spring Boot 如何支持 RSocket ------一种现代的、异步的、基于消息的网络通信协议。
我们来一步步通俗易懂地解释这段内容,帮助你理解:
🌟 一、什么是 RSocket?
RSocket 是一种二进制通信协议,运行在 TCP 或 WebSocket 等"字节流"传输层之上。
✅ 它的特点:
特性 | 含义 |
---|---|
异步(Async) | 不像 HTTP 那样"发请求 → 等响应",RSocket 支持双向异步通信。 |
单连接(Single Connection) | 客户端和服务器之间只建立一个连接,所有请求/响应都复用这个连接。 |
对称通信(Symmetric) | 客户端可以调用服务器,服务器也可以反过来调用客户端(双向角色)。 |
多种交互模式 | 支持: • 请求-响应(Request-Response) • 单向发送(Fire-and-Forget) • 流式响应(Stream Response) • 双向流(Channel) |
📌 类比:
- HTTP:像打电话,你说一句,对方回一句,说完就挂。
- RSocket:像微信聊天群,双方都可以随时发消息,还能发文件流、持续推送数据。
🔧 二、Spring 对 RSocket 的支持
Spring Framework(特别是 spring-messaging
模块)从 5.2 版本开始原生支持 RSocket。
Spring Boot 在此基础上做了自动配置(auto-configuration),让你用起来更简单。
📦 5.9.1. RSocket Strategies 自动配置
作用:
配置 如何序列化/反序列化数据(比如 Java 对象 ↔ 字节流)。
关键 Bean:RSocketStrategies
这是一个核心组件,负责:
- 编码(Encode):Java 对象 → 字节流
- 解码(Decode):字节流 → Java 对象
- 支持的数据格式:JSON、CBOR(更高效的二进制 JSON)
默认顺序(优先级):
- CBOR(使用 Jackson)
- JSON(使用 Jackson)
如果你的项目引入了
spring-boot-starter-rsocket
,这两个都会自动包含。
如何自定义?
你可以写一个类实现 RSocketStrategiesCustomizer
接口来自定义编解码器:
java
@Bean
public RSocketStrategiesCustomizer myCustomizer() {
return strategies -> {
// 添加自定义编码器,比如 Protobuf
};
}
⚠️ 注意:多个 customizer 的执行顺序由 @Order
注解决定。
🖥️ 5.9.2. RSocket Server 自动配置
Spring Boot 可以帮你自动启动一个 RSocket 服务器。
有两种方式:
✅ 方式一:嵌入到 WebFlux 服务器(通过 WebSocket)
适用场景:你已经有 WebFlux 应用,想通过 WebSocket 暴露 RSocket 服务。
条件:
yaml
# application.yml
spring:
rsocket:
server:
mapping-path: /rsocket # 必须指定路径
transport: websocket # 必须使用 WebSocket
# port: 未设置 # 不能设置独立端口
📌 原理:
- RSocket 服务会绑定到 Web 服务器的
/rsocket
路径上。 - 使用
ws://localhost:8080/rsocket
连接。 - 仅支持 Reactor Netty(因为 RSocket 底层依赖它)。
✅ 方式二:独立的 RSocket 服务器(TCP 或 WebSocket)
适用场景:你想单独运行一个高性能 RSocket 服务,不依赖 HTTP。
配置:
yaml
# application.yml
spring:
rsocket:
server:
port: 9898 # 必须设置端口
transport: tcp # 或 websocket
📌 启动后:
- 监听
9898
端口 - 可以通过
tcp://localhost:9898
直接连接 - 是一个独立的 RSocket 服务,不是 HTTP 服务
🔄 5.9.3. Spring Messaging RSocket 支持
Spring Boot 会自动创建一个关键组件:
RSocketMessageHandler
它的作用:
- 接收客户端发来的 RSocket 请求
- 根据
@MessageMapping
或route
路由到对应的处理方法 - 类似于 Spring MVC 中的
@RequestMapping
示例控制器:
java
@Controller
public class UserController {
@MessageMapping("user")
public Mono<User> getUser(String name) {
return userService.findByName(name);
}
}
👉 当客户端发送 route("user").data("Alice")
,就会调用这个方法。
📞 5.9.4. 使用 RSocketRequester 调用服务
RSocketRequester
是客户端用来发送 RSocket 请求的工具类。
✅ 自动配置:
Spring Boot 会提供一个 RSocketRequester.Builder
(原型 Bean),你可以用它来构建连接。
"原型 Bean" = 每次注入都会得到一个新实例(因为它是有状态的)
示例代码解析:
java
@Service
public class MyService {
private final Mono<RSocketRequester> rsocketRequester;
// 注入 Builder
public MyService(RSocketRequester.Builder rsocketRequesterBuilder) {
// 构建连接:连接到 example.org:9898
this.rsocketRequester = rsocketRequesterBuilder
.connectTcp("example.org", 9898)
.cache(); // 缓存连接,避免重复连接
}
public Mono<User> someRSocketCall(String name) {
return this.rsocketRequester.flatMap(req ->
req.route("user") // 设置路由为 "user"
.data(name) // 发送数据(用户名)
.retrieveMono(User.class) // 接收一个 User 响应
);
}
}
🧠 拆解调用过程:
route("user")
→ 匹配服务端的@MessageMapping("user")
.data(name)
→ 把name
作为参数发送过去.retrieveMono(User.class)
→ 期待返回一个Mono<User>
🧩 总结:RSocket vs HTTP
特性 | HTTP(REST) | RSocket |
---|---|---|
通信模式 | 请求-响应(为主) | 支持四种: • 请求-响应 • 单向 • 流式 • 双向流 |
连接 | 每次请求可能新建连接(HTTP/1.1 复用) | 单连接,长连接,复用 |
双向通信 | 不支持(除非用 WebSocket) | 原生支持(服务器可主动推) |
性能 | 文本协议,较慢 | 二进制协议,高效 |
适用场景 | 前后端分离、API 接口 | 微服务间通信、实时系统、IoT、游戏 |
🚀 实际应用场景举例
场景 | RSocket 如何发挥作用 |
---|---|
微服务间调用 | 服务 A 调用服务 B 的方法,B 还能反向调用 A(对称通信) |
实时通知系统 | 服务器主动推送消息给客户端(如股票行情、聊天) |
物联网设备通信 | 设备与平台保持长连接,低延迟传输数据 |
游戏服务器 | 实时双向通信,支持玩家间互动 |
✅ 如何启用 RSocket?
1. 添加依赖(Maven)
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-rsocket</artifactId>
</dependency>
2. 配置 application.yml
yaml
# 方式一:嵌入 WebFlux(WebSocket)
spring:
rsocket:
server:
mapping-path: /rsocket
transport: websocket
# 或方式二:独立服务器(TCP)
spring:
rsocket:
server:
port: 9898
transport: tcp
3. 写控制器
java
@Controller
public class GreetingController {
@MessageMapping("greet")
public Mono<String> sayHello(String name) {
return Mono.just("Hello, " + name + "!");
}
}
4. 客户端调用
使用 RSocketRequester
发起调用,如上文示例。
❗注意事项
- RSocket 不是替代 HTTP,而是补充,适用于特定高性能、实时场景。
- 学习成本较高,需要理解响应式编程(Reactor:Mono/Flux)。
- 生态还在发展中,不如 REST/HTTP 成熟。
如果你想,我可以提供一个 完整的 Spring Boot + RSocket 示例项目结构,包括:
- 服务端暴露 RSocket
- 客户端调用
- 流式数据推送
- 双向通信演示
是否需要?