Reactor Netty-如何使用延迟通量发送

时间:2019-03-06 03:53:08

标签: project-reactor reactor-netty

在Reactor Netty中,当通过out.send(publisher)将数据发送到TCP通道时,人们希望任何发布者都可以工作。但是,如果我们使用延迟元素而不是简单的立即Flux来代替它,那么它将停止正常工作。 例如,如果我们使用此Hello World TCP回显服务器,它将按预期工作:

import reactor.core.publisher.Flux;
import reactor.netty.DisposableServer;
import reactor.netty.tcp.TcpServer;

import java.time.Duration;

public class Reactor1 {
    public static void main(String[] args) throws Exception {
        DisposableServer server = TcpServer.create()
            .port(3344)
            .handle((in, out) -> in
                .receive()
                .asString()
                .flatMap(s ->
                    out.sendString(Flux.just(s.toUpperCase()))
                ))
            .bind()
            .block();
        server.channel().closeFuture().sync();
    }
}

但是,如果我们将out.sendString更改为

out.sendString(Flux.just(s.toUpperCase()).delayElements(Duration.ofSeconds(1)))

然后,我们期望对于每个接收到的项目,将产生一秒钟的延迟输出。

但是,服务器的行为方式是,如果服务器在间隔时间内接收到多个项目,则只会为第一个项目产生输出。例如,下面我们在第一秒钟内输入aabb,但只有AA被生成为输出(在一秒钟后):

$ nc localhost 3344
aa
bb
AA <after one second>

然后,如果以后再键入其他行,则将获得输出(一秒钟后),但输出来自先前的输入:

cc
BB <after one second>

有什么想法可以使send()在延迟的Flux下正常工作吗?

2 个答案:

答案 0 :(得分:1)

我认为您不应该为out.sendString(...)重新创建发布者 这有效:

DisposableServer server = TcpServer.create()
        .port(3344)
        .handle((in, out) -> out
                .options(NettyPipeline.SendOptions::flushOnEach)
                .sendString(in.receive()
                        .asString()
                        .map(String::toUpperCase)
                        .delayElements(Duration.ofSeconds(1))))
        .bind()
        .block();
server.channel().closeFuture().sync();

答案 1 :(得分:1)

尝试使用concatMap。这有效:

DisposableServer server = TcpServer.create()
        .port(3344)
        .handle((in, out) -> in
                .receive()
                .asString()
                .concatMap(s ->
                        out.sendString(Flux.just(s.toUpperCase())
                                           .delayElements(Duration.ofSeconds(1)))
                ))
            .bind()
            .block();
server.channel().closeFuture().sync();

延迟传入流量

DisposableServer server = TcpServer.create()
        .port(3344)
        .handle((in, out) -> in
                .receive()
                .asString()
                .timestamp()
                .delayElements(Duration.ofSeconds(1))
                .concatMap(tuple2 ->
                        out.sendString(
                                Flux.just(tuple2.getT2().toUpperCase() +
                                        " " +
                                        (System.currentTimeMillis() - tuple2.getT1())
                                ))
                ))
        .bind()
        .block();