You've already forked cpp-httplib
							
							
		
			
				
	
	
		
			102 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			102 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#include <atomic>
 | 
						|
#include <chrono>
 | 
						|
#include <condition_variable>
 | 
						|
#include <httplib.h>
 | 
						|
#include <iostream>
 | 
						|
#include <mutex>
 | 
						|
#include <sstream>
 | 
						|
#include <thread>
 | 
						|
 | 
						|
using namespace httplib;
 | 
						|
using namespace std;
 | 
						|
 | 
						|
class EventDispatcher {
 | 
						|
public:
 | 
						|
  EventDispatcher() {}
 | 
						|
 | 
						|
  void wait_event(DataSink *sink) {
 | 
						|
    unique_lock<mutex> lk(m_);
 | 
						|
    int id = id_;
 | 
						|
    cv_.wait(lk, [&] { return cid_ == id; });
 | 
						|
    sink->write(message_.data(), message_.size());
 | 
						|
  }
 | 
						|
 | 
						|
  void send_event(const string &message) {
 | 
						|
    lock_guard<mutex> lk(m_);
 | 
						|
    cid_ = id_++;
 | 
						|
    message_ = message;
 | 
						|
    cv_.notify_all();
 | 
						|
  }
 | 
						|
 | 
						|
private:
 | 
						|
  mutex m_;
 | 
						|
  condition_variable cv_;
 | 
						|
  atomic_int id_{0};
 | 
						|
  atomic_int cid_{-1};
 | 
						|
  string message_;
 | 
						|
};
 | 
						|
 | 
						|
const auto html = R"(
 | 
						|
<!DOCTYPE html>
 | 
						|
<html lang="en">
 | 
						|
<head>
 | 
						|
<meta charset="UTF-8">
 | 
						|
<title>SSE demo</title>
 | 
						|
</head>
 | 
						|
<body>
 | 
						|
<script>
 | 
						|
const ev1 = new EventSource("event1");
 | 
						|
ev1.onmessage = function(e) {
 | 
						|
  console.log('ev1', e.data);
 | 
						|
}
 | 
						|
const ev2 = new EventSource("event2");
 | 
						|
ev2.onmessage = function(e) {
 | 
						|
  console.log('ev2', e.data);
 | 
						|
}
 | 
						|
</script>
 | 
						|
</body>
 | 
						|
</html>
 | 
						|
)";
 | 
						|
 | 
						|
int main(void) {
 | 
						|
  EventDispatcher ed;
 | 
						|
 | 
						|
  Server svr;
 | 
						|
 | 
						|
  svr.Get("/", [&](const Request & /*req*/, Response &res) {
 | 
						|
    res.set_content(html, "text/html");
 | 
						|
  });
 | 
						|
 | 
						|
  svr.Get("/event1", [&](const Request & /*req*/, Response &res) {
 | 
						|
    cout << "connected to event1..." << endl;
 | 
						|
    res.set_chunked_content_provider("text/event-stream",
 | 
						|
                                     [&](size_t /*offset*/, DataSink &sink) {
 | 
						|
                                       ed.wait_event(&sink);
 | 
						|
                                       return true;
 | 
						|
                                     });
 | 
						|
  });
 | 
						|
 | 
						|
  svr.Get("/event2", [&](const Request & /*req*/, Response &res) {
 | 
						|
    cout << "connected to event2..." << endl;
 | 
						|
    res.set_chunked_content_provider("text/event-stream",
 | 
						|
                                     [&](size_t /*offset*/, DataSink &sink) {
 | 
						|
                                       ed.wait_event(&sink);
 | 
						|
                                       return true;
 | 
						|
                                     });
 | 
						|
  });
 | 
						|
 | 
						|
  thread t([&] {
 | 
						|
    int id = 0;
 | 
						|
    while (true) {
 | 
						|
      this_thread::sleep_for(chrono::seconds(1));
 | 
						|
      cout << "send event: " << id << std::endl;
 | 
						|
      std::stringstream ss;
 | 
						|
      ss << "data: " << id << "\n\n";
 | 
						|
      ed.send_event(ss.str());
 | 
						|
      id++;
 | 
						|
    }
 | 
						|
  });
 | 
						|
 | 
						|
  svr.listen("localhost", 1234);
 | 
						|
}
 |