admin管理员组

文章数量:1287598

I have a server and create a web interface for it, if a user presses the reboot button on the page, then the user is redirected to reboot.php where he is supposed to see a spinner gif till the server is reachable again and the server is getting rebooted via shell execute. If the server is reachable then i need to redirect to main.php

So i created the following function. The function starts with a timeout of 5 seconds, because otherwise it would instantly load main.php because the reboot mand takes it's time.

reboot.php

    $ret = false;

    test();

    function test()
    {
        setTimeout
        (
            function()
            {
                 $ret = ping("www.google.de");
                 if ($ret === false)
                 {
                     test();
                 }
                 else
                 {
                     window.location.href = "main.php";
                 }
            },
            3000
        );
    }

    function ping(url)
    {
        $.ajax
        (
            {
                url: url,
                success: function(result)
                {
                    alert('reply');
                    return true;
                },     
                error: function(result)
                {
                    alert('timeout/error');
                    return false;
                }
            }
        );
    }

<script src=".1.1/jquery.min.js"></script>

    <div class="col-lg-6 col-lg-offset-3" id="mydiv">
        <div class="mydiv_inhalt">
            <h2>Rebooting...</h2>
            <p>This can take about 2 minutes.</p>
            <center>
                <div class="waiting" id="waiting" style="margin-top:30px; margin-left: 0px;">
                    <center><img class="loading_table" src=".gif" alt="spinner gif"></center>
                </div>
            </center>
        </div>
    </div>

I have a server and create a web interface for it, if a user presses the reboot button on the page, then the user is redirected to reboot.php where he is supposed to see a spinner gif till the server is reachable again and the server is getting rebooted via shell execute. If the server is reachable then i need to redirect to main.php

So i created the following function. The function starts with a timeout of 5 seconds, because otherwise it would instantly load main.php because the reboot mand takes it's time.

reboot.php

    $ret = false;

    test();

    function test()
    {
        setTimeout
        (
            function()
            {
                 $ret = ping("www.google.de");
                 if ($ret === false)
                 {
                     test();
                 }
                 else
                 {
                     window.location.href = "main.php";
                 }
            },
            3000
        );
    }

    function ping(url)
    {
        $.ajax
        (
            {
                url: url,
                success: function(result)
                {
                    alert('reply');
                    return true;
                },     
                error: function(result)
                {
                    alert('timeout/error');
                    return false;
                }
            }
        );
    }

<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>

    <div class="col-lg-6 col-lg-offset-3" id="mydiv">
        <div class="mydiv_inhalt">
            <h2>Rebooting...</h2>
            <p>This can take about 2 minutes.</p>
            <center>
                <div class="waiting" id="waiting" style="margin-top:30px; margin-left: 0px;">
                    <center><img class="loading_table" src="http://www.securenet./sites/default/files/spinner.gif" alt="spinner gif"></center>
                </div>
            </center>
        </div>
    </div>

ajax.php

$cmd        = filter_input(INPUT_POST, "cmd");
if ( isset( $cmd ) && $cmd == "check_online_status" )
{
    echo "true";
}

In my ajax.php i simply return "true" if the call was successful. However, my logic does not work, it seems that my code only tries to make one call to my ajax.php and then never tries again and i get net::ERR_CONNECTION_REFUSED in the console.

I put many alerts into my code, but they are not executed, so i guess it does not try to call ajax.php a second time after getting net::ERR_CONNECTION_REFUSED.

My only idea would be to wait enough time and then redirect to main.php, but this is not a good solution because luck is needed, what if the time was not enough etc.

Share Improve this question edited Mar 18, 2016 at 13:06 Black asked Mar 15, 2016 at 9:20 BlackBlack 20.3k46 gold badges185 silver badges296 bronze badges
Add a ment  | 

8 Answers 8

Reset to default 7 +50

Let's summarize the issues in your code:

  • you need to use setInterval to execute the function every x seconds
  • the ajax request is asynchronous, and it should stay like that. You can't expect a return value from the callback, instead, you should act in the callback

