aboutsummaryrefslogtreecommitdiff
path: root/example/ssesvr.cc
diff options
context:
space:
mode:
Diffstat (limited to 'example/ssesvr.cc')
-rw-r--r--example/ssesvr.cc109
1 files changed, 109 insertions, 0 deletions
diff --git a/example/ssesvr.cc b/example/ssesvr.cc
new file mode 100644
index 0000000..4a58c66
--- /dev/null
+++ b/example/ssesvr.cc
@@ -0,0 +1,109 @@
+//
+// sse.cc
+//
+// Copyright (c) 2020 Yuji Hirose. All rights reserved.
+// MIT License
+//
+
+#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; });
+ if (sink->is_writable()) { 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);
+}