2012-06-13 16 views
6

Ora ho appena iniziato a bagnarmi i piedi in HTTP. Ho pianificato semplici requsts HTTP usando GET e POST. La pagina web che ho usato è un controllo php a 3 righe per il corretto $ _GET [] e $ _POST [], quindi semplicemente echo il carattere "1". Uso POST e GET con la stessa singola coppia nome/valore breve sperando che non ci sia bisogno della frammentazione dei pacchetti per mettere a fuoco le cose, e tutto questo viene fatto su un thread che è fuori dal thread dell'interfaccia utente. Le richieste vengono ripetute al telefono più volte durante il loro timing. Tutto funziona bene. (Vedi il codice qui sotto) Cioè, ottengo indietro la risposta di "1". Ma c'è un problema di temporizzazione persistente. quello che osservo è che:I primi tentativi POST e GET HTTP sono sempre lenti - Il sistema operativo è collegato o in rete?

  1. Nel primo tentativo il tempo di fare la richiesta è molto più lungo rispetto alle successive trys sia i metodi GET e POST.

  2. Il resto dei tentativi è sempre molto più veloce per entrambi.

  3. GET è sempre più veloce del POST.

Tutti questi sono veri per la connessione 3G e Wi-Fi (ma con Wi-Fi molto più veloce nel complesso come previsto).

Ho provato questo con BasicResponseHandler() e con i più manuali metodi Buffered IO Stream con gli stessi risultati.

Credo di capire 3. come risultato che un POST richiede due trasmissioni, una per il 'HTTP 100' restituisce quindi il corpo del pacchetto. - È corretto?

La mia domanda principale è cosa sta succedendo nei primi tentativi di richiesta che sono così lenti? A volte ci vogliono diversi secondi (!). È la rete che trattiene le cose o Android che mette in una presa creando una coda di qualche tipo? Se è Android, c'è un modo per codificare più correttamente ed evitare questo? C'è qualcosa nel mantenere aperto un socket per rendere questo problema solo una volta durante l'esecuzione? Se è così, è buona pratica farlo? Devo ammettere che questo aspetto non mi sembra affatto ovvio.

Ho trovato un po 'di discussione su questo, ma nessuno ha colpito direttamente questo aspetto.

-

Il codice di base per entrambi metodi GET e POST si presenta così (meno i try/catture), e vengono eseguite in un thread fuori l'interfaccia utente, prima il metodo GET poi il metodo POST: (uscita al di sotto)

ottenere una parte di esso:

public String[] HTTPGETIt(int numrounds) 
{ 
HttpClient httpclient = new DefaultHttpClient(); 
httpclient.getParams().setParameter (CoreProtocolPNames.PROTOCOL_VERSION,HttpVersion.HTTP_1_1); 
HttpGet GETRequest = new HttpGet("http://mypage.com/epoch.php?mynameis=tam"); 
ResponseHandler <String> MyBRH = new BasicResponseHandler(); 
String[] GETResult = new String[numrounds]; 

int i = 0; 
long timestart, DT; 
while(i < numrounds) 
{ 
    timestart = System.currentTimeMillis(); 
    GETResult[i] = httpclient.execute(GETRequest, MyBRH); 
    DT = System.currentTimeMillis() - timestart; 
    Log.d(TAG, "(" + i + ") GET-Round Trip was "+ DT + " ms."); 
    i++; 
}//while i <= numrounds 
httpclient.getConnectionManager().shutdown(); 
return GETResult; 
} //END HTTPGETIt 

E la versione POST:

public String[] HTTPPOSTIt(int numrounds) 
{ 
String Place = "HTTPPostping"; 
HttpClient httpclient = new DefaultHttpClient(); 
httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION,HttpVersion.HTTP_1_1); 
HttpPost PostRequest = new HttpPost("http://mypage.com/epoch.php"); 
ResponseHandler <String> MyBRH = new BasicResponseHandler(); 
String[] POSTResult = new String[numrounds]; 

List<NameValuePair> MynameValuePairs = new ArrayList<NameValuePair>(2); 
MynameValuePairs.add(new BasicNameValuePair("mynameis", "tam")); 

PostRequest.setEntity(new UrlEncodedFormEntity(MynameValuePairs)); 

