Dear Brian,
I've looked into it and tried to come with a fairly simple example. The question you have not addressed is, where the events are coming from that you want to distribute. In the example below, the events are triggered from a scheduled procedure. There is certainly much more which can be done: Define a small API, and/or integrate with the message-redirector, etc. etc.
Hope you find this simple example useful!
-g
Subscriber. This script is called by the EventSource()
call from the HTML page (see below). Place it e.g. into /www/timer-sse.tcl
set channel [ns_connchan detach]
ns_connchan write $channel [append _ \
"HTTP/1.1 200 OK\r\n" \
"Cache-Control: no-cache\r\n" \
"X-Accel-Buffering': no\r\n" \
"Content-type: text/event-stream\r\n" \
"\r\n"]
ns_connchan write $channel "data: Hi There!\n\n"
ns_connchan write $channel "data: Start time is: [clock format [clock seconds]]\n\n"
nsv_set sse_subscribers $channel 1
Background task checking for subscribers and delivering messages to them.
Place this e.g. into some *-init.tcl file such this is registered during startup:
nsv_set sse_subscribers {} {}
ns_schedule_proc -thread 5s {
foreach subscriber [nsv_array names sse_subscribers] {
if {$subscriber eq ""} continue
try {
ns_connchan write $subscriber "data: A voice from the background says: it is now [clock format [clock seconds]]!\n\n"
} on ok {result} {
} on error {errorMsg} {
ns_log notice "SSE SEND failed: '$errorMsg'"
ns_connchan close $subscriber
nsv_unset sse_subscribers $subscriber
}
}
}
Sample page for testing (remove the space before "script>"):
<!DOCTYPE html>
<html>
<meta content="utf-8" http-equiv="encoding">
<title>Timer SSE demo</title>
<body>
<h1>Getting server updates</h1>
<div id="result"></div>
< script>
if(typeof(EventSource) !== "undefined") {
var source = new EventSource("/timer-sse.tcl");
source.onmessage = function(event) {
document.getElementById("result").innerHTML += event.data + "<br>";
};
} else {
document.getElementById("result").innerHTML = "Sorry, your browser does not support server-sent events...";
}
</script>
</body>
</html>