What’s the difference between SSE and Ajax?

Asked

Viewed 374 times

6

I’m looking to update a div which contains a customer’s credits, so update in the Bank the amount of his credits and I am using the setInterval:

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

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

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

2 answers

9


Ajax is a normal HTTP request, but runs on background, Ajax is to be more exact is a "way" to use the API XmlHttpRequest asynchronously, but anyway the request is a normal HTTP request, it once requests the reply and closes the request, more details on:

The server-sent Events (SSE) is different, he’s over similar at the Websocket, however other than Websocket, SSE can work on a normal HTTP server, as you may know PHP, Asp.net-mvc and other web technologies run on server side and only send you the reply when you request/request, so when you do it:

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

You’ll be in a kind of persistent connection, namely the api.php can stay in an infinite loop, without ever ending, instead of you catch the answer is as if PHP sent you the answer at the time you want it, 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 will send a request" (relatively speaking) to the client-side, and you will be watching with:

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

SSE format

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

  • Event:

    If specified an event will be triggered in the window/tab that started SSE, the event will call an event added with addEventListener to own new EventSource, if you do not have a named event the onmessage

  • date

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

  • id

    It is used to identify the event, of course it can change, I believe it is more for use to know who is calling what.

  • Retry

    Sets the time to reconnect when trying to send an event, if the server-side script is not looped EventSource finishes alone and tries again after the last time set in retry (if set), otherwise I believe it uses the default time, apparently it also tries to connect again if you have problems with connection.

Support

According to the kennel the browsers that support SSE are:

  • Chorme 6
  • Firefox 6
  • Safari 5
  • Native Android Browser 4.4

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

Some Bugs or details about support reported:

  • 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, there was a loss of connection itself EventSource did not attempt to reconnect, despite what was said by kennel It is possible for you to circumvent it used property evtSource.readystate to check the state:

    • Returns 0 if you’re still connecting
    • Returns 1 if it’s open
    • Returns 2 if it is closed, that is, you can add a setTimeout to check in and check out 2 you can even try to reopen.
  • Until Firefox 52 there was no support for EventSource in web/Shared Workers

  • Eventually Antivirus software programs might block or cause some conflict (I’m not sure how it happens, if I find something about this I will edit the answer).

Testing the SSE

To MDN left an example in PHP: https://github.com/mdn/dom-examples/tree/master/server-sent-events, however I created a simpler example, if using PHP, create a script by calling chatbox.html (doesn’t have to be .php, but it makes no 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 in the same folder create a file with the name chat.php 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

  • 5

    Let’s play a Fut? only if it is now xD!

  • SSE is lighter than Ajax for the server then?

  • The PHP script that runs on the server, it is automatically destroyed as soon as the connection is terminated? You would need to use the connection_aborted () ?

  • 1

    @Jeffersonquesado This "lightweight" thing is very relative, I mean, the PHP script will stay open constantly, so it won’t need to be reinterpreted (php is not compiled), it helps the server, but it is something that can be quite relative, depends a lot on what you did in the back-end, so I didn’t cite the question of better or worse.

  • @Everson I will check and warn you.

  • @Guilhermenascimento I imagined that with SSE generates less traffic and less overhead due to http loads. I wasn’t talking about any particular backend. Overall, by your response, it seems to avoid even a good weight from an Ajax call

  • 1

    @Jeffersonquesado yes basically this is what happens with persistent connections usually, decrease HTTP requests helps a lot, especially if it’s something really heavy on the back-end side, but if it’s a light thing, maybe it doesn’t feel much better, I mean there probably will be, but it will be so minimal that you won’t even feel, I will try to confirm the details, if the persistent connection can be shared with all tabs or the same script that is running send reply to all SSE then I believe you will have a significant gain. Maybe I’ll say something about Websocket, ajax and SSE

Show 2 more comments

2

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

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

Browser other questions tagged

You are not signed in. Login or sign up in order to post.