The resulting code is way simpler:

var pingUrl = "www.google.de";
var targetUrl = "main.php";
setInterval(ping, 3000);

function ping() {
    $.ajax({
        url: pingUrl,
        success: function(result) {
            window.location.href = targetUrl;
        }
    });
}

@EdwardBlack fisrt you have to assing .gif image to image tag with id then in that image tag you to pass style="display:none"

<img id="imgid" src="" style="display:none">

function ping(url) {

        $.ajax({
              
                url: url,
                beforeSend : function(){
                   $('#imgid').css({'display':'block'}); //or 
                   $('#imgid').css('display', 'block');   // any one
                }, 
                success: function() {
                    alert('reply');
                    return true;
                },     
                error: function() {
                    alert('timeout/error');
                    return false;
                }
            });
    }

If the server is rebooting, usually you'll need some kind of failover IP or at least a caching proxy in front of the application server (in this case, OpenERP) to tell the user that it's down. Otherwise, while the server is offline, you'll just get a generic browser error message returned to the client, like "server not found" or similar.

In short, the best way to do this is to have another physical/virtual server sitting in front of the application server that is "always" up (or a cluster of servers that are rebooted independently), so that you always have something resolving the domain name or can fail over to a backup if the primary is down due to crashes or reboots.

Hope it helps

setTimeout runs the function only once

you can use setInterval instead of setTimeout

This may help as it's the closest to a ping you can do with JS : https://github./jdfreder/pingjs

Use the fallback as a recursive lunch-again part, and be careful to not redirect to quick in the first part.

This code should work. What I have done:

  • Use setInterval instead of setTimeout to execute the ping-function every x seconds.
  • The $.post function is executed asynchronously (the ajax request). That means that you cannot use a while loop as you did (except you set jQuery to make the call synchronously).
  • Please don't use Umlaute (äöü) in your code. Nothing good can e of it.

var timeoutCounter = 0;

var interval = setInterval(function() {
    ping(10);
}, 5000);

function ping(maxTimeouts) {
    $.post(
        'ajax.php',
        { cmd: "check_online_status" },
        function(data, status) {
            if (status == "success") {
                window.location.href = 'main.php';
                clearInterval(interval);
            } else { 
                timeoutCounter++;

                if (timeoutCounter >= maxTimeouts) {
                    alert("Max Timeouts ("+ maxTimeouts + ") exceeded!");
                    clearInterval(interval);
                }
            }
        }
    );  
}

You cannot return synchronously from the ping the way you do -- the return value is alway undefined in the test function if you check the value with a debugger. The reason is that $.ajax is not a synchronous call.

You should not (bad style) rely on synchronous apis when building javascript, so need to consider how to do the same using an async pattern.

For further reading, look at this question: How do I return the response from an asynchronous call?

Rewrite your code to use a async pattern, something like this;

$ret = false;

function rebooted(){ console.log("Reboot plete")};
test( rebooted );

function test(okcb)
{
    setTimeout
    (
        function()
        {
             ping("www.google.de",
                 function(){ $ret=true; okcb(); },
                 function(){ test(okcb);}
             );
        },
        3000
    );
}

function ping(url, yeah, nooo)
{
    $.ajax
    (
        {
            url: url,
            success: function(result)
            {
                console.log('reply');
                yeah();
            },     
            error: function(result)
            {
                console.log('timeout/error');
                nooo();
            }
        }
    );
}

Your ping function needs to be synchronous: param async: false in ajax request.

With the async request you made, you never enter the condition if ($ret === false), so the recursive call can't be made.

Also, returning a value in the successor error callbacks does not make your ping function returning the value you want.

You have to rewrite your pingfunction like this:

function ping(url)
{
    var ret = false;
    $.ajax
    (
        {
            async: false,
            url: url,
            success: function(result)
            {
                alert('reply');
                ret = true;
            },     
            error: function(result)
            {
                alert('timeout/error');
                ret = false;
            }
        }
    );
    return ret;
}

本文标签: javascriptShow waiting page while server rebootsStack Overflow