int i = 0; 
long timestart, DT; 
while(i < numrounds) 
{ 
    timestart = System.currentTimeMillis(); 
    POSTResult[i] = httpclient.execute(PostRequest, MyBRH); 
    DT = System.currentTimeMillis() - timestart; 
    Log.d(TAG, "(" + i + ") POST-Round Trip was "+ DT + " ms."); 
    i++; 
}//while i <= numrounds 
httpclient.getConnectionManager().shutdown(); 
return POSTResult; 
} // END HTTPPOSTIt 

Questi sono chiamati da:

Runnable HTTPGETJob = new HTTPGETTask(NS); 
Thread HTTPGETThread = new Thread(HTTPGETJob, "HTTPGETThread"); 
HTTPGETThread.setPriority(Thread.MAX_PRIORITY); 
HTTPGETThread.start(); 

e:

Runnable HTTPPOSTJob = new HTTPPOSTTask(NS); 
Thread HTTPPOSTThread = new Thread(HTTPPOSTJob, "HTTPPOSTThread"); 
HTTPPOSTThread.setPriority(Thread.MAX_PRIORITY); 
HTTPPOSTThread.start(); 

Con runnables:

class HTTPGETTask implements Runnable 
{ 
int numtimes; 
DeviceInfo tsrtDI; 
HTTPGETTask(int inNS) { 
    this.numtimes = inNS; 
} 

@Override 
public void run() 
{ 
    long [] TT2NS = new long[numtimes]; 
    TT2NS = HTTPGETIt(numtimes); 
} 
}; 

e,

class HTTPPOSTTask implements Runnable 
{ 
int numtimes; 
DeviceInfo tsrtDI; 
HTTPPOSTTask(int inNS) { 
    this.numtimes = inNS; 
} 

@Override 
public void run() 
{ 
    long [] TT2NS = new long[numtimes]; 
    TT2NS = HTTPPOSTIt(numtimes); 
} 
}; 

L'uscita è tipicamente:

(0) GET-Round Trip era 368 ms.

(1) GET-Round Trip era di 103 ms.

(2) GET-Round Trip è stata del 98 ms.

(3) GET-Round Trip era 106 ms.

(4) GET-Round Trip era 102 ms.


(0) POST-Round Trip era 1289 ms.

(1) POST-Round Trip era 567 ms.

(2) POST-Round Trip era 589 ms.

(3) POST-Round Trip era 496 ms.

(4) POST-Round Trip era 557 ms.

+0

Dopo la prima richiesta i risultati potrebbero essere memorizzati nella cache –

+0

, forse la risoluzione di dns? prova un indirizzo IP – goat

+0

@rambo Ho appena provato un indirizzo IP esplicito con gli stessi risultati. – Tam

risposta

1

Vorrei insistere per impostare Protocol Version come HTTP 1.1 e provarlo. Aumenterebbe la richiesta/tempo di risposta rispetto a quello che serve ora. Non l'ho ancora provato, ho appena ricevuto le informazioni. Quindi, puoi provare qualcosa come sotto prima di eseguire la richiesta.

httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, 
                 HttpVersion.HTTP_1_1); 
+0

Ci ha provato, maledetto, senza modifiche. Ho anche solo aggiornato il codice che ho postato per includerlo, solo per completezza. Grazie per il suggerimento però. – Tam

1

Sono d'accordo con risposta di Lalit Poptani, che possono contribuire a rendere più veloce chiamata come sembra essere dovuto al fatto HTTP 1.1 mantiene la connessione e non lo fate il tremolio della mano ogni volta.

Ma allo stesso tempo, vorrei dire che questo non è un problema specifico di Android, la stessa cosa accade in quasi tutte le piattaforme e in ogni lingua perché la prima volta quando si effettua una chiamata http la piattaforma deve creare e imposta oggetti diversi che assegnano valori per eseguire la chiamata, e che rimane lì, così quando si effettua una nuova chiamata viene salvato il tempo per creare e assegnare oggetti, in modo da ottenere risposte più veloci.

Quali sono questi oggetti? - Questo è detto nelle righe precedenti: non ho alcun elenco abbastanza chiaro di quelli, ma sono come le impostazioni proxy, memoria cache per questo.


aspettare qualcuno in più, fino a quando qualcuno viene fornito con profonda conoscenza tecnica su questo e spiega come funziona tutta roba dietro.

+0

Grazie. Non ho fatto questo tipo di programmazione all'interno di qualsiasi altro sistema operativo con cui ho lavorato. – Tam