2016-08-04 9 views
13

Pozwala przypuszczać, te dwa scenariusze sterownika, który wytwarza ilość liczb losowych z opóźnieniem:Spring 5 Web Reactive Programming - Jakie są zalety z punktu widzenia klienta HTTP?

1) Reaktywne sprężyny 5 reaktywne zgłoszenia:

@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 Wiosna MVC z 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; 
} 

z punktu widzenia klienta HTTP (przeglądarka, AJAX request) nie ma jakakolwiek różnica między oboma scenariuszami. Chodzi mi o to, że klient będzie czekał, aż wszystkie wyniki zostaną wysłane i nie przetworzy ich, dopóki cała odpowiedź nie zostanie zatwierdzona.

Oznacza to, że chociaż reaktywna sieć wiosenna powoduje, że myślimy, że wysyła wyniki z powrotem w trakcie ich produkcji, w rzeczywistości tak się nie dzieje, a klient nie będzie w stanie przetworzyć wyników do wszystkie liczby zostały wygenerowane.

Prostym sposobem na pełną reaktywność klienta byłoby korzystanie z WebSockets.

Tak więc, oprócz fajnych rzeczy (takich jak ładna semantyka, kompozycja ...), , jaki jest sens używania Spring Web Reactive, biorąc pod uwagę, że żądania HTTP przeglądarki nie są reaktywne i są równoważne użyciu tradycyjnego DeferredResult ?

Odpowiedz

15

Istnieją różnice, więc pozwól, że spróbuję to zepsuć.

Dla zwracanej wartości wyraźnie tablica musi zostać przygotowana najpierw, zanim wartość może zostać zapisana w odpowiedzi.

Spring Web Reactive zapisuje każdą indywidualną wartość z Flux<Double>, gdy stanie się dostępna. Teraz z perspektywy przeglądarki możesz nie zauważyć faktycznej różnicy, ponieważ nie da ci pełnej tablicy JSON, dopóki nie zostanie odebrana w całości.

To jest bardziej pytanie, jak przesłać strumieniowo do przeglądarki? Na przykład, jeśli dodasz "Accept: text/event-stream" jako nagłówek żądania, możesz następnie pochłonąć każde podwójne jako pojedyncze zdarzenie w przeglądarce. Więc zdolność serwera do robienia tego i robienia tego sprawnie jest.

+0

Dziękuję za oczyszczenie. Jeśli chodzi o przesyłanie strumieniowe, dwa pytania: 1) Czy oprócz wysłania 'text/event-stream' z przeglądarki, konieczna jest również zmiana typu zwracania w kontrolerze z" Flux "na" Flux "? 2) W przypadku, gdybyśmy mogli powrócić do kontrolera "Flux ", Jackson miałby zastosowanie do rozrządzeń Jackson'a, czyż nie? – codependent

+1

Bez problemu. Zarówno 'Flux ' jak i 'Flux ' są obsługiwane. Ten drugi jest skrótem do tworzenia SseEvent z tylko danymi. –

Powiązane problemy