2016-08-04 1 views
13

Давайте предположим, эти два сценария контроллера, который генерирует некоторое количество случайных чисел с задержкой:Spring 5 Web Reactive Programming - Каковы преимущества с точки зрения 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 Spring 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 запрос) не существует любая разница между обоими сценариями. Я имею в виду, что клиент будет ждать, пока все результаты будут отправлены, и не будет обрабатывать их до тех пор, пока не будет совершен весь ответ.

То есть, хотя весенняя паутина реагирует, мы думаем, что она посылает результаты назад, когда они производятся, на самом деле этого не происходит, и клиент не сможет обработать результаты до тех пор, пока все числа были сгенерированы.

Простым способом сделать клиент полностью реактивным является использование 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 только с данными. –