title: "E04. Receive SSE on the Client" order: 51
cpp-httplib ships a dedicated sse::SSEClient class. It handles auto-reconnect, per-event-name dispatch, and Last-Event-ID tracking for you — so receiving SSE is painless.
#include <httplib.h>
httplib::Client cli("http://localhost:8080");
httplib::sse::SSEClient sse(cli, "/events");
sse.on_message([](const httplib::sse::SSEMessage &msg) {
std::cout << "data: " << msg.data << std::endl;
});
sse.start(); // blocking
Build an SSEClient with a Client and a path, register a callback with on_message(), and call start(). The event loop kicks in and automatically reconnects if the connection drops.
When the server sends events with an event: field, register a handler per name via on_event().
sse.on_event("message", [](const auto &msg) {
std::cout << "chat: " << msg.data << std::endl;
});
sse.on_event("join", [](const auto &msg) {
std::cout << msg.data << " joined" << std::endl;
});
sse.on_event("leave", [](const auto &msg) {
std::cout << msg.data << " left" << std::endl;
});
on_message() is the generic fallback: it receives every event that has no handler registered through on_event(). With on_event("message", ...) registered as above, message events go there instead.
sse.on_open([] {
std::cout << "connected" << std::endl;
});
sse.on_error([](httplib::Error err) {
std::cerr << "error: " << httplib::to_string(err) << std::endl;
});
Hook into connection open and error events. Even when the error handler fires, SSEClient keeps trying to reconnect in the background. The exceptions are a 204, 403, or 404 response, after which it stops.
If you don't want to block the main thread, use start_async().
sse.start_async();
// main thread continues to do other things
do_other_work();
// when you're done, stop it
sse.stop();
start_async() spawns a background thread to run the event loop. Use stop() to shut it down cleanly.
You can tune the reconnect interval and maximum retries.
sse.set_reconnect_interval(5000); // 5 seconds
sse.set_max_reconnect_attempts(10); // up to 10 (0 = unlimited)
If the server sends a retry: field, that takes precedence.
SSEClient tracks the id of each received event internally and sends it back as Last-Event-ID on reconnect. As long as the server sends events with id:, this all works automatically.
std::cout << "last id: " << sse.last_event_id() << std::endl;
Use last_event_id() to read the current value.
Note:
SSEClient::start()blocks, which is fine for a one-off command-line tool. For GUI apps or embedded in a server, thestart_async()+stop()pair is the usual pattern.For the server side, see E01. Implement an SSE server.