2

I have seen tutorials on the net where the author sets up SSE/EventSource and in the server PHP script echos out some data and then calls ob_flush() and flush() to send the data back to the client browser. And this works fine and new data gets pushed to the client every 3 seconds.

But I also read a comment from somebody saying that this is the wrong way to use SSE. This person said that the whole point of SSE is that the server is supposed to maintain the connection and the reason the new data gets pushed to the client using the above method is because the EventSource realises the server disconnected. This person said the server should be using a loop and pushing the data out every few seconds by using sleep.

So, is this the case? Should SSE be implemented by having a loop on the server and pushing data, using sleep() to pace the pushing?

Simon Martin
  • 4,203
  • 7
  • 56
  • 93
sonicboom
  • 4,928
  • 10
  • 42
  • 60
  • Also, check out this question: http://stackoverflow.com/questions/9565290/how-to-fire-eventsource-sse-events – Šime Vidas Jan 01 '13 at 15:40
  • "On the server-side, the script (...) sends messages in the following form, with the text/event-stream MIME type." What has that got to do with my question? And that other link you posted is also irrelevant to my question which is what is the recommended way of implementing SSE, .ie should we always use an infinite loop on the server? – sonicboom Jan 01 '13 at 15:56
  • That other question is *"How to fire SSE events?"*, and you're asking *"How to implement SSE?"*. It may not be the same exact question, but I don't think that other question is irrelevant. – Šime Vidas Jan 01 '13 at 16:08
  • One of the great things about stackoverflow is helping each other out so that we don't have to go digging through lengthy jargon filled standards documents that may or may provide an answer. FWIW I went and looked through the standard in your link and didn't find an answer. – sonicboom Jan 01 '13 at 16:39
  • `sleep()` alone won't push the data to the web-browser, will it? `ob_flush(); flush();` will push the data, but I'm not sure if that's the only method to do it. – Šime Vidas Jan 01 '13 at 16:58
  • sleep() is just for pacing the pushing. – sonicboom Jan 01 '13 at 17:13
  • From what I'm seeing, the tutorials use `ob_flush(); flush();` to push the data, and `sleep();` for pacing. What's the alternative to this? – Šime Vidas Jan 01 '13 at 17:16
  • This is off topic, this is not what my question is about. My question is highlighted in bold in my post. – sonicboom Jan 01 '13 at 17:28
  • Aren't those tutorials using a loop, and `sleep();`? If not, how are they making sure that the data is sent out every 3 seconds? – Šime Vidas Jan 01 '13 at 17:31
  • I know that data can get pushed either by a loop or if EventSource reconnects. My question is which is the best practise way of doing it. There are lots of tutorials out there that don't use a loop and I have read somebody saying that such tutorials miss the point of SSE, so I'm trying to get clarification here. – sonicboom Jan 01 '13 at 17:46
  • Could you provide a link to a tutorial that doesn't use a loop? – Šime Vidas Jan 01 '13 at 17:52
  • http://www.developerdrive.com/2012/03/pushing-updates-to-the-web-page-with-html5-server-sent-events/ and http://www.html5rocks.com/en/tutorials/eventsource/basics/ – sonicboom Jan 01 '13 at 18:23
  • 1
    From what I understand, the server is **not** supposed to close the connection, so the tutorial you linked above is doing it wrong. I'm not a PHP programmer, but the solution with a loop and `sleep();` seams reasonable (that's how the [MDN article](https://developer.mozilla.org/en-US/docs/Server-sent_events/Using_server-sent_events) does it). – Šime Vidas Jan 01 '13 at 18:41
  • +1 Now that I finally understand your question, I must say, this is a good question. `:)` – Šime Vidas Jan 01 '13 at 18:45

1 Answers1

2

I don't know PHP well enough to say if sleep() the only way, but yes the point on the server side is to keep the connection open so that new data can be sent to the client at any time without opening a new connection.

There are a couple of wrinkles to this. Since SSE is designed to work with traditional shared web hosting, there is expected to be a timeout on the server side at some point (30 seconds or 60 seconds, in PHP depending on max_execution_time and/or set_time_limit(). This leads to the second wrinkle, because the server is expected disconnect periodically the browser is expected to automatically re-establish the connection, which explains the behaviour seen in the blog post you mention - the browser automatically re-connects so it appears as if SSE is working.

I think with sleep() you lose some of the real time aspect as if you're only sending data every second anyway you might as well use AJAX polling, but I know of no better way in PHP than the loop/sleep approach. Also, if you're using PHP for SSE, remember that the session object is single threaded so if you hold it open in your SSE page it will block any other scripts (eg. AJAX requests) which require access.

robertc
  • 74,533
  • 18
  • 193
  • 177
  • If that is the case then isn't looping completely useless in PHP as no new request can be handled due to the infinite loop? – sonicboom Jan 01 '13 at 22:02
  • @sonicboom I'm not sure what you mean? Why would no new request be handled? – robertc Jan 01 '13 at 23:22
  • Because is there is one thread per session and the we enter an infinite loop to send out SSE messages to a client every few seconds, then how can we handle a new request from that client when the thread associated with the session is iterating over the loop. – sonicboom Jan 02 '13 at 02:02
  • @sonicboom Sorry, should have been more clear - it's the session object which is single threaded, [so don't hold it open](http://php.net/manual/en/function.session-write-close.php). – robertc Jan 02 '13 at 08:16