我有以下RSocket服务器
@Log4j2
public class NativeRsocketServerFnF {
public static void main(String[] args) {
RSocketFactory.receive()
.frameDecoder(ZERO_COPY)
.errorConsumer(log::error)
.acceptor((setup, clientHandleRsocket) -> {
return Mono.just(
new AbstractRSocket() {
@Override
public Mono<Void> fireAndForget(Payload payload) {
CharSequence message = payload.data().readCharSequence(payload.data().readableBytes(), forName("UTF-8"));
payload.release();
log.info("> from client: {}", message);
return Mono.empty();
}
}
);
})
.transport(TcpServerTransport.create(8000))
.start()
.block()
.onClose()
.block();
}
}
和以下RSocket客户端
@Log4j2
public class NativeRsocketClientFnF {
public static void main(String[] args) {
RSocketFactory.connect()
.frameDecoder(ZERO_COPY)
.errorConsumer(log::error)
.transport(TcpClientTransport.create(8000))
.start()
.flatMap(rSocket -> rSocket.fireAndForget(DefaultPayload.create("ping")))
.block();
}
}
如您所见,我正在尝试将“ ping”作为有效载荷数据从客户端发送到服务器
第一次启动服务器并启动客户端时,我看到> from client: ping
如果再次重新启动客户端,则服务器上看不到任何消息。断点甚至没有在服务器上命中
我的理解是,Fire和Forget只是简单地发送数据,而不必费心等待并查看服务器是否成功处理了数据,但是在我的情况下,服务器本身在后续的客户端运行中未接收到数据(和新客户一样好
有什么我想念的吗?
我正在使用1.0.0-RC5
和rsocket-core
的{{1}}版
操作系统:Ubuntu 16.04
答案 0 :(得分:2)
您对“发射后忘记”模式的理解是正确的。
问题是io.rsocket.RSocketRequester#fireAndForget
已成功完成,然后才将数据发送到网络。当您阻止它并退出客户端应用程序时,连接将关闭。
请参见io.rsocket.RSocketRequester#handleFireAndForget
return emptyUnicastMono()
.doOnSubscribe(
new OnceConsumer<Subscription>() {
@Override
public void acceptOnce(@Nonnull Subscription subscription) {
ByteBuf requestFrame =
RequestFireAndForgetFrameFlyweight.encode(
allocator,
streamId,
false,
payload.hasMetadata() ? payload.sliceMetadata().retain() : null,
payload.sliceData().retain());
payload.release();
sendProcessor.onNext(requestFrame);
}
});
sendProcessor
是中间磁通处理器。用于实际连接,可能会延迟向网络发送请求帧。
出于测试目的,您可以在客户端的.then(Mono.delay(Duration.ofMillis(100)))
调用之前添加.block()
。我认为大多数真实的应用程序在调用fireAndForget之后不会立即退出。