Project

General

Profile

[Solved] Need help for setting up Server-Sent Events

Added by joo over 4 years ago

Hi,
I am using ubuntu 18.04 with lighttpd 1.4.45 and have been playing with Server-sent Event functionality, and unfortunately, not able to get it working. When I open the test_sse.html page, I see that the cgi program is spawned but no data is returned from my cgi program. (I use FireFox 72.0.1)

lighttpd.conf:
server.modules = (
"mod_access",
"mod_alias",
"mod_cgi",
"mod_compress",
"mod_redirect",
)

server.document-root = "/var/www/html" 
server.upload-dirs = ( "/var/cache/lighttpd/uploads" )
server.errorlog = "/var/log/lighttpd/error.log" 
server.pid-file = "/var/run/lighttpd.pid" 
server.username = "www-data" 
server.groupname = "www-data" 
server.port = 80

index-file.names = ( "index.php", "index.html", "index.lighttpd.html" )
url.access-deny = ( "~", ".inc" )
static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )

compress.cache-dir = "/var/cache/lighttpd/compress/" 
compress.filetype = ( "application/javascript", "text/css", "text/html", "text/plain" )

    default listening port for IPv6 falls back to the IPv4 port
        Use ipv6 if available
        #include_shell "/usr/share/lighttpd/use-ipv6.pl " + server.port
        include_shell "/usr/share/lighttpd/create-mime.assign.pl" 
        include_shell "/usr/share/lighttpd/include-conf-enabled.pl" 

$HTTP["url"] =~ "^/cgi-bin/" {
alias.url += ( "/cgi-bin/" => "/var/www/cgi-bin/" )
cgi.assign = ( ".cgi" => "",
".py" => "/usr/bin/python",
".php" => "/usr/bin/php" )
}

cgi.assign = (
".cgi" => "",
".py" => "/usr/bin/python",
".php" => "/usr/bin/php" 

)

test_sse.html (in /var/www/html folder)
<!DOCTYPE html>
<html>
<body>

<h1>Getting server1 updates</h1>
<div id="result"></div>

<script>
if(typeof(EventSource) !== "undefined") {
var source = new EventSource("cgi-bin/test_sse.cgi");

source.onmessage = function(event) {
    document.getElementById("result").innerHTML += event.data + "&lt;br&gt;";
  };
} else {
  document.getElementById("result").innerHTML = "Sorry, your browser does not support server-sent events...";
}
&lt;/script&gt;

</body>
</html>

test_sse.c (A simple cgi program written in C) (in /var/www/cgi-bin/test_sse.cgi)
#include "stdio.h" 
#include "time.h" 
#include <unistd.h>

int main(void) {
  time_t now;
  for (;;) {
    printf("Cache-Control: no-cache\n\n");
    printf("Content-Type: text/event-stream\n\n");
    now = time(NULL);
    printf("data: the server time is %ld\r\n",now );
    sleep(2);
  }
}

Could someone please help me what I am missing...

Thanks

Joo


Replies (2)

RE: Need help for setting up Server-Sent Events - Added by gstrauss over 4 years ago

By default, lighttpd buffers the output of CGI before sending to client. For your use case, I think you want to add to lighttpd.conf:

server.stream-response-body = 2

In your C code, you should only have a single "\n" after each response header, and a double "\n\n" at the end of the headers. Your client might require "\r\n" and "\r\n\r\n" instead of "\n" and "\n\n"

If you're using stdio, which you are doing with printf(), you need to set the buffering, or else the output will be block buffered by the libc stdio.

At the top of your main(), you need

setvbuf(stdout, NULL, _IOLBF, 0);

Please ensure that the rest of the output produced by the CGI is reasonable for the client consuming the server event stream.

RE: [Solved] Need help for setting up Server-Sent Events - Added by joo over 4 years ago

Perfect. Thank you very much.

    (1-2/2)