2014-09-12 11 views
16

Ho un URL nella formaCome verificare rapidamente se il server URL è disponibile

http://www.mywebsite.com/util/conv?a=1&from=%s&to=%s 

e si desidera controllare se è disponibile.

I collegamenti mi reindirizzano su una pagina di richiesta errata se provo ad aprirli con un browser, tuttavia tramite codice posso ottenere i dati di cui ho bisogno.

L'utilizzo di un blocco try-catch su una procedura di richiesta HTTP è piuttosto lento, quindi mi chiedo come posso eseguire il ping di un indirizzo simile per verificare se il server è attivo.


ho cercato

boolean reachable = InetAddress.getByName(myLink).isReachable(6000); 

ma ritorna sempre false.

Ho anche provato

public static boolean exists(String URLName) { 

    try { 
     HttpURLConnection.setFollowRedirects(false); 
     HttpURLConnection con = (HttpURLConnection) new URL(URLName).openConnection(); 
     con.setConnectTimeout(1000); 
     con.setReadTimeout(1000); 
     con.setRequestMethod("HEAD"); 
     return (con.getResponseCode() == HttpURLConnection.HTTP_OK); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     return false; 
    } 
} 

che restituisce il valore corretto al termine del processo, bit è troppo lento se il server non è disponibile.

EDIT

ho capito qual è la causa della lentezza

a) se il server restituisce alcuni dati, ma interrompe la richiesta prima di completare la richiesta il timeout viene ignorata e bloccato fino al ritorno di un Exception che portare l'esecuzione per raggiungere il blocco catch, questa è la causa della lentezza di questo metodo, e ancora non ho trovato una soluzione valida per evitare questo.

