RSocket 入门:Spring Boot 的 Fire-And-Forget

工程 | Ben Wilcock | 2020年3月16日 | ...

时间:大约15分钟。

一些阅读本文的开发者可能已经使用 HTTP 多年了。他们中的大多数人也知道,如果您想将 HTTP 与其他消息传递模型(例如 fire-and-forget)一起使用,有时您必须使用巧妙的解决方法例如 Stackoverflow 上的这个。这是因为 HTTP 是一种请求-响应协议。它要求发送请求并接收响应。它没有关于无需任何形式响应的单向消息的概念。

RSocket 采用了不同的方法。RSocket 在 TCP 和 WebSockets 等传输层之上定义了一个新的协议层。这个新协议为开发者提供了更大的选择,并内置支持四种不同的交互模型

  • 请求/响应
  • fire-and-forget
  • 请求/流
  • 通道

在之前的文章中,您已经学习了如何使用 RSocket 进行请求/响应。在这篇文章中,您将学习如何向代码中添加 fire-and-forget 消息传递。让我们开始吧!

如果您没有阅读之前关于使用 RSocket 进行服务器端客户端请求-响应消息传递的文章,现在是您的机会!代码示例可在GitHub上找到。

步骤 1:添加服务器端 Fire-And-Forget 方法

您会记得之前在 rsocket-server 项目中处理过的 RSocketController

@Slf4j
@Controller
public class RSocketController {
// code goes here
}

RSocketController 是处理请求-响应消息传递的服务器端类。它的 .requestResponse() 方法接受 Message 对象作为参数,并返回 Message 对象作为响应。正是这种一个对象输入、一个对象输出的方法签名使该方法成为请求-响应方法。

要向服务器添加 fire-and-forget 功能,您必须添加一个具有不同签名的方法。.fireAndForget() 方法应该接受单个 Message 参数,但这次返回 void,如下所示...

    @MessageMapping("fire-and-forget")
    public void fireAndForget(Message request) {
        log.info("Received fire-and-forget request: {}", request);
    }

您仍然必须在方法上使用 @MessageMapping 注解,但这次您必须为路由映射提供一个不同的名称。在上面的代码中,我使用了名称“fire-and-forget”。

在 Spring RSocket 文档中,方法签名规则位于消息映射部分。

步骤 2:添加客户端 Fire-And-Forget 方法

您在按照上一篇文章操作时,在 rsocket-client 项目中构建了 RSocketShellClient

@Slf4j
@ShellComponent
public class RSocketShellClient {
// code goes here
}

RSocketShellClient 使用 .requestResponse() 方法通过在类构造函数中创建的 RSocketRequester 向 RSocket 服务器发送单个请求。

要向客户端添加 fire-and-forget 功能,请向 RSocketShellClient 添加一个新的 .fireAndForget() 方法,如下所示

    @ShellMethod("Send one request. No response will be returned.")
    public void fireAndForget() throws InterruptedException {
        log.info("\nFire-And-Forget. Sending one request. Expect no response (check server log)...");
        this.rsocketRequester
                .route("fire-and-forget")
                .data(new Message(CLIENT, FIRE_AND_FORGET))
                .send()
                .block();
    }

让我们更详细地检查一下此方法中的代码

rsocketRequester 上的 .route() 设置为 "fire-and-forget"。此路由名称与 RSocketController 中 fire-and-forget 方法上的 @MessageMapping 注解匹配。

一个新的 Message 实例为 .data() 方法提供数据。消息实例将其来源设置为 CLIENT 并将 FIRE_AND_FORGET 设置为其交互模式。

请注意,没有 .retrieveMono() 调用。相反,fire-and-forget 特定的 .send() 方法将消息发送到服务器,而 .block() 则订阅并等待完成。请记住,如果没有订阅,响应式代码中不会发生任何事情。

所有编码都完成了。现在,是时候测试它是否工作了。

步骤 3:构建并运行 RSocket 服务器

打开一个终端窗口,并移动到 rsocket-server 目录。使用 Maven 包装器启动服务器,如下所示

cd rsocket-server
./mvnw clean package spring-boot:run -DskipTests=true

服务器在 localhost 端口 7000 上启动。

有关如何在 Windows 10 上运行 Linux 终端的详细信息,请参阅Ubuntu 的此快速指南

步骤 4:构建并运行 RSocket 客户端

打开第二个终端窗口,并移动到 rsocket-client 目录。在那里,构建并运行客户端应用程序,如下所示

cd rsocket-client
./mvnw clean package spring-boot:run -DskipTests=true

客户端运行时,Spring Shell 会向您显示一个新的提示符

shell:>

您可以通过在提示符下键入 fire-and-forget 将 fire-and-forget 消息发送到服务器。

shell:>fire-and-forget
2020-02-03 14:54:14.028 INFO 2929 --- [ main] io.pivotal.rsocketclient.RSocketClient :
Fire-And-Forget. Sending one request. Expect no response (check server)...

客户端不会打印任何响应,但如果您切换到服务器的终端窗口,您会注意到 fire-and-forget 消息的接收已成功记录到控制台

2020-02-03 14:54:14.129 INFO 2061 --- [or-http-epoll-2] io.pivotal.rsocketserver.RSocketServer : Received fire-and-forget request: Message(origin=Client, interaction=Fire-And-Forget, index=0, created=1580741654)

步骤 5:清理

您可以通过在 shell:> 提示符下键入 exit 来停止 rsocket-client

shell:>exit

您可以通过在服务器的终端窗口中按 Ctrl-C 来停止 rsocket-server 进程。

工作原理

客户端的 .fireAndForget() 方法使用 RSocketRequester 在调用 block() 方法时向服务器发送单个 Message。block 方法实际上是“订阅并等待”的指令。

服务器上的 RSocketController 检查消息元数据中的 route,并正确地将消息传递给 .fireAndForget(Message request) 方法进行处理。客户端发送请求后,就可以继续执行其他操作。服务器收到请求后,也可以继续执行其他工作。它不需要向客户端发送响应。

总结

在这篇文章中,您学习了如何使用 Spring Boot 和 RSocket 快速构建 fire-and-forget 功能。有关 Spring 的 RSocket 集成和消息映射的更多信息,请查看Spring RSocket 文档。在下一篇文章中,我们将介绍请求-流消息传递。在那里见!

获取 Spring 新闻通讯

与 Spring 新闻通讯保持联系

订阅

领先一步

VMware 提供培训和认证,以加速您的进步。

了解更多

获取支持

Tanzu Spring 通过一个简单的订阅提供 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件。

了解更多

即将举行的活动

查看 Spring 社区中所有即将举行的活动。

查看全部