大幅提升接收推流性能以及降低内存占用

This commit is contained in:
xiongziliang
2020-11-01 03:41:35 +08:00
parent 5c7a08eb7c
commit 700a16c759
38 changed files with 173 additions and 193 deletions

View File

@@ -13,7 +13,7 @@
namespace mediakit{
const char *HttpChunkedSplitter::onSearchPacketTail(const char *data, int len) {
const char *HttpChunkedSplitter::onSearchPacketTail(const char *data, uint64_t len) {
auto pos = strstr(data,"\r\n");
if(!pos){
return nullptr;

View File

@@ -30,7 +30,7 @@ public:
protected:
int64_t onRecvHeader(const char *data,uint64_t len) override;
void onRecvContent(const char *data,uint64_t len) override;
const char *onSearchPacketTail(const char *data,int len) override;
const char *onSearchPacketTail(const char *data,uint64_t len) override;
protected:
virtual void onRecvChunk(const char *data,uint64_t len){
if(_onChunkData){

View File

@@ -99,9 +99,6 @@ void HttpClient::onConnect(const SockException &ex) {
return;
}
//先假设http客户端只会接收一点点数据只接受http头节省内存
getSock()->setReadBuffer(std::make_shared<BufferRaw>(1 * 1024));
_totalBodySize = 0;
_recvedBodySize = 0;
HttpRequestSplitter::reset();
@@ -156,9 +153,6 @@ int64_t HttpClient::onRecvHeader(const char *data, uint64_t len) {
}
if(_parser["Transfer-Encoding"] == "chunked"){
//我们认为这种情况下后面应该有大量的数据过来,加大接收缓存提高性能
getSock()->setReadBuffer(std::make_shared<BufferRaw>(256 * 1024));
//如果Transfer-Encoding字段等于chunked则认为后续的content是不限制长度的
_totalBodySize = -1;
_chunkedSplitter = std::make_shared<HttpChunkedSplitter>([this](const char *data,uint64_t len){
@@ -183,13 +177,6 @@ int64_t HttpClient::onRecvHeader(const char *data, uint64_t len) {
//但是由于我们没必要等content接收完毕才回调onRecvContent(因为这样浪费内存并且要多次拷贝数据)
//所以返回-1代表我们接下来分段接收content
_recvedBodySize = 0;
if(_totalBodySize > 0){
//根据_totalBodySize设置接收缓存大小
getSock()->setReadBuffer(std::make_shared<BufferRaw>(MIN(_totalBodySize + 1,256 * 1024)));
}else{
getSock()->setReadBuffer(std::make_shared<BufferRaw>(256 * 1024));
}
return -1;
}

View File

@@ -39,6 +39,9 @@ void HttpRequestSplitter::input(const char *data,uint64_t len) {
const char *index = nullptr;
_remain_data_size = len;
while (_content_len == 0 && _remain_data_size > 0 && (index = onSearchPacketTail(ptr,_remain_data_size)) != nullptr) {
if(index == ptr){
break;
}
//_content_len == 0这是请求头
const char *header_ptr = ptr;
int64_t header_size = index - ptr;
@@ -61,8 +64,7 @@ void HttpRequestSplitter::input(const char *data,uint64_t len) {
if(_content_len == 0){
//尚未找到http头缓存定位到剩余数据部分
string str(ptr,_remain_data_size);
_remain_data = str;
_remain_data.assign(ptr,_remain_data_size);
return;
}
@@ -71,8 +73,7 @@ void HttpRequestSplitter::input(const char *data,uint64_t len) {
//数据按照固定长度content处理
if(_remain_data_size < _content_len){
//数据不够,缓存定位到剩余数据部分
string str(ptr,_remain_data_size);
_remain_data = str;
_remain_data.assign(ptr, _remain_data_size);
return;
}
//收到content数据并且接受content完毕
@@ -85,9 +86,7 @@ void HttpRequestSplitter::input(const char *data,uint64_t len) {
if(_remain_data_size > 0){
//还有数据没有处理完毕
string str(ptr,_remain_data_size);
_remain_data = str;
_remain_data.assign(ptr,_remain_data_size);
data = ptr = (char *)_remain_data.data();
len = _remain_data.size();
goto splitPacket;
@@ -112,7 +111,7 @@ void HttpRequestSplitter::reset() {
_remain_data.clear();
}
const char *HttpRequestSplitter::onSearchPacketTail(const char *data,int len) {
const char *HttpRequestSplitter::onSearchPacketTail(const char *data,uint64_t len) {
auto pos = strstr(data,"\r\n\r\n");
if(pos == nullptr){
return nullptr;

View File

@@ -12,7 +12,9 @@
#define ZLMEDIAKIT_HTTPREQUESTSPLITTER_H
#include <string>
#include "Network/Buffer.h"
using namespace std;
using namespace toolkit;
namespace mediakit {
@@ -54,7 +56,7 @@ protected:
* @param len 数据长度
* @return nullptr代表未找到包位否则返回包尾指针
*/
virtual const char *onSearchPacketTail(const char *data,int len);
virtual const char *onSearchPacketTail(const char *data, uint64_t len);
/**
* 设置content len
@@ -71,7 +73,7 @@ protected:
*/
int64_t remainDataSize();
private:
string _remain_data;
BufferLikeString _remain_data;
int64_t _content_len = 0;
int64_t _remain_data_size = 0;
};

View File

@@ -24,8 +24,6 @@ HttpSession::HttpSession(const Socket::Ptr &pSock) : TcpSession(pSock) {
TraceP(this);
GET_CONFIG(uint32_t,keep_alive_sec,Http::kKeepAliveSecond);
pSock->setSendTimeOutSecond(keep_alive_sec);
//起始接收buffer缓存设置为4K节省内存
pSock->setReadBuffer(std::make_shared<BufferRaw>(4 * 1024));
}
HttpSession::~HttpSession() {
@@ -638,14 +636,6 @@ void HttpSession::Handle_Req_POST(int64_t &content_len) {
return;
}
//根据Content-Length设置接收缓存大小
if(totalContentLen > 0){
getSock()->setReadBuffer(std::make_shared<BufferRaw>(MIN(totalContentLen + 1,256 * 1024)));
}else{
//不定长度的Content-Length
getSock()->setReadBuffer(std::make_shared<BufferRaw>(256 * 1024));
}
if(totalContentLen > 0 && totalContentLen < maxReqSize ){
//返回固定长度的content
content_len = totalContentLen;
@@ -738,9 +728,9 @@ void HttpSession::onWrite(const Buffer::Ptr &buffer, bool flush) {
}
}
void HttpSession::onWebSocketEncodeData(const Buffer::Ptr &buffer){
void HttpSession::onWebSocketEncodeData(Buffer::Ptr buffer){
_total_bytes_usage += buffer->size();
send(buffer);
send(std::move(buffer));
}
void HttpSession::onWebSocketDecodeComplete(const WebSocketHeader &header_in){

View File

@@ -92,7 +92,7 @@ protected:
* 发送数据进行websocket协议打包后回调
* @param buffer websocket协议数据
*/
void onWebSocketEncodeData(const Buffer::Ptr &buffer) override;
void onWebSocketEncodeData(Buffer::Ptr buffer) override;
/**
* 接收到完整的一个webSocket数据包后回调

View File

@@ -43,11 +43,11 @@ protected:
/**
* 发送前拦截并打包为websocket协议
*/
int send(const Buffer::Ptr &buf) override{
int send(Buffer::Ptr buf) override{
if(_beforeSendCB){
return _beforeSendCB(buf);
}
return ClientType::send(buf);
return ClientType::send(std::move(buf));
}
/**
@@ -287,8 +287,8 @@ protected:
* @param ptr 数据指针
* @param len 数据指针长度
*/
void onWebSocketEncodeData(const Buffer::Ptr &buffer) override{
HttpClientImp::send(buffer);
void onWebSocketEncodeData(Buffer::Ptr buffer) override{
HttpClientImp::send(std::move(buffer));
}
private:

View File

@@ -53,11 +53,11 @@ protected:
* @param buf 需要截取的数据
* @return 数据字节数
*/
int send(const Buffer::Ptr &buf) override {
int send(Buffer::Ptr buf) override {
if (_beforeSendCB) {
return _beforeSendCB(buf);
}
return TcpSessionType::send(buf);
return TcpSessionType::send(std::move(buf));
}
string getIdentifier() const override {
@@ -219,8 +219,8 @@ protected:
/**
* 发送数据进行websocket协议打包后回调
*/
void onWebSocketEncodeData(const Buffer::Ptr &buffer) override{
HttpSessionType::send(buffer);
void onWebSocketEncodeData(Buffer::Ptr buffer) override{
HttpSessionType::send(std::move(buffer));
}
private:

View File

@@ -132,7 +132,7 @@ protected:
* @param ptr 数据指针
* @param len 数据指针长度
*/
virtual void onWebSocketEncodeData(const Buffer::Ptr &buffer){};
virtual void onWebSocketEncodeData(Buffer::Ptr buffer){};
private:
void onPayloadData(uint8_t *data, uint64_t len);