Event Streaming to Web Browsers
By Arve Bersvendsenvirtuelvis. Friday, September 1, 2006 2:28:56 PM
One cool feature we added to Opera 9 is Server-Sent Events from the WHATWG Web Applications 1.0 specification. Using SSE you can push DOM events continously from your web server to the visitor's browser. This creates a lot of exciting opportunities for web application authors.
Traditionally, when building an Ajax application, the browser continually polls the server, sending requests to the server, asking to get data back, making new HTTP requests for every single poll, putting more strain on the server than needed.
The event streaming approach instead opens a persistent connection to the server, sending data to the client when new information is available, eliminating the need for continuous polling. This method for doing remoting offers a tremendous advantage, since the server no longer has to handle the overhead associated with clients asking for new data. Instead, the server simply sends back data every connected client when appropriate, thus reducing the load on the server, with the added advantage of offering instant feedback to the user.
Opera Web Chat
To provide you with a starting point on how to build your own event streaming application, we have built Opera Web Chat. This is a web based chatroom offering some of the features from the built in to the Opera IRC client. Currently the chat only offers one single chatroom. (A screenshot is available here)
Keep in mind that it is an experimental service, which means it may not always be available for use.
How to use Server-Sent Events
To use Server-Sent Events in a web application, add an <event-source> element to the document, with a src attribute pointing to a event source URL. This URL should provide a persistent HTTP connection that sends a data stream containing the events. The connection must use the content type application/x-dom-event-stream.
It is possible to send events with any name, and specify the properties of the event object. Opera 9.01 only supports the data property of the event, so this is what we are going to use in these examples.
The server side event source writes the events whenever they occur, and sends them over HTTP to the client. This is a basic example of event data. This is more thoroughly explained in the specification.
Event: server-time
data: [time on the server]
Event: the-answer
data: 42
This will send two events to the browser, and it's possible to catch them as DOM events. The following JavaScript example listens for the "server-time" event, and alerts the content.
document.getElementsByTagName("event-source")[0]
.addEventListener("server-time", eventHandler, false);
function eventHandler(event)
{
// Alert time sent by the server
alert(event.data);
}
This is a very simple Python CGI example which sends a new event every 3 seconds. Every event is named "server-time", and sends an event with the data property set to the current time of the server in seconds.
Keep in mind that when a CGI script outputs data, there is no guarantee that it is sent immediately. There are often caching mechanisms and so on in place. For this reason it may be necessary to explicitly flush the output.
Here is the example code written in python.
#!/usr/bin/python
import sys
import time
print "Content-Type: application/x-dom-event-stream\n\n"
while True:
print "Event: server-time"
print "data: %f\n" % (time.time(),)
sys.stdout.flush()
time.sleep(3)
The same example written in PHP:
<?php
header("Content-Type: application/x-dom-event-stream");
while(true) {
echo "Event: server-time\n";
$time = time();
echo "data: $time\n";
echo "\n";
flush();
sleep(3);
}
?>
Opportunities
In addition to the chat application we made, there are lots of different applications that can be made with Server-Sent Events. For instance games or instant messaging clients, such as MSN Messenger, Jabber or AIM. You could also build stock and news tickers, status and log file monitors, or anyhing you can come up with.
What will you build?


