Reactor-netty TCPClient无法接收响应

时间:2018-10-29 11:07:39

标签: project-reactor reactor-netty

我正在尝试对缺乏文档的最新反应堆网络版本进行一些项目前的经验;我正在使用0.8.0.M3版本。

我已经使用此tcp服务器开发了一个简单的spring boot应用程序,该应用程序可以正确启动并可以正常工作:

@PostConstruct
public void startServer() throws InterruptedException {
    TcpServer.create().
              host("localhost").
              port(1235).
              handle((in, out) -> {

                    Flux<String> fluxString = in.receive().asString().log().
                        map(text -> {
                            return "Hi server have received "+text;});  
                        return out.sendString(fluxString).then();

              } 
              ).
              wiretap().bindNow();
}

如果我尝试使用客户端进行测试,则交互似乎正确,但是我无法收到任何答复:

int counter = 10;
    CountDownLatch latch = new CountDownLatch(counter);
    Flux<String> input = Flux.range(0, counter).map(i->""+i);

    TcpClient.create().
      host("localhost").
      port(1235).
      handle((in, out) -> {

          in.receive().subscribe(receiv -> {System.out.println(receiv);latch.countDown();});
                return out.sendString(input).neverComplete();

      } 
      ).
      wiretap().connectNow();
    System.out.println("waiting closure");
    boolean result = latch.await(5, TimeUnit.SECONDS);

查看窃听日志记录,似乎客户端分别将每个int作为字符串发送,并且服务器仅接收到一个聚合字符串“ 0123456789”,并且仅发送一个响应。客户端什么也没收到,锁存器也不减1并保持10(我希望至少收到一个汇总响应)。

有人可以解释客户端的问题以及如何由服务器分别接收每个整数吗?

Thx G

1 个答案:

答案 0 :(得分:0)

您可能需要解决一些问题。 我想说的是,这对于学习来说有点复杂。

对于服务器:

    TcpServer.create()
            .host("localhost")
            .port(1235)
            .doOnConnection(c ->
                    //The origin input are 0,1,2,3,4,5,6,7,8,9.
                    //So you need a decoder split every 1 byte as a ByteBuf.
                    c.addHandler(
                            "1ByteStringDecoder",
                            new ByteToMessageDecoder() {
                                @Override
                                protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
                                    out.add(in.readBytes(1));
                                }
                            }
                    )
            )
            .handle((in, out) -> {
                        Flux<String> fluxString = in.receive()
                                .asString()
                                .log()
                                .map(text -> {
                                    return "Hi server have received " + text;
                                });
                        //Since the output is quite small, you need flush it
                        return out.options(o -> o.flushOnEach())
                                .sendString(fluxString)
                                .neverComplete();

                    }
            )
            .wiretap()
            .bindNow();

对于客户:

    int counter = 10;
    CountDownLatch latch = new CountDownLatch(counter);
    startServer();
    Flux<String> input = Flux.range(0, counter)
            .map(i -> "" + i);

    TcpClient.create()
            .host("localhost")
            .port(1235)
            .doOnConnected(c ->
                    c.addHandler(
                            //The covert input are "Hi server have received " + (0,1,2,3,4,5,6,7,8,9).
                            //So you need a decoder split every 25 byte as a ByteBuf.
                            "25ByteStringDecoder",
                            new ByteToMessageDecoder() {
                                @Override
                                protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
                                    out.add(in.readBytes(25));
                                }
                            }
                    )
            )
            .handle((in, out) -> {
                        in.receive()
                                .asString()//You need convert ByteBuf to String.
                                .subscribe(receiv -> {
                                    System.out.println(receiv);
                                    latch.countDown();
                                });

                        out.options(o -> o.flushOnEach())
                                .sendString(input)
                                .then()
                                .subscribe(); //You need to ask your client to send the data by subscribe
                        return Mono.never();

                    }
            )
            .wiretap()
            .connectNow();
    System.out.println("waiting closure");
    boolean result = latch.await(5, TimeUnit.SECONDS);