领先一步
VMware 提供培训和认证,以加速您的进步。
了解更多时间:大约15分钟。
一些阅读本文的开发者可能已经使用 HTTP 多年了。他们中的大多数人也知道,如果您想将 HTTP 与其他消息传递模型(例如 fire-and-forget)一起使用,有时您必须使用巧妙的解决方法例如 Stackoverflow 上的这个。这是因为 HTTP 是一种请求-响应协议。它要求发送请求并接收响应。它没有关于无需任何形式响应的单向消息的概念。
RSocket 采用了不同的方法。RSocket 在 TCP 和 WebSockets 等传输层之上定义了一个新的协议层。这个新协议为开发者提供了更大的选择,并内置支持四种不同的交互模型
在之前的文章中,您已经学习了如何使用 RSocket 进行请求/响应。在这篇文章中,您将学习如何向代码中添加 fire-and-forget 消息传递。让我们开始吧!
如果您没有阅读之前关于使用 RSocket 进行服务器端和客户端请求-响应消息传递的文章,现在是您的机会!代码示例可在GitHub上找到。
您会记得之前在 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 文档中,方法签名规则位于消息映射部分。
您在按照上一篇文章操作时,在 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()
则订阅并等待完成。请记住,如果没有订阅,响应式代码中不会发生任何事情。
所有编码都完成了。现在,是时候测试它是否工作了。
打开一个终端窗口,并移动到 rsocket-server
目录。使用 Maven 包装器启动服务器,如下所示
cd rsocket-server
./mvnw clean package spring-boot:run -DskipTests=true
服务器在 localhost
端口 7000
上启动。
有关如何在 Windows 10 上运行 Linux 终端的详细信息,请参阅Ubuntu 的此快速指南。
打开第二个终端窗口,并移动到 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)
您可以通过在 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 文档。在下一篇文章中,我们将介绍请求-流消息传递。在那里见!