1 2 Next »
GuillermoGuille # Friday, September 1, 2006 4:12:51 PM
I still can't make the chat sample to work.
Anonymous # Friday, September 1, 2006 4:23:25 PM
Brian HuismanGreyWyvern # Friday, September 1, 2006 4:26:29 PM
Let's see when the first two player action widget debuts!
Anonymous # Friday, September 1, 2006 5:19:00 PM
porneL # Friday, September 1, 2006 6:28:10 PM
Anonymous # Friday, September 1, 2006 7:40:57 PM
velmu # Friday, September 1, 2006 8:42:02 PM
Remco Lantingremcolanting # Friday, September 1, 2006 10:32:30 PM
This feature is just new to the general public, so there could still be bugs, but other than that, it's just a great new feature
grafio # Friday, September 1, 2006 10:36:10 PM
piper-noiter # Friday, September 1, 2006 10:50:23 PM
Anonymous # Saturday, September 2, 2006 3:52:49 AM
Anonymous # Saturday, September 2, 2006 5:59:10 AM
Evgeny Stepanischevbolk # Saturday, September 2, 2006 7:29:26 AM
<?php
header("Content-Type: application/x-dom-event-stream");
for (;
{
echo "Event: server-time\n",
'data: ', time(), "\n\n";
flush();
sleep(3);
}
?>
"ob_flush" should be use only if "ob_start" was used.
JasmoJazmo # Saturday, September 2, 2006 8:15:19 AM
chesss # Saturday, September 2, 2006 8:20:46 AM
very very cool!!
Anonymous # Saturday, September 2, 2006 9:21:10 AM
Anonymous # Saturday, September 2, 2006 9:23:11 AM
Anonymous # Saturday, September 2, 2006 11:04:57 AM
Haavardhaavard # Saturday, September 2, 2006 12:35:08 PM
http://www.opera.com/support/search/supsearch.dml?index=790
Anonymous # Saturday, September 2, 2006 2:54:10 PM
Anonymous # Sunday, September 3, 2006 2:55:30 AM
Arve Bersvendsenvirtuelvis # Sunday, September 3, 2006 6:00:21 PM
If you have comments in specific about the specification, they are best addressed on the WHATWG mailing list.
Edgar P. NashNetegrof # Monday, September 4, 2006 3:47:40 AM
Janizomg # Monday, September 4, 2006 4:57:46 PM
Had source code for a two player widget for a while... Haven't written the networking part for it though but I have something to base that stuff on. Not very "action" though... a board game.
I'm having trouble getting this stuff running.. might be a problem in my PHP or Apache configuration.
Anonymous # Thursday, September 7, 2006 7:42:13 AM
Anonymous # Thursday, September 7, 2006 5:22:40 PM
Anonymous # Monday, September 11, 2006 8:11:27 AM
Phil Endecottendecotp # Tuesday, September 12, 2006 8:14:03 PM
This new stuff is certainly interesting, and it would have been great if it had existed from day 1. But it will be a long long time before it is widespread in browsers and for now we can get the same effect using regular HTTP.
Elainemezzomama # Tuesday, September 19, 2006 7:10:18 AM
Arve Bersvendsenvirtuelvis # Thursday, September 21, 2006 4:59:25 PM
However: It is entirely possible to build secure applications with authentication using this technology.
Janizomg # Sunday, September 24, 2006 10:30:01 PM
I've written a stand-alone server for SSE with Python. So far it's been performing quite nicely on my 333mhz/64mb ram server box
You can find it from this page with some details on how to use it
http://zeeohemgee.blogspot.com/2006/09/writing-sse-backends-with-python_09.html
Elessar # Friday, October 20, 2006 10:46:32 PM
PHP is handled via a pool conntected over a fastcgi interface. In terms of ressources this is much more server friendly that apache with mpm_prefork/mod_php or similar.
_Grey_ # Wednesday, October 25, 2006 11:27:36 PM
Haavardhaavard # Sunday, October 29, 2006 12:13:03 PM
wykis # Saturday, November 4, 2006 3:21:38 PM
stephenvs # Thursday, November 30, 2006 6:05:58 AM
"; putenv("TZ=Asia/Kuala_Lumpur"); $NTime = "KLTime = ".date("Ymdhis")."
"; $html = $oTime.$NTime; ?> div = document.getElementById('contentdiv'); div.innerHTML = '<?php echo $html; ?>'; ******************
M Amroabadiamroabadi # Tuesday, December 26, 2006 2:22:57 PM
but the question is:
How to open a PERSISTENT connection to the server ?
I'd be thankful if someone kindly clarify this for me
amirsaied # Tuesday, January 9, 2007 7:06:20 PM
Smir # Thursday, September 13, 2007 9:50:53 AM
Now I was writing a small http server, which should send updates to all connected clients, whenever one client connects or disconnects to the event-source. And that was, when I noticed, that server-sent events only work with \n as line ending and not \r\n.
But as far as I understand the HTTP RFC, line endings should be \r\n:
CR = <US-ASCII CR, carriage return (13)>
LF = <US-ASCII LF, linefeed (10)>
CRLF = CR LF
CRLF is used as line-endings.
jacobolus # Friday, November 9, 2007 12:14:58 PM
eddie # Friday, December 14, 2007 9:56:05 AM
Does the server page actually needs an infinite loop? How does the script know there is a new event that needs to be sent to the connected clients?
rio258k # Wednesday, July 30, 2008 4:42:49 PM
Does anyone else have a more detailed example? I've tried to construct this simple demo, but it isn't working!
grafio # Wednesday, October 22, 2008 6:46:21 AM
MyOpera team, please fix this!fearphage # Friday, December 19, 2008 4:28:47 PM
jax510 # Friday, February 6, 2009 1:07:08 PM
MauriceNull # Wednesday, June 24, 2009 4:31:36 PM
I need some help, copied the php example:
<?php header("Content-Type: application/x-dom-event-stream"); while(true) { echo "Event: server-time\n"; $time = time(); echo "data: $time\n"; echo "\n"; flush(); sleep(3); } ?>But if I put this in a file (clock.php), upload it and surf to it in Opera, Opera asks me to download the file. So it doesn't open the page and show the time. Any ideas? THx
kesor # Wednesday, July 1, 2009 2:31:27 PM
I want to do capability sniffing in my javascript, something like this:
var capable = {
eventsource: (typeof(EventSource) == "function"),
activex_htmlfile: (typeof(ActiveXObject) == "function"),
plainxhr: (typeof(XMLHttpRequest) == "function")
}
How can I know that a browser supports the <event-source> tag and event-source events? How can I check for it in my javascript, without checking for browsers and browser versions?
Mauricio Silveiramsilveira # Sunday, July 12, 2009 2:57:55 PM
Drawbacks:
1.) What if someone is accessing 2 pages on the same server: will it keep only 1 connection open or will there be 2 connections active?
2.) What if dozens of thousands of users keep a page open concurrently on non-clustered servers? Scale it to to clustered servers * other dozens!? - By keeping open I mean forgetting it open.
Maybe this feature will find it's place on controlled environments for a better "real-time" application. Using timeouts for sessions
pepijndevos # Monday, October 26, 2009 2:25:31 PM
ESP SolutionsESPWebmaster # Tuesday, January 26, 2010 7:31:10 AM