优化hls播放器,使用持久化连接 (#3070)

hls播放时,如果对方reset断开了tcp连接,应该自动发起重连
This commit is contained in:
alexliyu7352
2023-12-01 17:56:08 +08:00
committed by GitHub
parent 50281513d9
commit 4648c156c8
7 changed files with 176 additions and 102 deletions

View File

@@ -23,6 +23,7 @@ void HlsPlayer::play(const string &url) {
_play_result = false;
_play_url = url;
setProxyUrl((*this)[Client::kProxyUrl]);
setAllowResendRequest(true);
fetchIndexFile();
}
@@ -99,6 +100,7 @@ void HlsPlayer::fetchSegment() {
if (!_http_ts_player) {
_http_ts_player = std::make_shared<HttpTSPlayer>(getPoller());
_http_ts_player->setProxyUrl((*this)[Client::kProxyUrl]);
_http_ts_player->setAllowResendRequest(true);
_http_ts_player->setOnCreateSocket([weak_self](const EventPoller::Ptr &poller) {
auto strong_self = weak_self.lock();
if (strong_self) {

View File

@@ -56,10 +56,14 @@ void HttpClient::sendRequest(const string &url) {
splitUrl(host, host, port);
_header.emplace("Host", host_header);
_header.emplace("User-Agent", kServerName);
_header.emplace("Connection", "keep-alive");
_header.emplace("Accept", "*/*");
_header.emplace("Accept-Language", "zh-CN,zh;q=0.8");
if (_http_persistent) {
_header.emplace("Connection", "keep-alive");
} else {
_header.emplace("Connection", "close");
}
_http_persistent = true;
if (_body && _body->remainSize()) {
_header.emplace("Content-Length", to_string(_body->remainSize()));
_header.emplace("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
@@ -78,7 +82,7 @@ void HttpClient::sendRequest(const string &url) {
printer.pop_back();
_header.emplace("Cookie", printer);
}
if (!alive() || host_changed) {
if (!alive() || host_changed || !_http_persistent) {
if (isUsedProxy()) {
_proxy_connected = false;
startConnect(_proxy_host, _proxy_port, _wait_header_ms / 1000.0f);
@@ -189,6 +193,17 @@ void HttpClient::onRecv(const Buffer::Ptr &pBuf) {
}
void HttpClient::onError(const SockException &ex) {
if (ex.getErrCode() == Err_reset && _allow_resend_request && _http_persistent && _recved_body_size == 0 && !_header_recved) {
// 连接被重置,可能是服务器主动断开了连接, 或者服务器内核参数或防火墙的持久连接空闲时间超时或不一致.
// 如果是持久化连接,那么我们可以通过重连来解决这个问题
// The connection was reset, possibly because the server actively disconnected the connection,
// or the persistent connection idle time of the server kernel parameters or firewall timed out or inconsistent.
// If it is a persistent connection, then we can solve this problem by reconnecting
WarnL << "http persistent connect reset, try reconnect";
_http_persistent = false;
sendRequest(_url);
return;
}
onResponseCompleted_l(ex);
}
@@ -437,4 +452,7 @@ bool HttpClient::checkProxyConnected(const char *data, size_t len) {
return _proxy_connected;
}
void HttpClient::setAllowResendRequest(bool allow) {
_allow_resend_request = allow;
}
} /* namespace mediakit */

View File

@@ -146,6 +146,13 @@ public:
*/
void setProxyUrl(std::string proxy_url);
/**
* 当重用连接失败时, 是否允许重新发起请求
* If the reuse connection fails, whether to allow the request to be resent
* @param allow true:允许重新发起请求 / true: allow the request to be resent
*/
void setAllowResendRequest(bool allow);
protected:
/**
* 收到http回复头
@@ -201,6 +208,8 @@ private:
//for http response
bool _complete = false;
bool _header_recved = false;
bool _http_persistent = true;
bool _allow_resend_request = false;
size_t _recved_body_size;
ssize_t _total_body_size;
Parser _parser;