Removed async_flush and its likely erroneous code.

This commit is contained in:
eidheim 2015-09-02 19:55:20 +02:00
commit 1a39476f92
2 changed files with 21 additions and 69 deletions

View file

@ -14,17 +14,15 @@ See also https://github.com/eidheim/Simple-WebSocket-Server for an easy way to m
* 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)
* 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
Note: newest version is NOT backward compatible with earlier versions.
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.
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
@ -38,7 +36,7 @@ Compile with a C++11 compiler supporting regex (for instance g++ 4.9):
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:

View file

@ -25,64 +25,19 @@ namespace SimpleWeb {
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,
boost::asio::yield_context& yield):
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);
}));
}
boost::asio::yield_context& yield): strand(strand), yield(yield), socket(socket), stream(&streambuf) {}
void flush() {
boost::asio::streambuf write_buffer;
std::ostream response(&write_buffer);
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:
@ -104,11 +59,6 @@ namespace SimpleWeb {
}
};
static Response& async_flush(Response& r) {
r.async_flush();
return r;
}
static Response& flush(Response& r) {
r.flush();
return r;
@ -355,16 +305,20 @@ namespace SimpleWeb {
try {
resource_function(response, request);
}
catch(std::exception& e) {
catch(const std::exception& e) {
return;
}
response.async_flush([this, socket, request, timer](const boost::system::error_code& ec) {
if(timeout_content>0)
timer->cancel();
if(!ec && stof(request->http_version)>1.05)
read_request_and_content(socket);
});
try {
response.flush();
}
catch(const std::exception &e) {
return;
}
if(timeout_content>0)
timer->cancel();
if(stof(request->http_version)>1.05)
read_request_and_content(socket);
});
}
};