mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2026-06-23 09:22:21 +08:00
大幅提升接收推流性能以及降低内存占用
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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){
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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){
|
||||
|
||||
@@ -92,7 +92,7 @@ protected:
|
||||
* 发送数据进行websocket协议打包后回调
|
||||
* @param buffer websocket协议数据
|
||||
*/
|
||||
void onWebSocketEncodeData(const Buffer::Ptr &buffer) override;
|
||||
void onWebSocketEncodeData(Buffer::Ptr buffer) override;
|
||||
|
||||
/**
|
||||
* 接收到完整的一个webSocket数据包后回调
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user