web-dev-qa-db-fra.com

Comment vérifier rapidement si le serveur d'URL est disponible

J'ai une URL sous la forme

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

Et voulez vérifier si il est disponible.

Les liens me redirigent vers une page de requête incorrecte si j'essaie de les ouvrir avec un navigateur, mais je peux obtenir via le code les données dont j'ai besoin.

L'utilisation d'un bloc try-catch sur une procédure de requête HTTP est assez lente, alors je me demande comment je pourrais envoyer une requête ping à une adresse similaire pour vérifier si son serveur est actif.


J'ai essayé

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

Mais retourne toujours false.

J'ai aussi essayé

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;
    }
}

Cela renvoie la valeur correcte à la fin du processus, le bit est trop lent si le serveur n’est pas disponible.

MODIFIER

J'ai compris quelle est la cause de la lenteur

a) si le serveur retourne des données mais interrompt la requête avant de terminer la requête, le délai d'attente est ignoré et bloqué jusqu'à ce qu'une valeur Exception conduisant à l'exécution du bloc catch soit renvoyée, ce qui est la cause de la lenteur de cette méthode, et j'ai encore 't trouvé une solution valable pour éviter cela.

b) Si je démarre l'appareil Android et que j'ouvre l'application sans connexion, la valeur fausse est renvoyée correctement. Si l'application est ouverte avec une connexion Internet active et que l'appareil a perdu sa connexion Internet, il en va de même dans le cas A essayez de terminer et de redémarrer l'application ... Je ne sais pas pourquoi, je suppose que quelque chose reste en cache)

Tout cela semble lié au fait que Java URLConnection ne fournit pas de délai d'expiration de sécurité pour les lectures. En regardant l’échantillon sur ce lien j’ai vu qui utilise un fil pour interrompre la connexion d’une manière ou d’une autre, mais si j’ajoute simplement la ligne new Thread(new InterruptThread(Thread.currentThread(), con)).start(); comme dans l’échantillon, rien ne change.

19
AndreaF
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;
}

ou en utilisant le 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;
}

Vous pouvez essayer isReachable() mais un bogue a été enregistré pour lui et ce commentaire indique que isReachable () nécessite une autorisation root :

try {
    InetAddress.getByName("your server url").isReachable(2000); //Replace with your name
    return true;
} catch (Exception e)
{
    return false;
}
19
Sagar Pilkhwal
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;
        }
    }
4
BSavaliya

avez-vous essayé d'utiliser des sockets raw?

Il devrait fonctionner plus vite car il est sur une couche inférieure

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
eridal

J'ai eu un problème similaire le mois dernier et quelqu'un m'a aidé avec un exemple facultatif. Je voudrais vous suggérer la même chose

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;
        }
    }

si return true que votre serveur d'URL est disponible, l'autre n'est pas disponible actuellement.

0
A_rmas

Le code ci-dessous attend que la page Web soit disponible:

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
khajappa

Comme mentionné par "eridal", cela devrait être plus rapide, ouvrez le socket; cependant, il vous indique seulement qu'un serveur écoute sur l'hôte et le port, mais pour être sûr, vous devez écrire HTTP ou alternativement une requête incorrecte (courrier indésirable), vous devez obtenir HTTP/1.1 400 Requête incorrecte. En lisant la première ligne renvoyée, si elle contient HTTP, vous êtes certain que le serveur est un serveur HTTP. De cette façon, vous êtes sûr que le serveur est disponible ainsi qu'un serveur HTTP.

Ceci est dans le prolongement de la réponse ci-dessus par eridal.

0
Ironluca

ici l'auteur suggère ceci:

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;
}

Est-ce que je ne peux pas juste faire un ping sur ma propre page, que je veux quand même demander? Vous pouvez même cocher les deux, si vous souhaitez faire la différence entre «connexion Internet disponible» et vos propres serveurs accessibles

lisez le lien. sa semble très bien

EDIT: Dans mon exp de l'utiliser, ce n'est pas aussi rapide que cette méthode:

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

elles sont un peu différentes, mais dans la fonctionnalité de vérification de la connexion à Internet, la première méthode peut devenir lente en raison des variables de connexion.

0
Emad