b) Se avvio il dispositivo Android e apro l'App senza connessione, il valore falso viene restituito correttamente, se l'app viene aperta con connessione Internet attiva e il dispositivo perde la connessione a Internet accade la stessa cosa del caso A (anche se provo a chiudere e riavviare l'app ... non so perché, suppongo che qualcosa rimanga memorizzato nella cache)

Tutto ciò sembra correlato al fatto che lo Java URLConnection non fornisce un timeout fail-safe su legge. Guardando il campione a this link ho visto che utilizza un thread per interrompere la connessione in qualche modo ma se aggiungo semplicemente la riga new Thread(new InterruptThread(Thread.currentThread(), con)).start(); come nell'esempio non cambia nulla.

+1

prova usando getResponseMessage() o getResponseCode() – KOTIOS

+0

Bad Request significa che il tuo URL non è valido, ma non che il server non è disponibile –

+0

@mtetno Potresti darmi maggiori dettagli un uso ha risposto a qualcosa di simile ma sembra lento come aspettare per eccezione del blocco try try correlato – AndreaF

risposta

2
public static boolean exists(String URLName) { 

     try { 
      HttpURLConnection.setFollowRedirects(false); 
      // note : you may also need 
      // HttpURLConnection.setInstanceFollowRedirects(false) 
      HttpURLConnection con = (HttpURLConnection) new URL(URLName) 
      .openConnection(); 
      con.setRequestMethod("HEAD"); 
      return (con.getResponseCode() == HttpURLConnection.HTTP_OK); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      return false; 
     } 
    } 
+0

Questo codice funziona ma è lento come l'attesa per il Eccezione del blocco catch try – AndreaF

0

hai provato a utilizzare socket non elaborati?

Dovrebbe correre più veloce in quanto è su un livello inferiore

static boolean exists(String serverUrl) { 

    final Socket socket; 

    try { 
     URL url = new URL(serverUrl); 
     socket = new Socket(url.getHost(), url.getPort()); 
    } catch (IOException e) { 
     return false; 
    } 

    try { 
     socket.close(); 
    } catch (IOException e) { 
     // will never happen, it's thread-safe 
    } 

    return true; 
} 
+0

con questa app di codice che si arresta in modo anomalo e ottiene l'eccezione di porta fuori intervallo – AndreaF

14
static public boolean isServerReachable(Context context) { 
    ConnectivityManager connMan = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 
    NetworkInfo netInfo = connMan.getActiveNetworkInfo(); 
    if (netInfo != null && netInfo.isConnected()) { 
     try { 
      URL urlServer = new URL("your server url"); 
      HttpURLConnection urlConn = (HttpURLConnection) urlServer.openConnection(); 
      urlConn.setConnectTimeout(3000); //<- 3Seconds Timeout 
      urlConn.connect(); 
      if (urlConn.getResponseCode() == 200) { 
       return true; 
      } else { 
       return false; 
      } 
     } catch (MalformedURLException e1) { 
      return false; 
     } catch (IOException e) { 
      return false; 
     } 
    } 
    return false; 
} 

o utilizzando runtime:

Runtime runtime = Runtime.getRuntime(); 
Process proc = runtime.exec("ping www.serverURL.com"); //<- Try ping -c 1 www.serverURL.com 
int mPingResult = proc .waitFor(); 
if(mPingResult == 0){ 
    return true; 
}else{ 
    return false; 
} 

Si può provare isReachable() ma c'è un bug filed for it e this comment says that isReachable() requires root permission:

try { 
    InetAddress.getByName("your server url").isReachable(2000); //Replace with your name 
    return true; 
} catch (Exception e) 
{ 
    return false; 
} 
+0

il primo campione ha lo stesso problema del codice che ho postato (funziona ma è lento quando il server non risponde), il secondo campione restituisce sempre false – AndreaF

+0

ho modificato la mia risposta, prova anche 'ping -c 1 www.serverURL.com' –

+0

Ho aggiunto -1 c dopo il ping, ma restituisco sempre false nonostante il primo metodo sullo stesso link restituisca correttamente true – AndreaF

0

Come menzionato da 'eridal', che dovrebbe essere più veloce, aprire la presa; tuttavia, ti dice solo che un server è in ascolto sull'host e sulla porta ma per essere sicuro, devi scrivere HTTP o alternativamente una richiesta errata (junk), dovresti ricevere HTTP/1.1 400 Bad Request. Leggendo la prima riga restituita, se contiene HTTP, si è sicuri che il server è un server HTTP. In questo modo sei sicuro che il server sia disponibile così come un server HTTP.

Questo è in estensione alla risposta di cui sopra da eridal.

-1

Ho avuto un problema simile il mese scorso e qualcuno mi ha aiutato con un esempio facoltativo. Vorrei suggerire lo stesso

public boolean isServerReachable() 
    // To check if server is reachable 
    { 
     try { 
      InetAddress.getByName("google.com").isReachable(3000); //Replace with your name 
      return true; 
     } catch (Exception e) { 
      return false; 
     } 
    } 

se il reso vero del server url è disponibile, altrimenti non è attualmente disponibile.

+0

oppure puoi controllare http://stackoverflow.com/questions/ 25541940/android-check-condition-per-server-down –

+0

come ho detto nella mia domanda questo codice rteturns sempre false con il mio collegamento – AndreaF

+0

Il tuo link ti porta al link "http://website.1and1.com/#top "quindi prova solo con ** website.1and1.com **. Ritorna vero –

-1
if (android.os.Build.VERSION.SDK_INT > 9) { 
          StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder() 
            .permitAll().build(); 

          StrictMode.setThreadPolicy(policy); 
         } 
         try { 
          URL diachi = new URL("http://example.com"); 
          HttpURLConnection huc = (HttpURLConnection) diachi.openConnection(); 
          huc.setRequestMethod("HEAD"); 
          int responseCode = huc.getResponseCode(); 

          if (responseCode != 404) { 
           //URL Exist 

          } else { 
           //URL not Exist 
          } 
         } catch (MalformedURLException e) { 
          e.printStackTrace(); 
         } catch (IOException e) { 
          e.printStackTrace(); 
         } 
0

Prova questo codice

public boolean isServerAlive() 
    // To check if server is reachable 
{ 
    try { 
     InetAddress.getByName("google.com").isReachable(3000); //Replace with your name 
     return true; 
    } catch (Exception e) { 
     return false; 
    } 
} 
0

Sotto codice attende fino pagina web è disponibile:

public void waitForWebavailability() throws Exception { 
     boolean success = false; 
     long waitTime = 0; 
     while (!success) { 
      try { 
       waitTest(30000); 
       waitTime += 30000; 
       if (waitTime > 600000) { 

        System.out.println("Web page is not available"); 
       } 
       webDriver.get("http://www.google.com"); 
       if (webDriver.getTitle().toLowerCase().contains("sometitle")) { 
        success = true; 
       } 
      } catch (Exception e) { 
       success = false; 
      } 

     } 

    } 

// Code related to waittest 

public void waitTest(long millis) throws Exception { 
     try { 
      Thread.sleep(millis); 
     } catch (InterruptedException e) { 
      throw new Exception(e); 
     } 
    } 
0

here lo scrittore suggerisce questo:

public boolean isOnline() { 
    Runtime runtime = Runtime.getRuntime(); 
    try { 
     Process ipProcess = runtime.exec("/system/bin/ping -c 1 8.8.8.8"); 
     int  exitValue = ipProcess.waitFor(); 
     return (exitValue == 0); 
    } catch (IOException | InterruptedException e) { e.printStackTrace(); } 
    return false; 
} 

Non posso semplicemente eseguire il ping della mia pagina, che voglio comunque richiedere? Potresti anche controllare entrambi, se vuoi distinguere tra "connessione Internet disponibile" e i tuoi server raggiungibili

leggere il collegamento. suo sembra molto buona

EDIT: nel mio exp di usarlo, non è veloce come questo metodo:

public boolean isOnline() { 
    NetworkInfo netInfo = connectivityManager.getActiveNetworkInfo(); 
    return netInfo != null && netInfo.isConnectedOrConnecting(); 
} 

sono un po 'diverso, ma nella funzionalità solo per la verifica della connessione ad internet della il primo metodo potrebbe rallentare a causa delle variabili di connessione.

Problemi correlati