Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用Reactor-Netty-HttpClient,如何将客户端配置为使用Flux发布服务器向服务器发送多个项目?_Java_Project Reactor_Reactor Netty - Fatal编程技术网

Java 使用Reactor-Netty-HttpClient,如何将客户端配置为使用Flux发布服务器向服务器发送多个项目?

Java 使用Reactor-Netty-HttpClient,如何将客户端配置为使用Flux发布服务器向服务器发送多个项目?,java,project-reactor,reactor-netty,Java,Project Reactor,Reactor Netty,更具体的问题是为什么Flux.fromIterable()不能与Reactor Netty HttpClient一起工作? 这个简单的例子很好用。所有10项都由Flux publisher发出: public class ConcurrentLinkedQueueFluxTest { public static final void main(String[] args) { List<Integer> aList = Arrays.asList(1, 2

更具体的问题是为什么Flux.fromIterable()不能与Reactor Netty HttpClient一起工作? 这个简单的例子很好用。所有10项都由Flux publisher发出:

public class ConcurrentLinkedQueueFluxTest {

    public static final void main(String[] args) {

        List<Integer> aList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        ConcurrentLinkedQueue<Integer> clq = new ConcurrentLinkedQueue<>();
        aList.stream().forEach(i -> clq.add(i));

        Flux.fromIterable(clq)
                .subscribe(new ReactiveSubscriber<Integer>());
    }
}
订户定义为:



class ElectionTransactionSubscriber extends BaseSubscriber<byte[]> {

    private static final Logger log = LoggerFactory.getLogger(ElectionTransactionSubscriber.class);

    private Subscription subscription;

    @Override
    public void hookOnSubscribe(Subscription s) {
        log.debug("In hookOnSubscribe");
        this.subscription = s;
        subscription.request(1);
    }

    @Override
    public void hookOnNext(byte[] response) {
        log.info("In hookOnNext");
        subscription.request(1);
    }

    @Override
    public void hookOnError(Throwable t) {
        log.error(t.getLocalizedMessage());
    }

    @Override
    public void hookOnComplete() {
        log.debug("In hookOnComplete");
        subscription.cancel();
    }
}

当客户机运行时,队列中有5个项目,但只有一个项目被发送到服务器,如日志所示。在订阅服务器中,仅在从Flux发布服务器发送1项后调用hookOnComplete()方法


2020-12-01 12:03:56,442 DEBUG [main] com.dd.vbc.business.services.client.requests.ElectionTransactionRequest: Queue size: 5

2020-12-01 12:03:56,539 DEBUG [main] com.dd.vbc.business.services.client.requests.ElectionTransactionSubscriber: In hookOnSubscribe

2020-12-01 12:03:56,746 INFO  [reactor-http-epoll-1] com.dd.vbc.business.services.client.requests.ElectionTransactionSubscriber: In hookOnNext

2020-12-01 12:03:56,746 DEBUG [reactor-http-epoll-1] com.dd.vbc.business.services.client.requests.ElectionTransactionSubscriber: In hookOnComplete


缓冲可能是最容易使用的。它发出缓冲区(它们是集合) — 默认情况下,列表)。因此,在您的情况下,订阅者将收到一个列表

StepVerifier.create(
    Flux.range(1, 10)
        .buffer(5, 3) //overlapping buffers
    )
        .expectNext(Arrays.asList(1, 2, 3, 4, 5))
        .expectNext(Arrays.asList(4, 5, 6, 7, 8))
        .expectNext(Arrays.asList(7, 8, 9, 10))
        .expectNext(Collections.singletonList(10))
        .verifyComplete();
=========================

这直接来自反应堆堆芯的文件:

三种配料

当您有很多元素并且希望将它们分成批时,Reactor中有三种广泛的解决方案:分组、窗口和缓冲。这三者在概念上是相近的,因为它们将通量重新分配为聚合。分组和窗口创建流量,同时将聚合缓冲到集合中。 流量分组

分组是将源流量拆分为多个批次的行为,每个批次都匹配一个键

关联的运算符是groupBy

每个组都表示为GroupedFlux,它允许您通过调用其key()方法检索密钥

这些小组的内容没有必要的连续性。一旦一个源元素产生一个新的键,该键的组就会被打开,与该键匹配的元素最终会进入该组(可以同时打开多个组)

这意味着各小组:

Are always disjoint (a source element belongs to one and only one group).

Can contain elements from different places in the original sequence.

Are never empty.
以下示例根据值是偶数还是奇数对值进行分组:

StepVerifier.create(
    Flux.just(1, 3, 5, 2, 4, 6, 11, 12, 13)
        .groupBy(i -> i % 2 == 0 ? "even" : "odd")
        .concatMap(g -> g.defaultIfEmpty(-1) //if empty groups, show them
                .map(String::valueOf) //map to string
                .startWith(g.key())) //start with the group's key
    )
    .expectNext("odd", "1", "3", "5", "11", "13")
    .expectNext("even", "2", "4", "6", "12")
    .verifyComplete();
警告 分组最适合于组数从中等到较低的情况。还必须强制使用这些组(例如通过flatMap),以便groupBy继续从上游获取数据并为更多组提供数据。有时,这两个约束相乘并导致挂起,例如当基数较高且使用组的flatMap的并发性太低时。 用焊剂开窗

窗口化是根据大小、时间、边界定义谓词或边界定义发布者的标准将源流量拆分为窗口的行为

关联的运算符是window、windowTimeout、windowUntil、windowWhile和windowWhen

与groupBy相反,groupBy根据传入的键随机重叠,窗口(大部分时间)是按顺序打开的

不过,有些变体仍然可以重叠。例如,在window(int maxSize,int skip)中,maxSize参数是窗口关闭后的元素数,skip参数是源中打开新窗口后的元素数。因此,如果maxSize>skip,则会在前一个窗口关闭之前打开一个新窗口,两个窗口重叠

以下示例显示重叠窗口:

StepVerifier.create(
    Flux.range(1, 10)
        .window(5, 3) //overlapping windows
        .concatMap(g -> g.defaultIfEmpty(-1)) //show empty windows as -1
    )
        .expectNext(1, 2, 3, 4, 5)
        .expectNext(4, 5, 6, 7, 8)
        .expectNext(7, 8, 9, 10)
        .expectNext(10)
        .verifyComplete();
注 使用反向配置(maxSize 在通过WindowUtil和windowWhile进行基于谓词的窗口化的情况下,后续源元素与谓词不匹配也会导致空窗口,如下例所示:

StepVerifier.create(
    Flux.just(1, 3, 5, 2, 4, 6, 11, 12, 13)
        .windowWhile(i -> i % 2 == 0)
        .concatMap(g -> g.defaultIfEmpty(-1))
    )
        .expectNext(-1, -1, -1) //respectively triggered by odd 1 3 5
        .expectNext(2, 4, 6) // triggered by 11
        .expectNext(12) // triggered by 13
        // however, no empty completion window is emitted (would contain extra matching elements)
        .verifyComplete();
通量缓冲

缓冲与窗口类似,但有以下扭曲:它不发射窗口(每个窗口都是通量),而是发射缓冲区(每个窗口都是集合) — 默认情况下,列表)

缓冲的运算符与窗口的运算符相同:buffer、bufferTimeout、bufferUntil、bufferWhile和bufferWhen

当相应的windowing操作符打开一个窗口时,缓冲操作符创建一个新集合并开始向其中添加元素。当窗口关闭时,缓冲操作符发出收集

缓冲还会导致源元素丢失或缓冲区重叠,如下例所示:

StepVerifier.create(
    Flux.range(1, 10)
        .buffer(5, 3) //overlapping buffers
    )
        .expectNext(Arrays.asList(1, 2, 3, 4, 5))
        .expectNext(Arrays.asList(4, 5, 6, 7, 8))
        .expectNext(Arrays.asList(7, 8, 9, 10))
        .expectNext(Collections.singletonList(10))
        .verifyComplete();
StepVerifier.create(
    Flux.just(1, 3, 5, 2, 4, 6, 11, 12, 13)
        .bufferWhile(i -> i % 2 == 0)
    )
    .expectNext(Arrays.asList(2, 4, 6)) // triggered by 11
    .expectNext(Collections.singletonList(12)) // triggered by 13
    .verifyComplete();
与窗口中不同,BufferTill和bufferWhile不会发出空缓冲区,如下例所示:

StepVerifier.create(
    Flux.range(1, 10)
        .buffer(5, 3) //overlapping buffers
    )
        .expectNext(Arrays.asList(1, 2, 3, 4, 5))
        .expectNext(Arrays.asList(4, 5, 6, 7, 8))
        .expectNext(Arrays.asList(7, 8, 9, 10))
        .expectNext(Collections.singletonList(10))
        .verifyComplete();
StepVerifier.create(
    Flux.just(1, 3, 5, 2, 4, 6, 11, 12, 13)
        .bufferWhile(i -> i % 2 == 0)
    )
    .expectNext(Arrays.asList(2, 4, 6)) // triggered by 11
    .expectNext(Collections.singletonList(12)) // triggered by 13
    .verifyComplete();

缓冲可能是最容易使用的。它发出缓冲区(它们是集合) — 默认情况下,列表)。因此,在您的情况下,订阅者将收到一个列表

StepVerifier.create(
    Flux.range(1, 10)
        .buffer(5, 3) //overlapping buffers
    )
        .expectNext(Arrays.asList(1, 2, 3, 4, 5))
        .expectNext(Arrays.asList(4, 5, 6, 7, 8))
        .expectNext(Arrays.asList(7, 8, 9, 10))
        .expectNext(Collections.singletonList(10))
        .verifyComplete();
=========================

这直接来自反应堆堆芯的文件:

三种配料

当您有很多元素并且希望将它们分成批时,Reactor中有三种广泛的解决方案:分组、窗口和缓冲。这三者在概念上是相近的,因为它们将通量重新分配为聚合。分组和窗口创建流量,同时将聚合缓冲到集合中。 流量分组

分组是将源流量拆分为多个批次的行为,每个批次都匹配一个键

关联的运算符是groupBy

每个组都表示为GroupedFlux,它允许您通过调用其key()方法检索密钥

这些小组的内容没有必要的连续性。一旦一个源元素产生一个新的键,该键的组就会被打开,与该键匹配的元素最终会进入该组(可以同时打开多个组)

这意味着各小组:

Are always disjoint (a source element belongs to one and only one group).

Can contain elements from different places in the original sequence.

Are never empty.
以下示例根据值是偶数还是奇数对值进行分组:

StepVerifier.create(
    Flux.just(1, 3, 5, 2, 4, 6, 11, 12, 13)
        .groupBy(i -> i % 2 == 0 ? "even" : "odd")
        .concatMap(g -> g.defaultIfEmpty(-1) //if empty groups, show them
                .map(String::valueOf) //map to string
                .startWith(g.key())) //start with the group's key
    )
    .expectNext("odd", "1", "3", "5", "11", "13")
    .expectNext("even", "2", "4", "6", "12")
    .verifyComplete();
警告 分组最适合于组数从中等到较低的情况。还必须强制使用这些组(例如通过flatMap),以便groupBy继续从上游获取数据并为更多组提供数据。有时,这两个约束相乘并导致挂起,例如当基数较高且使用组的flatMap的并发性太低时。 通量窗口化