A new Indy HTTP client / JAX-RS server example is now available on GitHub. The server side generates Server-sent events. Server-sent events (SSE) is a technology enabling a browser to receive automatic updates from a server via HTTP connection.
The example code uses TIdHTTP and TIdEventStream to connect to the server, and writes the incoming events to the console window.
Requirements
- Delphi or Lazarus IDE
- Indy 10.6.2
- Java IDE
- Java EE 8 application server
Client
The SSE client setup in the TIndySSEClient.Create creates a TIdHTTP instance and a TIdEventStream instance.
As recommended, the Accept header is set to 'text/event-stream'
. It also sets the Cache-Control header to 'no-store'
to prevent proxy servers from caching the result.
Our event handler TIndySSEClient.MyOnWrite
is assigned to the TIdEventStreamOnWrite
property.
constructor TIndySSEClient.Create;
begin
inherited Create;
SSE_URL := URL;
EventStream := TIdEventStream.Create;
EventStream.OnWrite := MyOnWrite;
IdHTTP := TIdHTTP.Create;
IdHTTP.Request.Accept := 'text/event-stream';
IdHTTP.Request.CacheControl := 'no-store';
end;
The OnWrite handler decodes the UTF-8 encoded event data and writes it to the console:
procedure TIndySSEClient.MyOnWrite;
begin
WriteLn('Received ' + IntToStr(Length(ABuffer)) + ' bytes');
WriteLn;
WriteLn(IndyTextEncoding_UTF8.GetString(ABuffer));
...
end;
Server (main REST method)
The server generates the server-sent event and places a Stock instance in its data part:
@GET
@Path("prices")
@Produces(MediaType.SERVER_SENT_EVENTS)
public void getStockPrices(@Context SseEventSink sseEventSink) {
int lastEventId = 1;
while (running) {
Stock stock = getNextTransaction();
System.out.println("Send event ...");
OutboundSseEvent sseEvent = this.eventBuilder
.name("stock")
.id(String.valueOf(lastEventId))
.mediaType(MediaType.APPLICATION_JSON_TYPE)
.data(Stock.class, stock)
.reconnectDelay(3000)
.comment("price change")
.build();
sseEventSink.send(sseEvent);
lastEventId++;
}
sseEventSink.close();
}
Additional notes
- this is the first draft of a SSE client, which does not support features such as reconnect
- the example assumes that every call of MyOnWrite contains exactly one event, teminated by a sequence of two line separators (cr lf / cr / lf) so that no extra code is required to do proper event stream parsing
Full source code
https://github.com/michaelJustin/indy-sse-jaxrs
References
You must be logged in to post a comment.