0

I have a web application connecting to a PHP script with a javascript xmlhttprequest I'm trying to check for when something server side changes. I've only been able to check by sending a ping to the page every second like

javascript

function stayConnected(){
  setTimeout(function(){
    xmlhttp.send();
  },1000);
}

php

<?php
  if(update())echo "there's an update";
  flush();
?>

This is super intensive for the user and the server

Is this better

javascript

xmlhttp.onreadystatechange = function(){
  if(server.xml.readyState == 4 &&
    server.xml.status == 200){
    doSomething(xmlhttp.responseText);
    xmlhttp.send();
  }
}

php

<?php
  for( $i = 0; i < 120; i++){
    if(update()){
      echo "there's and update";
      break;
    }
    sleep(1000);
  }
  flush();
?>

The second solution seems better for the viewer but does it hurt the server? There is no way for me to check the server load very well. Is there a better solution?

haelmic
  • 541
  • 4
  • 18

2 Answers2

1

This is a reprint of my earlier answer, from this board.

You could use Server Sent Events. The flow is as follows:

  1. Each user subscribes to a channel (think of it as registering an event listener on a connection). On the server side, a script is running continuously to track for changes
  2. A user posts an update to the server.
  3. The script notices the update and issues an event
  4. All clients who subscribed to the channel receive the event, read its data property and update their local models.

See this introduction, with sample PHP implementation.

You could also use Web Sockets. Here is a comparison of the two. Before implementing either, consider browser compatibility.

Community
  • 1
  • 1
BeetleJuice
  • 39,516
  • 19
  • 105
  • 165
1

There are several options you have:

Polling

This is the first option you mentioned. A client has to request every x time units to ask for updates. This results in many requests. Just think about 100 users that asks for updates every second, this results in 6000 requests per minute. In many cases it will happen that the requests queue and it's not real time anymore.

Long Polling

Here the client sends a request and the on the server you have a loop which checks for updates (somehow like your second example). The respond will be send as soon as there is an update. This results in many parallel threads to handle for the server. 100 users makes 100 threads …

Both solutions are not optimal. Instead we should use a persistent connection for the communication.

There are two options for persistent connections:

Web Sockets

WebSockets provide a persistent connection between a client and server that both parties can use to start sending data at any time. In the end this an event loop, but you don't have to care about this. Advantage is, that this is another protocol that is specialised on real time connections! WebSockets are event-based, so it's just using only one thread.

Server Sent Events

It's very similar to WebSockets. You open a persistent connection on clientside to the server, but over HTTP. Main difference is that SSE connections can only push data to the client.

Conclusion

So in practice: Since everything that can be done with SSE can also be done with WebSockets and the browser support for WebSockets is much better than for SSE, I think this is the best option you can go with. For example: IE / Edge supports WebSockets but not SSE

Maybe you could use Ratchet as a framework for WebSockets for PHP: http://socketo.me/

But I have to give you the hint that PHP is not made for heavy real time applications. It's that your use-case, maybe you should use node.js for backend since JavaScript is naturally event-based to fit such use-cases.

Community
  • 1
  • 1
ScientiaEtVeritas
  • 5,158
  • 4
  • 41
  • 59
  • Your answer was really good. I've marked as the correct answer but I don't have access to the server admin privileges and there for I'm unable to use web sockets. Is SSE the only other solution? does IE have something instead. – haelmic Jul 18 '16 at 07:56
  • If you want the support of all mayor browsers, I would also consider using long polling. Famous frameworks like Comet are using long polling and they work perfectly good. Also many frameworks are using long polling as a fallback for websockets (e.g. socket.io). For implementation maybe take a look at: https://stackoverflow.com/questions/333664/how-do-i-implement-basic-long-polling – ScientiaEtVeritas Jul 18 '16 at 13:34
  • What you also could do is that you check whether the client supports Server Sent Events and if so you use this and long polling only as fallback if the client does not support SSE. – ScientiaEtVeritas Jul 18 '16 at 15:59