views:

76

answers:

4

Hello,

I'm trying to figure a way where my clients can ping my server via php, and then retrieve the results into format like this "15 MS".

I ended up finding a way where servers can ping servers. However I want to be able to have the remote user somehow ping the server, or maybe have the server ping the client possibly?

function track($host, $port, $timeout) {
$firstTime = microtime(true);
$sock = fSockOpen($host, $port, $errno, $errstr, $timeout);
if (!$sock) {
echo "<b>Offline</b>";
}
$secondTime = microtime(true);
$ping = round((($secondTime - $firstTime) * 1000), 0);
echo $ping." ms";
}

track($_SERVER["REMOTE_ADDR"], 80, 10);

I tried this function, where I'd get the server to ping the client to see the response time between the client/server.

fsockopen() [function.fsockopen]: unable to connect to XXXXXXXXXXX:80

A: 

What makes you think clients are going to reliably respond to ICMP echo requests?

A better solution would be to write a client-side Java applet (or JavaScript?) to ping your server.

Remember, security restrictions will limit both languages to only communicate back to their origin server. You won't be able to allow your users to ping a server besides your own... but that doesn't appear to be an issue in your case.

Dolph
A: 

Do you wanna know the time between the http request and response? You need implement it in client-side using javascript...

Look the extension firebug of firefox if this is only required to you.

[]'s

Felipe Cardoso Martins
A: 

You have to do this in JavaScript. The client cannot run PHP at all, and your attempt to ping the client will not work when their firewall blocks requests from the outside (which is often the case).

Build a "ping" function in JS which fetches a page a few times by AJAX. This example is built upon the jQuery framework:

Web page/JS

<script src="jquery-1.4.2.min.js"></script>
<script>
var global_runs = 0;
function ping(data) {
        var op = "";
        if(global_runs == 0) {
                op = "start";
        }else if(global_runs == 3){
                op = "end";
        }else if(global_runs > 3) {
                return;
        }
        global_runs++;
        $.post("ping.php", {op: op}, ping);
        if(data != null) {
                $("#time").text(data + " MS");
        }
}

$(document).ready(function(){
        //Start pinging
        ping();
});
</script>

<p id="time">Time will be here</p>

ping.php

<?php
session_start();
if($_POST['op'] == 'start' || !isset($_SESSION['start'])) {
        $_SESSION['start'] = microtime(true);
        $_SESSION['runs'] = 0;
}else{
        $_SESSION['runs']++;
        $now = microtime(true);
        $time = $now - $_SESSION['start'];

        echo ($time / $_SESSION['runs']) * 1000; //milliseconds
}
?>

I don't really make use of the end op here, but it can be used to let the server now that this is the last ping request. Note that this code trusts the client, which means you may need some extra work on the security on the serverside (maybe take away the whole notion of "ops" from the serverside and ust send the pings?). Also, you probably want different counters for each page, maybe identified by some token that you return in the first request.

Also note that this is depending on HTTP and CPU latency as well, not just the network, but I think it's as good as you can get it.

Emil Vikström
-1 for "Build a "ping" function in JS" then going to great lengths describing how to measure an HTTP request via TCP.
symcbean
symcbean, this is the best solution that I know of. I clearly state that HTTP and CPU latency will be included as well, but if you know of a way to send ICMP requests or otherwise measure the network latency only I will be glad to be proven wrong.
Emil Vikström
+1 for pointing out that you're also measuring the execution time of the monitoring software :)
symcbean
+1  A: 

I'm trying to figure a way where my clients can ping my server via php

Why? What's the value in knowing this information? Although I noted that Emil's answer didn't address the question, it might address the problem - the time it takes for an ICMP packet to go to a server and come back will be different from the time taken to complete a TCP handshake on port 80 across the internet (they should be roughly the same on a LAN provided the webserver is not saturated).

If you want to get good information about RTT times, then a better solution would be to use a network monitoring tool / software. PastMon is an obvious candidate.

If you really must send a ping from the client, then you'd need to do this using a java applet / flash / activeX (assuming that these have the low-level TCP stack access required to carry out a ping).

C.

symcbean
What symcbean said. Not to mention that many ISP routers prioritize ICMP traffic at or near the least priority. Ban ping-then-do!
dbasnett