7

RSocket | 替代 REST 的不二选择

 3 years ago
source link: https://mp.weixin.qq.com/s?__biz=MjM5MzEwODY4Mw%3D%3D&%3Bmid=2257485946&%3Bidx=1&%3Bsn=162e28b869992eafda4a925435a561f2
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

关于 RSocket

  • RSocket 是一个新的、语言无关的第七层应用网络协议。它是一个双向、多路复用、基于消息、基于反应流背压的二进制协议。

  • 和传统网络编程模型 HTTP 的 Request/Response 方式不同。RSocket 除了 Request/Response 方式之外,还支持 Fire And Forget(发送不回)、Stream(单向流)、Channel(双向流)。

  • 提供常见语言的客户端实现,极大的丰富了网络交互场景,无论即时通讯、服务交互、物联网。

nqMryei.png!mobile
  • Dubbo 在 3.0 版本已经拥抱 RSocket,基于 RSocket 对响应式编程提供了支持。

  • 随着 Spring Boot 2.4 的发布, Spring 对 RSocket 的支持日渐完善 ,本文将通过将通过 Spring Boot 完成 RSocket 的四种交互模式。

安装 RSC 客户端

  • 通过 rsc 客户端,我们可以非常方便的调试调用 RSocket (可以理解成 http postman 工具)

  • 下载最新版本安装即可 https://github.com/making/rsc/releases [1]

  • 查看 rsc 版本

 ./rsc --version                                                        20:51:28
{"version": "0.7.0", "build": "2021-01-08T01:52:51Z", "rsocket-java": "1.1.0"}

创建 RSocket Server

  • 创建 spring boot 项目,添加相关依赖即可

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-rsocket</artifactId>
</dependency>
  • 指定 rsocket server 服务端口即可

spring.rsocket.server.port=8848

RR 请求模型

  • 使用 @MessageMapping 指定路由路径即可

@Controller
public class GreetingsController {
@MessageMapping("request-response")
Mono<String> reqResponse(@Payload String payload) {
log.info("收到 RR 请求信息: {}", payload);
return Mono.just("Hello, " + payload);
}
}
  • 使用 rsc 请求 rsocket server 得到响应

./rsc tcp://localhost:8848  -r request-response -d 'lengleng'          21:05:27
Hello, lengleng!
  • 可以增加 --debug 参数 查看整个请求过程

 ./rsc tcp://localhost:8848  -r request-response -d 'lengleng' --debug  21:05:31
2021-01-19 21:07:49.124 DEBUG 76916 --- [actor-tcp-nio-2] io.rsocket.FrameLogger : sending ->
Frame => Stream ID: 0 Type: SETUP Flags: 0b0 Length: 75
Data:

2021-01-19 21:07:49.128 DEBUG 76916 --- [actor-tcp-nio-2] io.rsocket.FrameLogger : sending ->
Frame => Stream ID: 1 Type: REQUEST_RESPONSE Flags: 0b100000000 Length: 38
Metadata:
+-------------------------------------------------+
| 0 1 2 3 4 5 6 7 8 9 a b c d e f |
+--------+-------------------------------------------------+----------------+
|00000000| fe 00 00 11 10 72 65 71 75 65 73 74 2d 72 65 73 |.....request-res|
|00000010| 70 6f 6e 73 65 |ponse |
+--------+-------------------------------------------------+----------------+
Data:
+-------------------------------------------------+
| 0 1 2 3 4 5 6 7 8 9 a b c d e f |
+--------+-------------------------------------------------+----------------+
|00000000| 6c 65 6e 67 6c 65 6e 67 |lengleng |
+--------+-------------------------------------------------+----------------+
2021-01-19 21:07:49.142 DEBUG 76916 --- [actor-tcp-nio-2] io.rsocket.FrameLogger : receiving ->
Frame => Stream ID: 1 Type: NEXT_COMPLETE Flags: 0b1100000 Length: 22
Data:
+-------------------------------------------------+
| 0 1 2 3 4 5 6 7 8 9 a b c d e f |
+--------+-------------------------------------------------+----------------+
|00000000| 48 65 6c 6c 6f 2c 20 6c 65 6e 67 6c 65 6e 67 21 |Hello, lengleng!|
+--------+-------------------------------------------------+----------------+

FNF 请求模型

  • 相较于 RR 模型,FNF 不需要返回结果 Mono

 @MessageMapping("fire-forget")
Mono<Void> fnf(@Payload String payload) {
log.info("收到 FAF 请求信息: {}", payload);
return Mono.empty();
}
  • 使用 rsc 请求 rsocket server 无响应

 ./rsc tcp://localhost:8848  -r fire-forget -d  --fnf                   21:19:29
⋊>

单向 Stream

  • 单向 Stream 使用 Flux 作为报文输出,这里演示在收到客户端请求后,每秒返回一次流

 @MessageMapping("stream")
Flux<String> stream(@Payload String payload) {
return Flux.interval(Duration.ofSeconds(1)).map(aLong -> payload + LocalDateTime.now());
}
  • 使用 rsc 请求 rsocket server 返回 stream 流

⋊> ~/e/t/rscoket ./rsc tcp://localhost:8848  -r stream -d 'lengleng' --stream            21:32:15
lengleng2021-01-19T21:34:10.700473
lengleng2021-01-19T21:34:11.696332
lengleng2021-01-19T21:34:12.698527
lengleng2021-01-19T21:34:13.699631
lengleng2021-01-19T21:34:14.697984

双向 Channel

  • 双向 channel 的输出和响应都为 Flux

 @MessageMapping("channel")
Flux<String> channel(Flux<String> settings) {
return settings.map(s -> "你好 " + s + LocalDateTime.now());
}
  • 使用 rsc 进入 channel 并指定交互模式 (注意最后的 - 参数)

./rsc  tcp://localhost:8848  -r channel -d  -  --channel               21:42:40
lengleng
你好 lengleng2021-01-19T21:42:48.010415
spring
你好 spring2021-01-19T21:42:51.316467
java
你好 java2021-01-19T21:42:54.181102

参考资料

[1]

RSC客户端: https://github.com/making/rsc/releases


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK