9

Klient okresowo wywołuje metodę asynchroniczną (long polling), przekazując mu wartość symbolu giełdowego, którą serwer wykorzystuje do zapytania bazy danych i zwrócenia obiektu z powrotem do klienta.Long Polling z Spring DeferredResult

Używam klasy Spring DeferredResult, ale nie jestem zaznajomiony z jej działaniem. Zwróć uwagę, w jaki sposób używam właściwości symbolu (wysłanej z klienta), aby wysłać zapytanie do bazy danych o nowe dane (patrz poniżej).

Być może istnieje lepsze podejście do długiego sondowania ze Spring?

Jak przekazać właściwość symbolu z metody deferredResult() do processQueues()?

private final Queue<DeferredResult<String>> responseBodyQueue = new ConcurrentLinkedQueue<>(); 

    @RequestMapping("/poll/{symbol}") 
    public @ResponseBody DeferredResult<String> deferredResult(@PathVariable("symbol") String symbol) { 
     DeferredResult<String> result = new DeferredResult<String>(); 
     this.responseBodyQueue.add(result); 
     return result; 
    } 

    @Scheduled(fixedRate=2000) 
    public void processQueues() { 
     for (DeferredResult<String> result : this.responseBodyQueue) { 
      Quote quote = jpaStockQuoteRepository.findStock(symbol); 
      result.setResult(quote); 
      this.responseBodyQueue.remove(result); 
     } 
    } 
+0

Czy chcesz poczekać na wynik i odesłać go do klienta? Jeśli nie, po prostu zwróć wartość null. Jeśli tak, prawdopodobnie lepiej użyj Future, ponieważ możesz później wyodrębnić wynik z wątku przesyłania. – Jan

Odpowiedz

7

DeferredResult wiosną 4.1.7:

podklasy mogą rozszerzyć tę klasę łatwo skojarzyć dodatkowe dane lub zachowań z DeferredResult. Na przykład można skojarzyć użytkownika używanego do utworzenia DeferredResult, rozszerzając klasę i dodając dodatkową właściwość dla użytkownika. W ten sposób użytkownik będzie mógł łatwo uzyskać dostęp później, bez potrzeby używania struktury danych do wykonania mapowania.

Można przedłużyć DeferredResult i zapisać parametr symbol jako pole klasy.

static class DeferredQuote extends DeferredResult<Quote> { 
    private final String symbol; 
    public DeferredQuote(String symbol) { 
     this.symbol = symbol; 
    } 
} 

@RequestMapping("/poll/{symbol}") 
public @ResponseBody DeferredQuote deferredResult(@PathVariable("symbol") String symbol) { 
    DeferredQuote result = new DeferredQuote(symbol); 
    responseBodyQueue.add(result); 
    return result; 
} 

@Scheduled(fixedRate = 2000) 
public void processQueues() { 
    for (DeferredQuote result : responseBodyQueue) { 
     Quote quote = jpaStockQuoteRepository.findStock(result.symbol); 
     result.setResult(quote); 
     responseBodyQueue.remove(result); 
    } 
}