Uutiset:

Want to get involved in developing SMF, then why not lend a hand on our github!

Main Menu
Advertisement:

Auto updating in a block

Aloittaja cap269, heinäkuu 06, 2013, 10:52:06 AP

« edellinen - seuraava »

cap269

I have created a Custom PHP block on my SMF/SimplePortal site that pings a remote server and reports if it is online/offline and some status info. That part is working fine. What I would like, though, is to be able to fetch that status information again every 10-20 seconds automatically without refreshing the entire front page as there is also an IRC box on there as well. Is it possible to write a loop or a timed function to poll those servers and update the information in that one Custom PHP block?

codenaught

What you would probably need to do is change the block to an HTML block with JS included in it. The Javascript would need to make an AJAX request to a URL to your PHP page that returns a response with a boolean of whether the server is on or off and then in your callback to the request you would be able to show the appropriate text/icon.

Have any experience with JS?

For the looping, I imagine if you put the request into a recursive function "myFunc" that called setTimeout(myFunc, 20000) at the end might do the trick.
Dev Consultant
Former SMF Doc Coordinator

cap269

Thanks, your answer sounds like it is headed in the right direction. I figured it would probably need to be AJAX-ish. However, I have no experience writing JS, and consequently none with AJAX. I'm good with HTML; I used to write in ASP about 10 years ago, and am currently learning PHP. I was formerly a professional programmer (C/C++/Asm), but only now in 'retirement' have I really started getting into this type of web programming, merely out of self-interest, and also to eventually be able to help out other folks, such as you are doing with me right now. Any and all assistance is greatly appreciated.

codenaught

That would be great if you are able to help others when you have more experience with web programming. :) Web programming is quite a bit different from C/C++ and ASM, but I rather enjoy it.

Here is an example of something that might be similar to what you will need:

HTML for block:

<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="status"></div>
<script>
$(document).ready(function() {
var server_connected = "Server Connected",
server_disconnected = "Server Disconnected";
wait_time = 20000;
error = "Problem receiving status";

function reloadResponse() {
$.ajax({
  url: "status.php",
  context: $('#status')
}).done(function(flag) {
if (flag) {
$(this).html(server_connected);
}
else
$(this).html(server_disconnected);
}).error(function() {
$(this).html(error);
});

setTimeout(reloadResponse, wait_time);
};

reloadResponse();
});
</script>


Note that loads jQuery. You may already have it loaded if something else you use needs jQuery. If you do not wish to use any JS libraries you will have to write quite a bit of extra code to make an AJAX request.

PHP file called status.php (on the same server):

<?php

header
('Content-type: application/json');

$serverRunning isServerRunning();

echo 
json_encode($serverRunning);

?>



Where you would have to insert your logic for whether the server was up or not where you see isServerRunning() there.
Dev Consultant
Former SMF Doc Coordinator

cap269

Yes, indeed, it is quite a different bucket of bolts than C/C++. Anyhow, thank you so much for your excellent responses... looks like I'm going to be playing with these code snippets tonight! (Hope the missus doesn't get too mad, lol)   I'll give it a go and report back once I've had a chance to tinker with these. I've not used jQuery before, so I have some research to do first. Thanks again!

Matthew K.

Definitely keep the jQuery documentation and API in mind, it's quite extensive, gives detailed examples and a lot of tips and pointers - it's VERY helpful!

cap269

Ok, so this works a treat. I now have a status indicator that works nearly the way I want it to. Now, in the original post, I mentioned that there was some data as well (number of users logged in). Let me post some code first:

FILE: status1.php
<?php 

function isServerRunning ($host$port=80) {
     
$server = new ServerStatus$host$port );
     return 
$server;
}

$Server1 isServerRunning ("192.168.1.2");
header('Content-type: application/json');
echo 
json_encode$Server1->online );
?>



And, an example of the PHP class that is in the status.php file:


class ServerStatus {
 
public $server;
public $online, $users;
public $error = "OK";

    function __construct($url, $port = '80') {
 
        $this->server = array(
            "url" => $url,
            "port" => $port
        );
 
        if ( $sock = @stream_socket_client('tcp://'.$url.':'.$port, $errno, $errstr, 1) ) {
 
            $this->online = true;
            $this->users = [external function that returns number of logged-in users];
            }
            else {
                $this->error = "Cannot retrieve server info.";
            }
 
        }
        else {
            $this->online = false;
            $this->error = "Cannot connect to server.";
        }
 
    }
}

And the Ajax call:

<script>
$(document).ready(function() {
var server_connected = "ONLINE";
server_disconnected = "OFFLINE";
error = "Problem receiving status";
wait_time = 1000;

function reloadResponse() {
$.ajax({
  url: "status1.php"
}).done(function(flag) {
if (flag) {
$('#status').html(server_connected);
}
else {
$('#status').html(server_disconnected);
}

}).error(function() {
$(this).html(error);
});

setTimeout(reloadResponse, wait_time);
};

reloadResponse();
});
</script>


The Custom HTML block does indeed display the text indicating the server status. The class function that determines the online status also returns the number of logged-in users. I would like to know how to modify the server_connected variable to read "ONLINE with x users." I guess the real question is, how to take the PHP variable array that is returned by the class function ($Server1) and pass it to a Javascript variable in the HTML file for further use there? My inadequacy with Javascript is really showing through now, lol.

cap269

I got it. What I did was simply return a JSON-encoded array containing all the values I want to use rather than the single Boolean. Works great, and learned a lot too. Thanks to codenaught for pointing me in the correct direction. This was a fun little excursion.

Advertisement: