In this second part, a server application uses the Indy HTTP server to provide a HTML page which uses SSE to update its content with data sent from the server.
Part 2: the basic demo application, some client data added
Ingredient #1: the HTML page with JavaScript
The script now reads two data items from the ping event:
- the time stamp, now sent from the server in proper ISO 8601 format
- the peer data, which is the remote ip address and port number
<!DOCTYPE html>
<html>
<head>
<title>SSE example</title>
</head>
<body>
<script>
const evtSource = new EventSource("sse");
evtSource.addEventListener("ping", (event) => {
const newElement = document.createElement("li");
const eventList = document.getElementById("list");
const time = JSON.parse(event.data).time;
const peer = JSON.parse(event.data).peer;
newElement.textContent = `ping at ${time} from ${peer}`;
eventList.appendChild(newElement);
});
</script>
<ul id="list">
</ul>
</body>
</html>
The code is based on the article Using server-sent events on MDN
https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events
Ingredient #2: server side code
The TIdHTTPServer subclass now contains a private method to provide client-specific data in the /sse resource.
function TMySSEServer.BuildContentText(AContext: TIdContext): string;
begin
Result := '';
repeat
Result := Result + 'event: ping' + #13 +
Format('data: {"time": "%s", "peer": "%s:%d"}',
[DateToISO8601(Now, False), AContext.Binding.PeerIP,
AContext.Binding.PeerPort]) + #13#13;
Sleep(100);
until Random < 0.8;
end;
The DoCommandGet method uses the BuildContentText function to provide the event data:
procedure TMySSEServer.DoCommandGet(AContext: TIdContext;
ARequestInfo: TIdHTTPRequestInfo;
AResponseInfo: TIdHTTPResponseInfo);
begin
if ARequestInfo.Document = '/sse' then
begin
AResponseInfo.ContentType := 'text/event-stream';
AResponseInfo.CacheControl := 'no-store';
AResponseInfo.ContentText := BuildContentText(AContext);
end
else
begin
AResponseInfo.ContentType := 'text/html';
AResponseInfo.ContentStream :=
TFileStream.Create('index.html', fmOpenRead);
end;
AResponseInfo.CharSet := 'UTF-8';
end;
Output
When the browser navigates to http://localhost
, the server will provide the HTML and the embedded JavaScript will start reading data from the address http://localhost/sse
and receive one or more events.
The ping event, which the server sends to the browser, now includes the server time in ISO 8601 format and the peer IP address and port.

Next part
In the next part, the data stream will be sent continuously.
Discover more from Habarisoft Blog
Subscribe to get the latest posts sent to your email.