Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "seasocks/PrintfLogger.h"
- #include "seasocks/Server.h"
- #include "seasocks/Response.h"
- #include "seasocks/ResponseWriter.h"
- #include "seasocks/ResponseCode.h"
- #include "seasocks/util/RootPageHandler.h"
- #include "seasocks/util/PathHandler.h"
- #include <cassert>
- #include <cstring>
- #include <iostream>
- #include <memory>
- #include <set>
- #include <sstream>
- #include <string>
- #include <thread>
- #include <unistd.h>
- using namespace seasocks;
- using namespace std;
- // The AsyncResponse does some long-lived "work" (in this case a big sleep...)
- // before responding to the ResponseWriter, in chunks. It uses a new thread to
- // perform this "work". As responses can be canceled before the work is
- // complete, we must ensure the ResponseWriter used to communicate the response
- // is kept alive long enough by holding its shared_ptr in the "work" thread.
- // Seasocks will tell the response it has been cancelled (if the connection
- // associated with the request is closed); but the ResponseWriter is safe in the
- // presence of a closed connection so for simplicity this example does nothing
- // in the cancel() method. It is assumed the lifetime of the Server object is
- // long enough for all requests to complete before it is destroyed.
- struct AsyncResponse : Response {
- Server &_server;
- explicit AsyncResponse(Server &server) : _server(server) {}
- // From Response:
- virtual void handle(shared_ptr<ResponseWriter> writer) override {
- auto &server = _server;
- thread t([&server, writer] () mutable {
- usleep(1000000); // A long database query...
- string response = "some kind of response...beginning<br>";
- server.execute([response, writer]{
- writer->begin(ResponseCode::Ok, TransferEncoding::Chunked);
- writer->header("Content-type", "application/html");
- writer->payload(response.data(), response.length());
- });
- response = "more data...<br>";
- for (auto i = 0; i < 5; ++i) {
- usleep(1000000); // more data
- server.execute([response, writer]{
- writer->payload(response.data(), response.length());
- });
- }
- response = "Done!";
- usleep(100000); // final data
- server.execute([response, writer]{
- writer->payload(response.data(), response.length());
- writer->finish(true);
- });
- });
- t.detach();
- }
- virtual void cancel() override {
- // If we could cancel the thread, we would do so here. There's no need
- // to invalidate the _writer; any writes to it after this will be
- // silently dropped.
- }
- };
- struct DataHandler : CrackedUriPageHandler {
- virtual std::shared_ptr<Response> handle(
- const CrackedUri &/*uri*/, const Request &request) override {
- return make_shared<AsyncResponse>(request.server());
- }
- };
- int main(int /*argc*/, const char* /*argv*/[]) {
- shared_ptr<Logger> logger(new PrintfLogger(Logger::Level::DEBUG));
- Server server(logger);
- auto root = make_shared<RootPageHandler>();
- auto pathHandler = make_shared<PathHandler>("data", make_shared<DataHandler>());
- root->add(pathHandler);
- server.addPageHandler(root);
- server.serve("src/async_test_web", 9090);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement