What is the difference between SSE and Ajax?

5

I want to update a div that contains the credits of a client, as soon as I update the amount of credits in the Bank and I'm using setInterval :

setInterval(function(){
    ver_creditos();
}, 60000);

Then I saw the function of HTML5 , EventSource (SSE) and did a test, and through the console I saw that it makes requests every 5 seconds.

In my question, I wanted to know which of these functions would be best for my utility, and which one would use the server less?

    
asked by anonymous 07.06.2017 / 02:15

2 answers

9

Ajax is a normal HTTP request, but it runs at background , Ajax is to be more exact is a "way" of using the XmlHttpRequest API asynchronously, but anyway the request is a normal HTTP request, it requests once it receives the response and closes the request, more details in:

The server-sent events ( SSE) is different , it's more similar to WebSocket , however other than WebSocket , SSE can work on a normal HTTP server, as PHP should know, asp.net-mvc and other web technologies run on the server side and only send you the response when you request / request, then when you do this:

var evtSource = new EventSource("api.php");

You'll be in a kind of persistent connection , meaning api.php can stay in an infinite loop, never ending, instead of you get the response it's as if PHP sent you the response at the time it's wanted, for example:

date_default_timezone_set("America/Sao_Paulo");
header("Content-Type: text/event-stream\n\n");

$counter = rand(1, 10);

while (1) {  
  echo "event: ping\n";
  $curDate = date(DATE_ISO8601);
  echo 'data: ' . $curDate;
  echo "\n\n";

  $counter--;

  if (!$counter) {
    echo 'data: This is a message at time ' . $curDate . "\n\n";
    $counter = rand(1, 10);
  }

  ob_end_flush();
  flush();
  sleep(1);
}

Every second is the PHP "who is going to send a request" (relatively speaking) to the client-side, and you will be observing with:

evtSource.onmessage = function(e) {
      console.log(e.data); //Pega a resposta do PHP
}

SSE format

The sse has a somewhat standard format, first you need to pass the Content-Type: text/event-stream on the headers, and then what would be equivalent to the body must contain these fields (not all at the same time, it depends a lot on what you want to do):

  • event :

    If an event is specified in the window / tab that started SSE, the event will call an event added with addEventListener to itself new EventSource , if it does not have a named event the onmessage p>

  • data

    Send a string to onmessage , if you need multiple lines it will be necessary to start with data: , EventSource will receive all concatenated lines, line breaks will be removed

  • id

    It's used to identify the event, of course it can change, I think it's more to use to know who's calling what.

  • retry

    Set the time to reconnect when trying to send an event, if the script on the server side is not in loop, EventSource ends alone and tries again after the last time set in retry (if set), otherwise I think it uses default time, apparently it also tries to connect again if it has problems with connection.

Support

Depending on the caniuse browsers that support SSE are:

  • Chorme 6
  • Firefox 6
  • Safari 5
  • Android 4.4 native browser
  

Note: Internet Explorer and Microsoft Edge do not support SSE, Edge is under construction,

Some BUGs or related support details:

  • CORS in EventSource is only supported from Firefox 10+, Opera 12+, Chrome 26+, and Safari 7.0 +.

  • Until version 36 of Firefox there was a bug, perhaps there was a loss of connection EventSource itself did not try to reconnect, despite what was said by caniuse it is possible to get around this used to property evtSource.readystate to check which state:

    • Returns 0 if you are still connecting
    • Returns 1 if it is open
    • Returns 2 if it is closed, that is, you can add setTimeout to check it and if 2 yourself can try to reopen.
  • Until Firefox 52 there was no support for EventSource on web / shared workers

Testing the SSE

MDN left an example in PHP: link , however I created a simpler example, if using PHP, create a script by calling chatbox.html (not must be .php , but it does not make any difference in this case) with this content:

<!DOCTYPE html>
<html>
<head></head>
<body>

<button id="close">Terminar conversa</button>
<div id="chatbox"></div>

<script type="text/javascript">
var btnClose = document.getElementById("close");
var chatbox = document.getElementById("chatbox");
var evtSource = new EventSource("chat.php");

evtSource.onmessage = function(e) {
    var n = document.createElement("p");

    n.innerHTML = "message: " + e.data;
    chatbox.appendChild(n);
};

btnClose.onclick = function () {
    evtSource.close(); //Finaliza a conexão do SSE
};
</script>
</body>
</html>

And then do not create a file with the name chat.php in the same folder and add this content:

<?php
header('Content-Type: text/event-stream');

$canned = array(
    'Oi?',
    'Quer tc?',
    'você é de onde?',
    'Poderia me ajudar com uma duvida de JS?',
    'já usou o stack overflow?',
    'Vamos jogar um fut?'
);

$size = count($canned) - 1;

echo 'data: <strong>Você entrou na sala!</strong>';

echo "\n\n"; //Requer duas quebras de linha


//Loop "infinito"
while (1) {

    //Pega uma "mensagem pronta" aleatória
    $response = $canned[mt_rand(0, $size)];

    echo 'data: ', htmlentities($response);

    echo "\n\n"; //Requer duas quebras de linha

    flush();

    //Varia entre 1 e 4 segundos para que o PHP envia uma nova mensagem para o SSE
    sleep(mt_rand(1, 4));
}

This script simulates a person sending messages to you, it's just to understand the behavior

    
07.06.2017 / 06:05
2

An important point to consider is that IE does not support SSE, you should use a polyfill like this if you want or a library such as Yaffle

Server Sent Events generates less traffic on the server because the client does not have to request data from the server to find that nothing has changed, information is sent only when it is available.

    
07.06.2017 / 05:46