2013-05-02 22 views
7

Dokumentacja states, że spray jest w stanie obsłużyć porwane odpowiedzi, ale nie mogę znaleźć żadnego przykładu na początek. Tam jest mój naiwny realizacja:Chunked response handling z opcją sprayu

object Main extends App { 

    implicit val system = ActorSystem() 
    import system.dispatcher 
    val log = Logging(system, getClass) 
    val ioBridge = IOExtension(system).ioBridge() 
    val httpClient = system.actorOf(Props(new HttpClient(ioBridge))) 

    val conduit = system.actorOf(
    props = Props(new HttpConduit(httpClient, "localhost", 3000)), 
    name = "http-conduit" 
) 

    val pipeline = HttpConduit.sendReceive(conduit) 
    val response = pipeline(
    HttpRequest(
     method = GET, 
     uri = "/output.cgi.xml" 
    ) 
) 

    response onComplete { 
    case Success(a) => 
     log.info("Success: " + a) 
     system.shutdown() 

    case Failure(error) => 
     log.error(error, "Failure") 
     system.shutdown() 
    } 

} 

mam ustawione response-chunk-aggregation-limit = 0, nadal nic się nie dzieje.

Czy możesz podać mi przykład czytania fragmentów odpowiedzi?

Aktualizacja

mam przepisany mój kod w następujący sposób:

object Main extends App { 

    implicit val system = ActorSystem() 
    import system.dispatcher 
    val log = Logging(system, getClass) 
    val ioBridge = IOExtension(system).ioBridge() 
    val httpClient = system.actorOf(Props(new HttpClient(ioBridge))) 

    actor(new Act { 
    httpClient ! Connect(new InetSocketAddress("localhost", 3000)) 

    become { 
     case Connected(_) => 
     log.info("connected") 
     sender ! HttpRequest(GET, "/output.cgi.xml") 
     case Closed(handle, reason) => 
     log.info("closed: " + reason) 
     system.shutdown() 
     case ChunkedResponseStart(res) => 
     log.info("start: " + res) 
     case MessageChunk(body, ext) => 
     log.info("chunk: " + body) 
     case ChunkedMessageEnd(ext, trailer) => 
     log.info("end: " + ext) 
     case m => 
     log.info("received unknown message " + m) 
     system.shutdown() 
    } 
    }) 

} 

a teraz jestem otrzymaniu closed: ProtocolError(Aggregated response entity greater than configured limit of 1048576 bytes) tuż po nawiązaniu połączenia.

Moja application.conf

spray.can { 
    client { 
    response-chunk-aggregation-limit = 0 
    } 
} 
+0

WDYM z "nic się jeszcze nie dzieje"? Mówisz, że nigdy nie uzyskasz wyniku zapytania? – jrudolph

+0

Którą wersję sprayu używasz? – jrudolph

+0

Używam 1.1-M7. Chodzi mi o to, że nie wiem, jak poradzić sobie z reakcją w zgrabny sposób. Obecnie 'onComplete' otrzymuje zagregowaną odpowiedź. – lambdas

Odpowiedz

9

Jak zauważyliście, HttpConduit działa tylko na zagregowanych odpowiedzi. Musisz spaść do warstwy puszki z aerozolem, aby poradzić sobie z pojedynczymi porcjami.

Niestety, obecnie nie mamy żadnego przykładu pokazującego, jak to zrobić. Z grubsza, działa następująco (w M7):

  1. Set response-chunk-aggregation-limit = 0
  2. Wyślij Connect do httpclient aktora i czekać na Connected
  3. Wyślij HttpRequest do nadawcy wiadomości Connected
  4. Uchwyt pakietowego komunikaty żądań ChunkedResponseStart, MessageChunk i ChunkedResponseEnd.

Więcej informacji można znaleźć http://spray.io/documentation/spray-can/http-client/#chunked-responses

w przeciwieństwie do korzystania HttpConduit oznacza to trzeba zarządzać siebie połączeń (jeśli to dlaczego uzywasz HttpConduit). W ostatnich nocach było to łatwiejsze, ponieważ nowy HttpClient automatycznie obsługuje pule połączeń, itp. Jeśli potrzebujesz, możesz również uzyskać więcej informacji na liście mailingowej.

+0

Czy to oznacza, że ​​mój klient otrzyma każdą wystarczająco dużą odpowiedź w postaci fragmentów lub jakieś specjalne wsparcie po stronie serwera? – lambdas

+0

Dostajesz obecnie porcje tylko wtedy, gdy serwer wysyła porcje. Dodałem bilet do obsługi API fragmentów, nawet jeśli faktyczna odpowiedź nie jest porwana przez przewód: https://github.com/spray/spray/issues/281 – jrudolph

+0

Fajnie, dziękuję! – lambdas