example_clock building and working

This commit is contained in:
flamingcow
2019-05-05 00:11:57 -07:00
commit ee2667bb1a
9 changed files with 154 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
*.o
*.a
example_clock

3
.gitmodules vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule "firecgi"]
path = firecgi
url = git@github.com:firestuff/firecgi.git

22
Makefile Normal file
View File

@@ -0,0 +1,22 @@
FIRE_CXX ?= clang++
FIRE_CXXFLAGS ?= -O3 -std=gnu++2a -Wall -Werror
FIRE_LDLIBS ?= -lgflags -lglog -lpthread
all: firesse.a example_clock
objects = firesse.o stream.o
firesse.a: $(objects)
$(MAKE) --directory=firecgi
ar rcs $@ $^
example_clock: example_clock.o $(objects)
$(MAKE) --directory=firecgi
$(FIRE_CXX) $(FIRE_CXXFLAGS) -o $@ $+ firecgi/firecgi.a firecgi/firebuf/firebuf.a $(FIRE_LDLIBS)
%.o: %.cc *.h Makefile
$(FIRE_CXX) $(FIRE_CXXFLAGS) -c -o $@ $<
clean:
$(MAKE) --directory=firecgi clean
rm --force example_clock *.o *.a

25
example_clock.cc Normal file
View File

@@ -0,0 +1,25 @@
#include <gflags/gflags.h>
#include <glog/logging.h>
#include <sys/time.h>
#include "firesse.h"
DEFINE_int32(port, 9000, "TCP port to bind");
int main(int argc, char *argv[]) {
google::InitGoogleLogging(argv[0]);
gflags::ParseCommandLineFlags(&argc, &argv, true);
firesse::Server server(FLAGS_port, [](std::unique_ptr<firesse::Stream> stream) {
while (true) {
timeval tv;
PCHECK(gettimeofday(&tv, nullptr) == 0);
uint64_t time_ms = tv.tv_sec * 1000 + tv.tv_usec / 1000;
if (!stream->WriteEvent(std::to_string(time_ms), 0, "time")) {
break;
}
sleep(1);
}
});
server.Serve();
}

1
firecgi Submodule

Submodule firecgi added at 09c4ce2290

30
firesse.cc Normal file
View File

@@ -0,0 +1,30 @@
#include "firesse.h"
namespace firesse {
Server::Server(int port, const std::function<void(std::unique_ptr<Stream>)>& callback)
: callback_(callback),
firecgi_server_(port,
[this](std::unique_ptr<firecgi::Request> request) { OnRequest(std::move(request)); },
1,
{"HTTP_ACCEPT"}) {}
void Server::Serve() {
firecgi_server_.Serve();
}
void Server::OnRequest(std::unique_ptr<firecgi::Request> request) {
if (request->GetParam("HTTP_ACCEPT") != "text/event-stream") {
LOG(WARNING) << "bad HTTP_ACCEPT: " << request->GetParam("HTTP_ACCEPT");
request->WriteHeader("Status", "400 Bad Request");
request->WriteHeader("Content-Type", "text-plain");
request->WriteBody("No \"Accept: text/event-stream\" header found in request. Please call this endpoint using EventSource.");
request->End();
return;
}
request->WriteHeader("Content-Type", "text/event-stream");
request->WriteBody("");
callback_(std::make_unique<Stream>(std::move(request)));
}
} // namespace firesse

20
firesse.h Normal file
View File

@@ -0,0 +1,20 @@
#pragma once
#include "firecgi/firecgi.h"
#include "stream.h"
namespace firesse {
class Server {
public:
Server(int port, const std::function<void(std::unique_ptr<Stream>)>& callback);
void Serve();
private:
void OnRequest(std::unique_ptr<firecgi::Request> request);
std::function<void(std::unique_ptr<Stream>)> callback_;
firecgi::Server firecgi_server_;
};
} // namespace firesse

30
stream.cc Normal file
View File

@@ -0,0 +1,30 @@
#include "stream.h"
namespace firesse {
Stream::Stream(std::unique_ptr<firecgi::Request> request)
: request_(std::move(request)) {}
bool Stream::WriteEvent(const std::string& data, uint64_t id, const std::string& type) {
if (id) {
request_->WriteBody("id: ");
request_->WriteBody(std::to_string(id));
request_->WriteBody("\n");
}
if (!type.empty()) {
request_->WriteBody("event: ");
request_->WriteBody(type);
request_->WriteBody("\n");
}
request_->WriteBody("data: ");
request_->WriteBody(data);
request_->WriteBody("\n\n");
return request_->Flush();
}
bool Stream::End() {
return request_->End();
}
} // namespace firesse

20
stream.h Normal file
View File

@@ -0,0 +1,20 @@
#pragma once
#include <memory>
#include "firecgi/request.h"
namespace firesse {
class Stream {
public:
Stream(std::unique_ptr<firecgi::Request> request);
[[nodiscard]] bool WriteEvent(const std::string& data, uint64_t id=0, const std::string& type="");
bool End();
private:
std::unique_ptr<firecgi::Request> request_;
};
} // namespace firesse