2015-03-04 9 views
6

Sto lavorando allo sviluppo di un'app mobile incentrata sul caricamento di più foto su un web API. Sto usando Xamarin.Forms e System.Net.Http.HttpClient e Clumsy per simulare condizioni di rete scadenti (ritardo, pacchetti scartati, pacchetti out-of-order). L'app è stata originariamente scritta con Titanium e ha funzionato correttamente per la maggior parte degli utenti, ma alcuni utenti su reti mobili scadenti hanno riscontrato errori frequenti. Andando avanti stiamo eseguendo il porting su Xamarin e cercando di soddisfare gli utenti con scarsa connettività.Come gestire il caricamento di file HttpClient.PostAsync in condizioni di rete scadenti?

using (var httpClient = CreateClient()) 
     { 
      httpClient.Timeout = TimeSpan.FromMinutes(5); 
      using (var formData = new MultipartFormDataContent()) 
      { 
       // add required fields via formData.Add() ... 

       var httpContent = new ByteArrayContent(imageData); 
       formData.Add(httpContent, "file", Guid.NewGuid() + ".jpg"); 

       try 
       { 
        var response = await httpClient.PostAsync("fileupload", formData).ConfigureAwait(false); 

        if (response.IsSuccessStatusCode) 
        { 
         responseObject = await ResponseMessageToResponseModel(response).ConfigureAwait(false); 
        } 
       } 
       catch (HttpRequestException ex) 
       { 
        Debug.WriteLine("HttpRequestException"); 
       } 
       catch (TaskCanceledException ex) 
       { 
        Debug.WriteLine("TaskCanceledException"); 
       } 
      } 
     } 

Quello che sto trovando è che tutto funziona come previsto in condizioni normali, comunque; attivando Clumsy con "lag, drop, out-of-order" e tentando il caricamento, PostAsync() non termina mai e alla fine termina con TaskCanceledException. La cosa strana è che il file finisce sul server ... quindi i dati POST apparentemente sono andati bene.

Suppongo che i pacchetti rilasciati nella risposta dal server significhi che HttpClient non riceve mai una risposta adeguata e continua ad attendere fino a quando non scade.

Per arrivare al punto, mi chiedo se qualcuno ha qualche idea su come rendere questo processo il più possibile a prova di proiettile. Solo catturare il timeout e riprovare non funziona molto bene se il file lo ha fatto per la prima volta. qualche idea?

Inoltre, tutte le informazioni su come HttpClient gestisce i pacchetti in ritardo o fuori ordine in modo da poter capire meglio che cosa sta succedendo sarebbe grande.

+0

Ho fatto un po 'di test aggiuntivi e ho trovato qualcosa di interessante. Con Clumsy abilitato (sia in entrata che in uscita) se lo lascio abilitato, ottengo la situazione originariamente descritta (il file è stato caricato correttamente, ma PostAsync scade e lancia TaskCanceledException). Tuttavia, se spengo Clumsy dopo un paio di minuti, allora tutto ha successo. Ciò significa che la risposta dal server web api viene inviata più e più volte finché la ricezione non viene confermata? – AnthonyRyan

risposta

1

Una cosa con HttpClient I ha battuto la testa qualche tempo fa era la gestione speciale (leggi non comune) delle richieste POST. Quando invia la richiesta POST, invia prima le intestazioni (compresa l'ContentLenght e l'intestazione speciale Expect: 100-continue) al server ma senza il corpo. E attende che il server risponda con il codice di stato 100 se la richiesta è accettabile. Dopo di ciò inizia a inviare il corpo. Ulteriori informazioni qui: MSDN Page for ServicePointManager.Expect100Continue MSDN blog post with some details

Nel mio caso il problema era che questa parte del protocollo non è stata gestita particolarmente bene dal servizio di back-end (Play quadro) Stavo parlando quando richiesta dimensione era troppo grande per da gestire. Non stava restituendo alcun errore. E richiesta semplicemente scaduta. Quindi disabilitarlo con ServicePointManager.Expect100Continue = false; molto prima di inviare qualsiasi richiesta di a questo host ha risolto il problema per me. Almeno ora stava restituendo qualcosa.

Se ciò non aiuta, la cosa migliore che posso raccomandare è guardare con wireshark o qualcosa di simile a quello che sta succedendo sul filo. A condizione che giochi bene con questo strumento di Clumsy che stai usando. (Grazie per il collegamento tra l'altro. Stavo cercando qualcosa di simile me stesso)

Problemi correlati