Implementing Server Side Events using Sparkle

Hello

Do you have any examples on how to use Sparkle HTTP server (http.sys) with Server Side Events (https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events).

I've been experimenting without success and would appreciate any advise .

Initially just trying a simple scenario where Sparkle server module would simply send a timestamp every 1 seconds.

I'm using a sample for client side that just logs data (https://github.com/mdn/dom-examples/blob/master/server-sent-events/index.html using my url) and static serving it from same sparkle server.

So far have this though as mentioned it it's not working - ProcessRequest is reached and run ok but client is not showing any data and similarly browser debug tools do not show any data in the EventStream

procedure TServerSideEventsModule.ProcessRequest(const C: THttpServerContext);
var
Writer: TStreamWriter;
begin
inherited;
C.Response.StatusCode := 200;
C.Response.Chunked := true;
C.Response.Headers.Clear;
C.Response.ContentType := 'text/event-stream';
C.Response.Headers.SetValue('Connection','keep-alive');
C.Response.Headers.SetValue('Cache-Control','no-cache');

Writer := TStreamWriter.Create(C.Response.Content, TEncoding.UTF8);
Writer.AutoFlush := true;

try
while not C.Response.Closed do
begin
Writer.Write('data: ' + DateTimeToStr(now) + '\n\n');
sleep(1000);
end;
finally
Writer.Free;
end;
end;

Thanks

I'll answer my own question - after some further testing i realized the chunks were not being sent since default minimum chunk size is 16K.

For now i just set it to 5 bytes and tings started working
C.Response.MinChunkSize := 5;

I think the only follow-up question i have

  1. Is there a built-in mechanism for THttpServerModule ProcessRequest to know it should be stopping - I'm basically doing a busy wait loop so i'd need to add some a check for some "server shutting down" type of flag/event. Client side is OK as that would be captured

  2. Is there a better way you can suggest to implement server side events ?

Thanks

One thing you could do is check the TSparkleHttpSysDispatcher.IsRunning property. When the server is requested to stop, it will wait for threads to finish, until a timeout happens. Then, IsRunning is set to false.

I don't think there would be a better way to implement this, I guess.

I have a question about server sent event.Client side I connect to server and close but I don't take data value.Here my javascript code what is the wrong please help me.

unction start() {

if (!window.EventSource) {
// IE or an old browser
alert("The browser doesn't support EventSource.");
return;
}

var eventSource = new EventSource("http://localhost:8000/tms/generic/");
eventSource.onopen = function(event) {
log("Event: open");
};

eventSource.onerror = function(event) {
log("Event: error");
if (this.readyState == EventSource.CONNECTING) {
log(Reconnecting (readyState=${this.readyState})...);
} else {
log("Error has occured.");
}
};

eventSource.onmessage = function(event) {
log("Event: message, data: " + event.data);

};
}

function log(msg) {
denemeh.innerHTML += msg + "
";
}

Sorry, but I don't have experience with server-side events, never used it either in JavaScript or Sparkle. Maybe @Wilson_Jason can provide some info if he was successful in implementing this.

I recognize a error ;
ERROR
Uncaught TypeError: Cannot read property 'length' of undefined | TypeError: Cannot read property 'length' of undefined at Object.ProcessAccelerator

I see you have duplicated this request at server sent event.

I need a answer about SSE.