Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove safari's loading wheel when using Server Sent Events

Tags:

html

push

safari

I'm using HTML5's Server Sent Events to push updates to my online clients. Everything works fine on Firefox and Chrome but with Safari there's a loading wheel all the time. Maybe because he detect SSE as something loading in the page.

How can I say to Safari that SSE isn't something that loads but simply a updating script so the user won't see the loading wheel after the page is really loaded?

This is the live updated html page that the client is looking at:

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>SSE Tester</title>
</head>
<body>
    <h1>SSE Output</h1>
    <div id="result"></div> 
    <h1>Debug Console</h1>
    <div id="status"></div>   
    <script>
    //SSE si compatible
    if(typeof(EventSource)!=="undefined")
    {
        var i = 1;
        var source=new EventSource("demo_sse.php");



        //Lorsque le serveur envoie un message
        source.onmessage=function(event)
        {
            //Validation de l'origine du serveur
            if (event.origin != 'https://secure.mydomain.com') 
            {
                document.getElementById("status").innerHTML+= "<br><b>Oups! Looks like something went wrong!\n\nPlease contact [email protected] with the following error :</b><p><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The Origin of the EventSource wasn\'t coming from our secure server!</pre>";
                return;
            }
            document.getElementById("result").innerHTML+= "#" + i + " " + event.data + "<br />";            
            i++;
        }   

        //EventListener
        source.addEventListener('message', function(e)
        {
            console.log(e.data);
            //document.getElementById("status").innerHTML+= "Message Recevied<br />";
        }, false);

        source.addEventListener('open', function(e) 
        {
            // Connection was opened.
            document.getElementById("status").innerHTML+= "Connection #" + i + " opened<br />";
        }, false);

        source.addEventListener('error', function(e)
        {
            if (e.readyState == EventSource.CLOSED)
            {
                // Connection was closed.
                document.getElementById("status").innerHTML+= "Connection closed by the server<br />";
            }
            else
            {
                // Error.
                document.getElementById("status").innerHTML+= "<b>Error Connection interrupted</b><br />";
            }
        }, false);
    }
    else
    {
        document.getElementById("result").innerHTML="Sorry, your browser does not support server-sent events...";
    }     

    </script>    
</body>
</html>

And there's the code of my demo_sse.php script (server side):

<?php
$clientLatest = "1";
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
while(true)
{
    //Retreive latest version
    $filename = "version.txt";
    $handle = fopen($filename, "r");
    $serverLatest = fread($handle, filesize($filename));
    fclose($handle);

    if ($clientLatest < $serverLatest)
    {
        //Update client 
        $time = date("H:i:s");
        echo "data: Updating to Version: $serverLatest because client's Version: $clientLatest at: {$time}\n\n";
        $clientLatest = $serverLatest;
        ob_flush();
        flush();
    }   
    //sleep( rand(2, 7));
    sleep(1);
}
?>
like image 528
exomic Avatar asked Mar 29 '12 19:03

exomic


1 Answers

Looks like using javascript's timeout fonctions fixed the problem in safari. Simply timeout the script before connecting for 1000ms so the loading seems completed for safari and then connect to SSE server.

like image 154
exomic Avatar answered Oct 03 '22 02:10

exomic