2016-08-04 58 views
13

允許假設具有延遲產生隨機數的量的控制器的這兩個場景:Spring 5 Web反應式編程 - HTTP客戶端的優點是什麼?

1)反應性彈簧5的反應性應用:

@GetMapping("/randomNumbers") 
public Flux<Double> getReactiveRandomNumbers() { 
    return generateRandomNumbers(10, 500); 
} 

/** 
* Non-blocking randon number generator 
* @param amount - # of numbers to generate 
* @param delay - delay between each number generation in milliseconds 
* @return 
*/ 
public Flux<Double> generateRandomNumbers(int amount, int delay){ 
    return Flux.range(1, amount) 
       .delayMillis(delay) 
       .map(i -> Math.random()); 
} 

2)Tradicional彈簧MVC與DeferredResult :

@GetMapping("/randomNumbers") 
public DeferredResult<Double[]> getReactiveRandomNumbers() { 
    DeferredResult<Double[]> dr = new DeferredResult<Double[]>(); 

    CompletableFuture.supplyAsync(() -> { 
     return generateRandomNumbers(10, 500); 
    }).whenCompleteAsync((p1, p2) -> { 
     dr.setResult(p1); 
    }); 

    return dr; 
} 

/** 
* Blocking randon number generator 
* @param amount - # of numbers to generate 
* @param delay - delay between each number generation in milliseconds 
* @return 
*/ 
public Double[] generateRandomNumbers(int amount, int delay){ 
    int generated = 0; 
    Double [] d = new Double[amount]; 
    while(generated < amount){ 
     try { 
      Thread.sleep(delay); 
     } catch (InterruptedException e) {} 
     d[generated] = Math.random(); 
     generated++; 
    } 
    return d; 
} 

從HTTP客戶端的角度(瀏覽器,AJAX請求)沒有兩種情況之間的任何差異。我的意思是客戶將等到所有結果發送完畢,並且在整個響應提交之前不會處理它們。

也就是說,儘管spring web反應讓我們認爲它會在生成時發回結果,但實際上它不會以這種方式發生,客戶將無法處理結果,直到所有的數字已經生成。

使客戶端完全反應的直接方法是使用WebSockets。

因此,除了很酷的東西(比如很好的語義,組成......),使用Spring Web Reactive考慮到瀏覽器HTTP請求沒有被動性,並且相當於使用傳統的DeferredResult ?

回答

15

有差異,所以讓我嘗試分解它。

對於DeferredResult<Double[]>返回值,顯然必須先將數組準備好,然後才能將值寫入響應。

Spring Web Reactive會在Flux<Double>可用時將每個值寫入。現在從瀏覽器的角度來看,你可能不會看到實際的差異,因爲它不會給你完整的JSON數組,直到它被完整接收。

這更多的是如何流入瀏覽器的問題?例如,如果您將"Accept: text/event-stream"添加爲請求標頭,則可以在瀏覽器中將每個雙精度元素作爲單個事件使用。所以服務器的能力,做到這一點,並有效地做到這一點。

+0

謝謝你清理它。關於流媒體,有兩個問題:1)除了從瀏覽器發送'text/event-stream'外,是否還需要將控制器中的返回類型從'Flux '更改爲'Flux '? 2)如果我們可以在控制器中返回'Flux ',傑克遜編組將會適用,不是嗎? – codependent

+1

沒問題。支持「Flux 」和「Flux 」。後者是創建僅包含數據的SseEvent的快捷方式。 –

相關問題