服务器未在RSocket Fire and Forget情况下接收数据

时间:2019-10-21 22:41:48

标签: rsocket rsocket-java

我有以下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-RC5rsocket-core的{​​{1}}版

操作系统:Ubuntu 16.04

1 个答案:

答案 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之后不会立即退出。