Removed async_flush and its likely erroneous code.
This commit is contained in:
parent
0ddc469edd
commit
1a39476f92
2 changed files with 21 additions and 69 deletions
|
|
@ -14,17 +14,15 @@ See also https://github.com/eidheim/Simple-WebSocket-Server for an easy way to m
|
||||||
* Client supports chunked transfer encoding
|
* Client supports chunked transfer encoding
|
||||||
* Timeouts, if any of Server::timeout_request and Server::timeout_content are >0 (default: Server::timeout_request=5 seconds, and Server::timeout_content=300 seconds)
|
* Timeouts, if any of Server::timeout_request and Server::timeout_content are >0 (default: Server::timeout_request=5 seconds, and Server::timeout_content=300 seconds)
|
||||||
* Simple way to add REST resources using regex for path, and anonymous functions
|
* Simple way to add REST resources using regex for path, and anonymous functions
|
||||||
* Possibility to flush response to clients both synchronously (Server::flush) and asynchronously (Server::async_flush).
|
* Possibility to flush response to clients synchronously (Server::flush).
|
||||||
|
|
||||||
###Usage
|
###Usage
|
||||||
|
|
||||||
Note: newest version is NOT backward compatible with earlier versions.
|
|
||||||
|
|
||||||
See http_examples.cpp or https_examples.cpp for example usage.
|
See http_examples.cpp or https_examples.cpp for example usage.
|
||||||
|
|
||||||
See particularly the JSON-POST (using Boost.PropertyTree) and the GET /match/[number] examples, which are most relevant.
|
See particularly the JSON-POST (using Boost.PropertyTree) and the GET /match/[number] examples, which are most relevant.
|
||||||
|
|
||||||
The default_resource includes example use of Server::flush. Note that Server::async_flush might be slightly slower than Server::flush unless you need to process computationally expensive tasks while simultaneously sending large datasets to a client.
|
The default_resource includes example use of Server::flush.
|
||||||
|
|
||||||
### Dependencies
|
### Dependencies
|
||||||
|
|
||||||
|
|
@ -38,7 +36,7 @@ Compile with a C++11 compiler supporting regex (for instance g++ 4.9):
|
||||||
|
|
||||||
On Linux using g++: add `-pthread`
|
On Linux using g++: add `-pthread`
|
||||||
|
|
||||||
Note: added `-lboost_filesystem` for the default_resource example, and `-lboost_thread` to make the json-example thread safe. Also added `-lboost_coroutine -lboost_context` to make synchronous and asynchronous flushing of response stream work. On some systems you might have to use postfix `-mt` to link to these libraries.
|
Note: added `-lboost_filesystem` for the default_resource example, and `-lboost_thread` to make the json-example thread safe. Also added `-lboost_coroutine -lboost_context` to make synchronous flushing of response stream work. On some systems you might have to use postfix `-mt` to link to these libraries.
|
||||||
|
|
||||||
You can now also compile using CMake and make:
|
You can now also compile using CMake and make:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,64 +25,19 @@ namespace SimpleWeb {
|
||||||
|
|
||||||
std::shared_ptr<socket_type> socket;
|
std::shared_ptr<socket_type> socket;
|
||||||
|
|
||||||
std::shared_ptr<boost::asio::deadline_timer> async_timer;
|
|
||||||
|
|
||||||
std::shared_ptr<bool> async_writing;
|
|
||||||
std::shared_ptr<bool> async_waiting;
|
|
||||||
|
|
||||||
Response(boost::asio::io_service& io_service, std::shared_ptr<socket_type> socket, std::shared_ptr<boost::asio::strand> strand,
|
Response(boost::asio::io_service& io_service, std::shared_ptr<socket_type> socket, std::shared_ptr<boost::asio::strand> strand,
|
||||||
boost::asio::yield_context& yield):
|
boost::asio::yield_context& yield): strand(strand), yield(yield), socket(socket), stream(&streambuf) {}
|
||||||
strand(strand), yield(yield), socket(socket), async_timer(new boost::asio::deadline_timer(io_service)),
|
|
||||||
async_writing(new bool(false)), async_waiting(new bool(false)), stream(&streambuf) {}
|
|
||||||
|
|
||||||
void async_flush(std::function<void(const boost::system::error_code&)> callback=nullptr) {
|
|
||||||
if(!callback && !socket->lowest_layer().is_open()) {
|
|
||||||
if(*async_waiting)
|
|
||||||
async_timer->cancel();
|
|
||||||
throw std::runtime_error("Broken pipe.");
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<boost::asio::streambuf> write_buffer(new boost::asio::streambuf);
|
|
||||||
std::ostream response(write_buffer.get());
|
|
||||||
response << stream.rdbuf();
|
|
||||||
|
|
||||||
//Wait until previous async_flush is finished
|
|
||||||
strand->dispatch([this](){
|
|
||||||
if(*async_writing) {
|
|
||||||
*async_waiting=true;
|
|
||||||
try {
|
|
||||||
async_timer->async_wait(yield);
|
|
||||||
}
|
|
||||||
catch(std::exception& e) {
|
|
||||||
}
|
|
||||||
*async_waiting=false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
*async_writing=true;
|
|
||||||
|
|
||||||
auto socket_=this->socket;
|
|
||||||
auto async_writing_=this->async_writing;
|
|
||||||
auto async_timer_=this->async_timer;
|
|
||||||
auto async_waiting_=this->async_waiting;
|
|
||||||
|
|
||||||
boost::asio::async_write(*socket, *write_buffer,
|
|
||||||
strand->wrap([socket_, write_buffer, callback, async_writing_, async_timer_, async_waiting_]
|
|
||||||
(const boost::system::error_code& ec, size_t /*bytes_transferred*/) {
|
|
||||||
*async_writing_=false;
|
|
||||||
if(*async_waiting_)
|
|
||||||
async_timer_->cancel();
|
|
||||||
if(callback)
|
|
||||||
callback(ec);
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
void flush() {
|
void flush() {
|
||||||
boost::asio::streambuf write_buffer;
|
boost::asio::streambuf write_buffer;
|
||||||
std::ostream response(&write_buffer);
|
std::ostream response(&write_buffer);
|
||||||
response << stream.rdbuf();
|
response << stream.rdbuf();
|
||||||
|
|
||||||
boost::asio::async_write(*socket, write_buffer, yield);
|
boost::system::error_code ec;
|
||||||
|
boost::asio::async_write(*socket, write_buffer, yield[ec]);
|
||||||
|
|
||||||
|
if(ec)
|
||||||
|
throw std::runtime_error(ec.message());
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -104,11 +59,6 @@ namespace SimpleWeb {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static Response& async_flush(Response& r) {
|
|
||||||
r.async_flush();
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Response& flush(Response& r) {
|
static Response& flush(Response& r) {
|
||||||
r.flush();
|
r.flush();
|
||||||
return r;
|
return r;
|
||||||
|
|
@ -355,16 +305,20 @@ namespace SimpleWeb {
|
||||||
try {
|
try {
|
||||||
resource_function(response, request);
|
resource_function(response, request);
|
||||||
}
|
}
|
||||||
catch(std::exception& e) {
|
catch(const std::exception& e) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
response.async_flush([this, socket, request, timer](const boost::system::error_code& ec) {
|
try {
|
||||||
if(timeout_content>0)
|
response.flush();
|
||||||
timer->cancel();
|
}
|
||||||
if(!ec && stof(request->http_version)>1.05)
|
catch(const std::exception &e) {
|
||||||
read_request_and_content(socket);
|
return;
|
||||||
});
|
}
|
||||||
|
if(timeout_content>0)
|
||||||
|
timer->cancel();
|
||||||
|
if(stof(request->http_version)>1.05)
|
||||||
|
read_request_and_content(socket);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue