Improve transmission efficiency

This commit is contained in:
antao 2018-12-30 22:18:20 +08:00
parent ed70959fe5
commit f58d73991f
5 changed files with 52 additions and 51 deletions

View File

@ -20,6 +20,7 @@
#include <trantor/utils/Logger.h>
#include <stdio.h>
#include <sys/stat.h>
#include <memory>
using namespace trantor;
using namespace drogon;
@ -307,13 +308,14 @@ std::string HttpResponseImpl::web_response_code_to_string(int code)
return "Undefined Error";
}
}
void HttpResponseImpl::makeHeaderString(MsgBuffer *output) const
void HttpResponseImpl::makeHeaderString(const std::shared_ptr<std::string> &headerStringPtr) const
{
char buf[64];
assert(headerStringPtr);
snprintf(buf, sizeof buf, "HTTP/1.1 %d ", _statusCode);
output->append(buf);
output->append(_statusMessage);
output->append("\r\n");
headerStringPtr->append(buf);
headerStringPtr->append(_statusMessage);
headerStringPtr->append("\r\n");
if (_sendfileName.empty())
{
snprintf(buf, sizeof buf, "Content-Length: %lu\r\n", static_cast<long unsigned int>(_bodyPtr->size()));
@ -329,12 +331,12 @@ void HttpResponseImpl::makeHeaderString(MsgBuffer *output) const
snprintf(buf, sizeof buf, "Content-Length: %llu\r\n", static_cast<long long unsigned int>(filestat.st_size));
}
output->append(buf);
headerStringPtr->append(buf);
if (_headers.find("Connection") == _headers.end())
{
if (_closeConnection)
{
output->append("Connection: close\r\n");
headerStringPtr->append("Connection: close\r\n");
}
else
{
@ -347,18 +349,18 @@ void HttpResponseImpl::makeHeaderString(MsgBuffer *output) const
it != _headers.end();
++it)
{
output->append(it->first);
output->append(": ");
output->append(it->second);
output->append("\r\n");
headerStringPtr->append(it->first);
headerStringPtr->append(": ");
headerStringPtr->append(it->second);
headerStringPtr->append("\r\n");
}
output->append("Server: drogon/");
output->append(drogon::getVersion());
output->append("\r\n");
headerStringPtr->append("Server: drogon/");
headerStringPtr->append(drogon::getVersion());
headerStringPtr->append("\r\n");
}
void HttpResponseImpl::appendToBuffer(MsgBuffer *output) const
std::shared_ptr<std::string> HttpResponseImpl::renderToString() const
{
if (_expriedTime >= 0)
{
@ -366,24 +368,25 @@ void HttpResponseImpl::appendToBuffer(MsgBuffer *output) const
{
bool isDateChanged = false;
auto newDate = getHttpFullDate(trantor::Date::now(), &isDateChanged);
{
{
std::lock_guard<std::mutex> lock(*_httpStringMutex);
if (isDateChanged)
{
_httpString = std::make_shared<std::string>(*_httpString);
memcpy(_httpString->data() + _datePos, newDate, strlen(newDate));
}
output->append(*_httpString);
}
return;
return _httpString;
}
}
auto httpString = std::make_shared<std::string>();
if (!_fullHeaderString)
{
makeHeaderString(output);
makeHeaderString(httpString);
}
else
{
output->append(*_fullHeaderString);
httpString->append(*_fullHeaderString);
}
//output cookies
@ -392,22 +395,23 @@ void HttpResponseImpl::appendToBuffer(MsgBuffer *output) const
for (auto it = _cookies.begin(); it != _cookies.end(); it++)
{
output->append(it->second.cookieString());
httpString->append(it->second.cookieString());
}
}
//output Date header
output->append("Date: ");
auto datePos = output->readableBytes();
output->append(getHttpFullDate(trantor::Date::date()));
output->append("\r\n\r\n");
httpString->append("Date: ");
auto datePos = httpString->length();
httpString->append(getHttpFullDate(trantor::Date::date()));
httpString->append("\r\n\r\n");
LOG_TRACE << "reponse(no body):" << output->peek();
output->append(*_bodyPtr);
LOG_TRACE << "reponse(no body):" << httpString->c_str();
httpString->append(*_bodyPtr);
if (_expriedTime >= 0)
{
std::lock_guard<std::mutex> lock(*_httpStringMutex);
_datePos = datePos;
_httpString = std::make_shared<std::string>(output->peek(), output->readableBytes());
_httpString = httpString;
}
return httpString;
}

View File

@ -207,7 +207,7 @@ class HttpResponseImpl : public HttpResponse
{
_headers["Location"] = url;
}
void appendToBuffer(MsgBuffer *output) const;
std::shared_ptr<std::string> renderToString() const;
virtual void clear() override
{
@ -292,9 +292,8 @@ class HttpResponseImpl : public HttpResponse
}
void makeHeaderString()
{
trantor::MsgBuffer buf;
makeHeaderString(&buf);
_fullHeaderString = std::make_shared<std::string>(buf.peek(), buf.readableBytes());
_fullHeaderString = std::make_shared<std::string>();
makeHeaderString(_fullHeaderString);
}
protected:
@ -304,7 +303,7 @@ class HttpResponseImpl : public HttpResponse
static std::string web_response_code_to_string(int code);
void makeHeaderString(MsgBuffer *output) const;
void makeHeaderString(const std::shared_ptr<std::string> &headerStringPtr) const;
private:
std::map<std::string, std::string> _headers;

View File

@ -120,15 +120,16 @@ void HttpServer::onMessage(const TcpConnectionPtr &conn,
if (context->firstReq() && isWebSocket(conn, context->request()))
{
auto wsConn = std::make_shared<WebSocketConnectionImpl>(conn);
newWebsocketCallback_(context->request(), [=](const HttpResponsePtr &resp) mutable {
if (resp->statusCode() == HttpResponse::k101SwitchingProtocols)
{
context->setWebsockConnection(wsConn);
}
MsgBuffer buffer;
std::dynamic_pointer_cast<HttpResponseImpl>(resp)->appendToBuffer(&buffer);
conn->send(std::move(buffer));
},
newWebsocketCallback_(context->request(),
[=](const HttpResponsePtr &resp) mutable {
if (resp->statusCode() == HttpResponse::k101SwitchingProtocols)
{
context->setWebsockConnection(wsConn);
}
MsgBuffer buffer;
auto httpString = std::dynamic_pointer_cast<HttpResponseImpl>(resp)->renderToString();
conn->send(httpString);
},
wsConn);
}
else
@ -252,8 +253,8 @@ void HttpServer::sendResponse(const TcpConnectionPtr &conn,
const HttpResponsePtr &response)
{
MsgBuffer buf;
std::dynamic_pointer_cast<HttpResponseImpl>(response)->appendToBuffer(&buf);
conn->send(std::move(buf));
auto httpString = std::dynamic_pointer_cast<HttpResponseImpl>(response)->renderToString();
conn->send(httpString);
auto &sendfileName = std::dynamic_pointer_cast<HttpResponseImpl>(response)->sendfileName();
if (!sendfileName.empty())
{

View File

@ -129,10 +129,8 @@ bool HttpServerContext::parseRequest(MsgBuffer *buf)
{
auto resp = HttpResponse::newHttpResponse();
resp->setStatusCode(HttpResponse::k100Continue);
MsgBuffer buffer;
std::dynamic_pointer_cast<HttpResponseImpl>(resp)
->appendToBuffer(&buffer);
connPtr->send(std::move(buffer));
auto httpString = std::dynamic_pointer_cast<HttpResponseImpl>(resp)->renderToString();
connPtr->send(httpString);
}
}
else if (!expect.empty())
@ -144,9 +142,8 @@ bool HttpServerContext::parseRequest(MsgBuffer *buf)
auto resp = HttpResponse::newHttpResponse();
resp->setStatusCode(HttpResponse::k417ExpectationFailed);
MsgBuffer buffer;
std::dynamic_pointer_cast<HttpResponseImpl>(resp)
->appendToBuffer(&buffer);
connPtr->send(std::move(buffer));
auto httpString = std::dynamic_pointer_cast<HttpResponseImpl>(resp)->renderToString();
connPtr->send(httpString);
buf->retrieveAll();
connPtr->forceClose();

@ -1 +1 @@
Subproject commit 088af9a4d5351d7e027894836c3f93ff2b7191f5
Subproject commit 69f6ece8d83b251842d633aa7a2fb3a6bd6ba2e5