2015-07-20 24 views
11

Ho un problema strano quando consumo la mia API dalla mia app. A volte, per nessuna ragione, la richiesta non è solo inviato, e non riesce alla fine del time-out con il seguente errore:Richiesta non inviata

Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." 

Ho provato molti API quali NSURLConnection delegati, NSURLSession e NSURLConnection.sendSynchronousRequest senza successo.

Ecco un esempio di progetto che ho fatto per evidenziare il problema. ConnectionBugApp

Ecco i passaggi per riprodurre:

  • Eseguire l'applicazione in Xcode e fermare il debug solo così l'applicazione è sul telefono
  • Aprire l'applicazione, fare clic su Verifica connessione (ci riesce, ruota di carico subito dopo)
  • Vai ad altre app come facebook/twitter/giochi di rete (alcuni sono un po 'pesanti) e passa in modalità aereo alcune volte
  • Torna alla mia app e fai clic su Test di connessione (ruota di caricamento mai si ferma)

Alcuni dettagli che potrebbero aiutare:

  • Se io uso il mio IP del server al posto del mio nome a dominio, riesce

  • Problema appare solo quando sulla rete LTE/4G

Qualsiasi idea o soluzione alternativa sarebbe molto apprezzata! Sentiti libero di chiedere maggiori dettagli.

Grazie

EDIT

ho modificato la descrizione molto da quando ho postato (sperando di rendere più pulita e più chiara), mi dispiace se alcune risposte o commentano don' ha davvero più senso.

+0

Se si utilizza l'API NSURLSession, il problema si riproduce? –

+0

@LeoNatan, sì ho lo stesso identico problema con 'NSURLSession' – streem

+0

Che cosa vedi sul lato server? Vedi il server accetta una connessione client o non raggiunge nemmeno il server? Direi che sembra da qualche parte nel tuo server, stai lasciando cadere la connessione. Forse un firewall. –

risposta

2

Come menzionato nei commenti, ho avuto DNSSEC (protezione da avvelenamento della cache) abilitato sul mio servizio di hosting.

Disabilitarlo, risolto il problema, anche se potrebbe non essere una soluzione davvero piacevole. Dopo alcune settimane di ricerche, sarà abbastanza buono.

Darò la generosità a qualcuno che può spiegarlo, o chi può fornire una soluzione migliore.

+0

"I pacchetti DNSSEC possono essere negati perché la dimensione della risposta è troppo grande." Controllare il collegamento http://www.cisco.com/web/about/security/intelligence/dnssec.html Questa potrebbe essere una ragione. – Karlos

0

Prova il seguente codice per la connessione. Questo ti aiuterà.

 let urlData = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: &error) 

      if error != nil || urlData!.length == 0 
      { 
       println("Error happend timeout======\(error?.code)!") 

       continue 
      } 
      else //else1 
      {if let httpResponse = response as? NSHTTPURLResponse 
       { 
        println("Status Code for successful---\(httpResponse.statusCode)") 

        // For example 502 is for Bad Gateway 
        if (httpResponse.statusCode == 502) 
        { 
         // Check the response code from your server and break 
         break 
        } 
        else 
        { 

         //Your code 
        } 
      } 
    } 

È possibile ottenere l'elenco dei codici di stato HTTPS nel seguente link StatusCode

+0

Grazie per la risposta, non sono sicuro per quale motivo hai postato questo codice e sfortunatamente ho lo stesso problema con esso. – streem

+0

Ho provato ConnectionBugApp sulla connessione LTE/4G e funziona bene per gli URL "https://tripaff.com/" e "https://meetsam.co/". Ho ricevuto l'errore 503 per l'URL "http://ip.jsontest.com/". – Karlos

+0

Hmm, hai provato dopo aver utilizzato intensamente la rete su altre app? Puoi anche provare dimenticando l'app per qualche ora e premere di nuovo il pulsante Prova connessione più tardi. – streem

2

Mi sono imbattuto in questo problema quando si utilizza una richiesta asincrona. Sembra che iOS limiti il ​​numero di connessioni aperte a un singolo dominio, in modo tale che tutte le connessioni successive falliscano nel modo descritto.

Se le connessioni in genere si completano rapidamente, questo probabilmente non sarà un problema.

La soluzione è limitare il numero di connessioni aperte allo stesso dominio per impedire che ciò accada.

La risposta inviata da karlos funziona perché la sincronizzazione della connessione impedisce ad altri di essere aperti.

+0

Grazie per la tua risposta, il suggerimento di karlos non funziona. Se posso aggiungere anche, ho un header 'Connection: close' in ogni risposta e credo che sia il fatto che io uso altre app che rendono la richiesta non andare. Come se il sistema operativo avesse messo la mia app e la sua connessione in background e si fosse dimenticato di riattivarlo. – streem

+0

Hai provato ad aggiungere il timeout per la richiesta https? – Karlos

+0

Vuoi dire quando inizio la mia richiesta? sì, ha un timeout di 120 secondi. – streem

1

Nel codice la richiesta richiede un timeout predefinito di 60 secondi, ma è possibile modificare il tempo di richiesta nel codice come di seguito.

nel tempo di sostituzione classe NetworkItem.

init(request:NSMutableURLRequest){ 
    self.request = request 
    self.request.timeoutInterval = 120 
    super.init() 
} 
+0

Grazie per la risposta, ma questo non è un problema di durata del timeout. Quando fallisce, fallisce sempre alla fine del timeout qualunque sia la durata. – streem