14.2.3 发送 即发即忘
消息
想象一下,您在一艘刚刚受到敌舰攻击的星际飞船上。您发出全舰范围的“红色警报”,以便所有人员都处于战斗模式。您不需要等待飞船计算机的响应来确认警报发送状态。在这种情况下,您也没有时间等待阅读任何回应。您设置了警报,然后继续执行更多关键操作。
这是一个 即发即忘
的例子。考虑到目前的情况,虽然您可能不会忘记您处于红色警戒状态。对您来说,应对这场战争危机比处理警报响应显然更重要。
为了模拟这个场景,我们将创建一个 RSocket 服务器,它处理警报状态,但不进行任何响应。首先,我们需要定义一个请求数据类。像清单 14.6 中的 Alert 类。
清单 14.6 表示警报的模型类。
package rsocket;
import java.time.Instant;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class Alert {
private Level level;
private String orderedBy;
private Instant orderedAt;
public static enum Level {
YELLOW, ORANGE, RED, BLACK
}
}
警报对象捕获警报级别、警报的请求者以及警报发出时的时间戳(定义为 Instant 类型)。同样,为了保持代码简短,我们使用 Lombok 自动生成构造和访问方法。
在服务器端,清单 14.7 中的 AlertController 类将处理警报消息。
清单 14.7 处理警报更新的 RSocket 控制器。
package rsocket;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.stereotype.Controller;
import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Mono;
@Controller
@Slf4j
public class AlertController {
@MessageMapping("alert")
public Mono<Void> setAlert(Mono<Alert> alertMono) {
return alertMono
.doOnNext(alert -> {
log.info(alert.getLevel() + " alert"
+ " ordered by " + alert.getOrderedBy()
+ " at " + alert.getOrderedAt());
})
.thenEmpty(Mono.empty());
}
}
setAlert()
方法处理“alert”路由上的消息。为保持简单(尽管在实际作战情况下毫无用处),它只记录警报。但重要的是返回一个Mono<Void>
,表示没有响应。因此此处理方法支持 即发即忘
模型。
在客户端中,代码与 请求/响应
或 请求/流
的代码差别不大:
RSocketRequester tcp = requesterBuilder.tcp("localhost", 7000);
tcp
.route("alert")
.data(new Alert(
Alert.Level.RED, "Craig", Instant.now()))
.send()
.subscribe();
log.info("Alert sent");
但是,请注意,客户端没有调用 retrieveMono()
或 retrieveFlux()
,而只是调用 send()
,不需要响应。
现在,让我们看看如何处理 通道
通信模型,在该模型中,服务器和客户端相互发送多条消息。