Last active
December 4, 2019 10:12
-
-
Save PixlRainbow/b720c965dde920cc404095848942ad02 to your computer and use it in GitHub Desktop.
SSE using cpp-httplib
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <httplib.h> | |
#include <cstdio> | |
#include <chrono> | |
using namespace httplib; | |
bool reconnect = true; | |
unsigned long retry = 3000; | |
//warning: events do not necessarily correspond with chunks | |
//a chunk may contain more than one event | |
bool chunk_callback(const char *data, uint64_t len){ | |
//warning: this callback runs async | |
std::string msg(data, len); | |
if(msg.rfind("retry: ", 8) == 0){ | |
retry = std::stoul(msg.substr(7)); | |
printf("detected timeout: %lu\n", retry); | |
}; | |
printf("new chonk: %s\n", msg.c_str()); | |
return true; | |
}); | |
int main(){ | |
// http://samshull.com/server-sent/events.php | |
Client cli("samshull.com"); | |
cli.follow_location(true); | |
const httplib::Headers headers = { | |
{ "Accept", "text/event-stream" }, | |
{ "Connection", "Keep-Alive"} | |
}; | |
while(reconnect){ | |
auto res = cli.Get("/server-sent/events.php", headers, chunk_callback); | |
if(res){ | |
printf("HTTP %i\n", res->status); | |
//check that response code is 2xx | |
reconnect = (res->status / 100) == 2; | |
} | |
else{ | |
printf("SSE stream ended. Will retry in %f seconds\n", retry/1000.0); | |
std::this_thread::sleep_for(std::chrono::milliseconds(retry)); | |
printf("Retrying\n"); | |
} | |
} | |
printf("closed connection\n"); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <chrono> | |
#include <cstdio> | |
#include <httplib.h> | |
using namespace httplib; | |
uint64_t event_id; | |
void create_event(uint64_t offset, DataSink sink, Done done){ | |
std::string eventdata; | |
std::this_thread::sleep_for(std::chrono::seconds(3)); | |
if(event_id == 0) | |
//tell client to retry in 15s if disconnected | |
eventdata = "retry: 15000\n\n"; | |
else | |
{ | |
eventdata += "id: "; | |
eventdata += std::to_string(event_id); | |
eventdata += "\ndata: This is an event message\n\n"; | |
} | |
event_id++; | |
sink(eventdata.c_str(), eventdata.length()); | |
} | |
int main(void) { | |
Server svr; | |
svr.Get("/eventsrc",[](const Request &req, Response &res){ | |
res.set_chunked_content_provider(create_event); | |
res.set_header("Content-Type", "text/event-stream"); | |
}); | |
svr.listen("localhost", 8080); | |
return 0; | |
} |
@kreativnix sorry! yhirose updated httplib.h upstream and changed the content streaming interface on the server side. I have edited this gist to reflect his changes.
Hi PixlRainbow, I thank you very much for the quick reaction. I did not believe that in advance. Now I can continue to test.
My goal is to find a relative simple possibility to program in a RasPi 3B+ a program including webserver functionality with SSE, because I have measurment data to display. Maybe this httplib will help!
Many thanks and a nice weekend
Gerald
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Unfortunately your program can not compile:
error: ‘struct httplib::Response’ has no member named ‘content_producer’
res.content_producer = create_event;
I have the newest httplib.h!
Gerald