mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-25 12:11:36 +08:00
适配ZLToolKit代码,支持自定义创建Socket:#468
This commit is contained in:
parent
9a088f4825
commit
c711eedaa7
@ -1 +1 @@
|
|||||||
Subproject commit dfb20fe40baca2c22212a0f7e253dda8e1d623c5
|
Subproject commit 311bee0aeff620f51bf43149b001c62079f40ea7
|
@ -13,7 +13,7 @@ namespace mediakit {
|
|||||||
|
|
||||||
HlsPlayer::HlsPlayer(const EventPoller::Ptr &poller){
|
HlsPlayer::HlsPlayer(const EventPoller::Ptr &poller){
|
||||||
_segment.setOnSegment([this](const char *data, uint64_t len) { onPacket(data, len); });
|
_segment.setOnSegment([this](const char *data, uint64_t len) { onPacket(data, len); });
|
||||||
_poller = poller ? poller : EventPollerPool::Instance().getPoller();
|
setPoller(poller ? poller : EventPollerPool::Instance().getPoller());
|
||||||
}
|
}
|
||||||
|
|
||||||
HlsPlayer::~HlsPlayer() {}
|
HlsPlayer::~HlsPlayer() {}
|
||||||
@ -63,6 +63,15 @@ void HlsPlayer::playNextTs(bool force){
|
|||||||
std::shared_ptr<Ticker> ticker(new Ticker);
|
std::shared_ptr<Ticker> ticker(new Ticker);
|
||||||
|
|
||||||
_http_ts_player = std::make_shared<HttpTSPlayer>(getPoller(), false);
|
_http_ts_player = std::make_shared<HttpTSPlayer>(getPoller(), false);
|
||||||
|
|
||||||
|
_http_ts_player->setOnCreateSocket([weakSelf](const EventPoller::Ptr &poller) {
|
||||||
|
auto strongSelf = weakSelf.lock();
|
||||||
|
if (strongSelf) {
|
||||||
|
return strongSelf->createSocket();
|
||||||
|
}
|
||||||
|
return Socket::createSocket(poller, true);
|
||||||
|
});
|
||||||
|
|
||||||
_http_ts_player->setOnDisconnect([weakSelf, ticker, ts_duration](const SockException &err) {
|
_http_ts_player->setOnDisconnect([weakSelf, ticker, ts_duration](const SockException &err) {
|
||||||
auto strongSelf = weakSelf.lock();
|
auto strongSelf = weakSelf.lock();
|
||||||
if (!strongSelf) {
|
if (!strongSelf) {
|
||||||
@ -84,6 +93,7 @@ void HlsPlayer::playNextTs(bool force){
|
|||||||
}, strongSelf->getPoller()));
|
}, strongSelf->getPoller()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
_http_ts_player->setOnPacket([weakSelf](const char *data, uint64_t len) {
|
_http_ts_player->setOnPacket([weakSelf](const char *data, uint64_t len) {
|
||||||
auto strongSelf = weakSelf.lock();
|
auto strongSelf = weakSelf.lock();
|
||||||
if (!strongSelf) {
|
if (!strongSelf) {
|
||||||
@ -94,9 +104,10 @@ void HlsPlayer::playNextTs(bool force){
|
|||||||
});
|
});
|
||||||
|
|
||||||
_http_ts_player->setMethod("GET");
|
_http_ts_player->setMethod("GET");
|
||||||
if(!(*this)[kNetAdapter].empty()) {
|
if (!(*this)[kNetAdapter].empty()) {
|
||||||
_http_ts_player->setNetAdapter((*this)[Client::kNetAdapter]);
|
_http_ts_player->setNetAdapter((*this)[Client::kNetAdapter]);
|
||||||
}
|
}
|
||||||
|
|
||||||
_http_ts_player->sendRequest(_ts_list.front().url, 2 * _ts_list.front().duration);
|
_http_ts_player->sendRequest(_ts_list.front().url, 2 * _ts_list.front().duration);
|
||||||
_ts_list.pop_front();
|
_ts_list.pop_front();
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ void HttpClient::onConnect(const SockException &ex) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//先假设http客户端只会接收一点点数据(只接受http头,节省内存)
|
//先假设http客户端只会接收一点点数据(只接受http头,节省内存)
|
||||||
_sock->setReadBuffer(std::make_shared<BufferRaw>(1 * 1024));
|
getSock()->setReadBuffer(std::make_shared<BufferRaw>(1 * 1024));
|
||||||
|
|
||||||
_totalBodySize = 0;
|
_totalBodySize = 0;
|
||||||
_recvedBodySize = 0;
|
_recvedBodySize = 0;
|
||||||
@ -157,7 +157,7 @@ int64_t HttpClient::onRecvHeader(const char *data, uint64_t len) {
|
|||||||
|
|
||||||
if(_parser["Transfer-Encoding"] == "chunked"){
|
if(_parser["Transfer-Encoding"] == "chunked"){
|
||||||
//我们认为这种情况下后面应该有大量的数据过来,加大接收缓存提高性能
|
//我们认为这种情况下后面应该有大量的数据过来,加大接收缓存提高性能
|
||||||
_sock->setReadBuffer(std::make_shared<BufferRaw>(256 * 1024));
|
getSock()->setReadBuffer(std::make_shared<BufferRaw>(256 * 1024));
|
||||||
|
|
||||||
//如果Transfer-Encoding字段等于chunked,则认为后续的content是不限制长度的
|
//如果Transfer-Encoding字段等于chunked,则认为后续的content是不限制长度的
|
||||||
_totalBodySize = -1;
|
_totalBodySize = -1;
|
||||||
@ -185,9 +185,9 @@ int64_t HttpClient::onRecvHeader(const char *data, uint64_t len) {
|
|||||||
_recvedBodySize = 0;
|
_recvedBodySize = 0;
|
||||||
if(_totalBodySize > 0){
|
if(_totalBodySize > 0){
|
||||||
//根据_totalBodySize设置接收缓存大小
|
//根据_totalBodySize设置接收缓存大小
|
||||||
_sock->setReadBuffer(std::make_shared<BufferRaw>(MIN(_totalBodySize + 1,256 * 1024)));
|
getSock()->setReadBuffer(std::make_shared<BufferRaw>(MIN(_totalBodySize + 1,256 * 1024)));
|
||||||
}else{
|
}else{
|
||||||
_sock->setReadBuffer(std::make_shared<BufferRaw>(256 * 1024));
|
getSock()->setReadBuffer(std::make_shared<BufferRaw>(256 * 1024));
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -476,7 +476,7 @@ void HttpSession::sendResponse(const char *pcStatus,
|
|||||||
|
|
||||||
//发送http body
|
//发送http body
|
||||||
AsyncSenderData::Ptr data = std::make_shared<AsyncSenderData>(shared_from_this(),body,bClose);
|
AsyncSenderData::Ptr data = std::make_shared<AsyncSenderData>(shared_from_this(),body,bClose);
|
||||||
_sock->setOnFlush([data](){
|
getSock()->setOnFlush([data](){
|
||||||
return AsyncSender::onSocketFlushed(data);
|
return AsyncSender::onSocketFlushed(data);
|
||||||
});
|
});
|
||||||
AsyncSender::onSocketFlushed(data);
|
AsyncSender::onSocketFlushed(data);
|
||||||
@ -543,10 +543,10 @@ void HttpSession::Handle_Req_POST(int64_t &content_len) {
|
|||||||
|
|
||||||
//根据Content-Length设置接收缓存大小
|
//根据Content-Length设置接收缓存大小
|
||||||
if(totalContentLen > 0){
|
if(totalContentLen > 0){
|
||||||
_sock->setReadBuffer(std::make_shared<BufferRaw>(MIN(totalContentLen + 1,256 * 1024)));
|
getSock()->setReadBuffer(std::make_shared<BufferRaw>(MIN(totalContentLen + 1,256 * 1024)));
|
||||||
}else{
|
}else{
|
||||||
//不定长度的Content-Length
|
//不定长度的Content-Length
|
||||||
_sock->setReadBuffer(std::make_shared<BufferRaw>(256 * 1024));
|
getSock()->setReadBuffer(std::make_shared<BufferRaw>(256 * 1024));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(totalContentLen > 0 && totalContentLen < maxReqSize ){
|
if(totalContentLen > 0 && totalContentLen < maxReqSize ){
|
||||||
@ -610,7 +610,7 @@ void HttpSession::setSocketFlags(){
|
|||||||
GET_CONFIG(int, mergeWriteMS, General::kMergeWriteMS);
|
GET_CONFIG(int, mergeWriteMS, General::kMergeWriteMS);
|
||||||
if(mergeWriteMS > 0) {
|
if(mergeWriteMS > 0) {
|
||||||
//推流模式下,关闭TCP_NODELAY会增加推流端的延时,但是服务器性能将提高
|
//推流模式下,关闭TCP_NODELAY会增加推流端的延时,但是服务器性能将提高
|
||||||
SockUtil::setNoDelay(_sock->rawFD(), false);
|
SockUtil::setNoDelay(getSock()->rawFD(), false);
|
||||||
//播放模式下,开启MSG_MORE会增加延时,但是能提高发送性能
|
//播放模式下,开启MSG_MORE会增加延时,但是能提高发送性能
|
||||||
setSendFlags(SOCKET_DEFAULE_FLAGS | FLAG_MORE);
|
setSendFlags(SOCKET_DEFAULE_FLAGS | FLAG_MORE);
|
||||||
}
|
}
|
||||||
|
@ -12,9 +12,9 @@
|
|||||||
namespace mediakit {
|
namespace mediakit {
|
||||||
|
|
||||||
HttpTSPlayer::HttpTSPlayer(const EventPoller::Ptr &poller, bool split_ts){
|
HttpTSPlayer::HttpTSPlayer(const EventPoller::Ptr &poller, bool split_ts){
|
||||||
_segment.setOnSegment([this](const char *data, uint64_t len) { onPacket(data, len); });
|
|
||||||
_poller = poller ? poller : EventPollerPool::Instance().getPoller();
|
|
||||||
_split_ts = split_ts;
|
_split_ts = split_ts;
|
||||||
|
_segment.setOnSegment([this](const char *data, uint64_t len) { onPacket(data, len); });
|
||||||
|
setPoller(poller ? poller : EventPollerPool::Instance().getPoller());
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpTSPlayer::~HttpTSPlayer() {}
|
HttpTSPlayer::~HttpTSPlayer() {}
|
||||||
@ -25,8 +25,8 @@ int64_t HttpTSPlayer::onResponseHeader(const string &status, const HttpClient::H
|
|||||||
shutdown(SockException(Err_other, StrPrinter << "bad http status code:" + status));
|
shutdown(SockException(Err_other, StrPrinter << "bad http status code:" + status));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
auto contet_type = const_cast< HttpClient::HttpHeader &>(headers)["Content-Type"];
|
auto content_type = const_cast< HttpClient::HttpHeader &>(headers)["Content-Type"];
|
||||||
if (contet_type.find("video/mp2t") == 0 || contet_type.find("video/mpeg") == 0) {
|
if (content_type.find("video/mp2t") == 0 || content_type.find("video/mpeg") == 0) {
|
||||||
_is_ts_content = true;
|
_is_ts_content = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ public:
|
|||||||
|
|
||||||
HttpWsClient(ClientTypeImp<ClientType,DataType> &delegate) : _delegate(delegate){
|
HttpWsClient(ClientTypeImp<ClientType,DataType> &delegate) : _delegate(delegate){
|
||||||
_Sec_WebSocket_Key = encodeBase64(SHA1::encode_bin(makeRandStr(16, false)));
|
_Sec_WebSocket_Key = encodeBase64(SHA1::encode_bin(makeRandStr(16, false)));
|
||||||
_poller = delegate.getPoller();
|
setPoller(delegate.getPoller());
|
||||||
}
|
}
|
||||||
~HttpWsClient(){}
|
~HttpWsClient(){}
|
||||||
|
|
||||||
@ -312,7 +312,7 @@ private:
|
|||||||
});
|
});
|
||||||
|
|
||||||
//设置sock,否则shutdown等接口都无效
|
//设置sock,否则shutdown等接口都无效
|
||||||
_delegate.setSock(HttpClientImp::_sock);
|
_delegate.setSock(HttpClientImp::getSock());
|
||||||
//触发连接成功事件
|
//触发连接成功事件
|
||||||
_delegate.onConnect(ex);
|
_delegate.onConnect(ex);
|
||||||
//拦截websocket数据接收
|
//拦截websocket数据接收
|
||||||
|
@ -117,7 +117,7 @@ protected:
|
|||||||
*/
|
*/
|
||||||
bool onWebSocketConnect(const Parser &header) override{
|
bool onWebSocketConnect(const Parser &header) override{
|
||||||
//创建websocket session类
|
//创建websocket session类
|
||||||
_session = _creator(header, *this,HttpSessionType::_sock);
|
_session = _creator(header, *this,HttpSessionType::getSock());
|
||||||
if(!_session){
|
if(!_session){
|
||||||
//此url不允许创建websocket连接
|
//此url不允许创建websocket连接
|
||||||
return false;
|
return false;
|
||||||
|
@ -17,31 +17,43 @@ using namespace toolkit;
|
|||||||
namespace mediakit {
|
namespace mediakit {
|
||||||
|
|
||||||
MediaPlayer::MediaPlayer(const EventPoller::Ptr &poller) {
|
MediaPlayer::MediaPlayer(const EventPoller::Ptr &poller) {
|
||||||
_poller = poller;
|
_poller = poller ? poller : EventPollerPool::Instance().getPoller();
|
||||||
if(!_poller){
|
|
||||||
_poller = EventPollerPool::Instance().getPoller();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MediaPlayer::~MediaPlayer() {
|
MediaPlayer::~MediaPlayer() {
|
||||||
}
|
}
|
||||||
void MediaPlayer::play(const string &strUrl) {
|
|
||||||
_delegate = PlayerBase::createPlayer(_poller,strUrl);
|
static void setOnCreateSocket_l(const std::shared_ptr<PlayerBase> &delegate, const Socket::onCreateSocket &cb){
|
||||||
|
auto helper = dynamic_pointer_cast<SocketHelper>(delegate);
|
||||||
|
if (helper) {
|
||||||
|
helper->setOnCreateSocket(cb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MediaPlayer::play(const string &url) {
|
||||||
|
_delegate = PlayerBase::createPlayer(_poller, url);
|
||||||
|
assert(_delegate);
|
||||||
|
setOnCreateSocket_l(_delegate, _on_create_socket);
|
||||||
_delegate->setOnShutdown(_shutdownCB);
|
_delegate->setOnShutdown(_shutdownCB);
|
||||||
_delegate->setOnPlayResult(_playResultCB);
|
_delegate->setOnPlayResult(_playResultCB);
|
||||||
_delegate->setOnResume(_resumeCB);
|
_delegate->setOnResume(_resumeCB);
|
||||||
_delegate->setMediaSouce(_pMediaSrc);
|
_delegate->setMediaSouce(_pMediaSrc);
|
||||||
_delegate->mINI::operator=(*this);
|
_delegate->mINI::operator=(*this);
|
||||||
_delegate->play(strUrl);
|
_delegate->play(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
EventPoller::Ptr MediaPlayer::getPoller(){
|
EventPoller::Ptr MediaPlayer::getPoller(){
|
||||||
return _poller;
|
return _poller;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaPlayer::pause(bool bPause) {
|
void MediaPlayer::setOnCreateSocket(Socket::onCreateSocket cb){
|
||||||
|
setOnCreateSocket_l(_delegate, cb);
|
||||||
|
_on_create_socket = std::move(cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MediaPlayer::pause(bool pause) {
|
||||||
if (_delegate) {
|
if (_delegate) {
|
||||||
_delegate->pause(bPause);
|
_delegate->pause(pause);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,12 +27,15 @@ public:
|
|||||||
|
|
||||||
MediaPlayer(const EventPoller::Ptr &poller = nullptr);
|
MediaPlayer(const EventPoller::Ptr &poller = nullptr);
|
||||||
virtual ~MediaPlayer();
|
virtual ~MediaPlayer();
|
||||||
void play(const string &strUrl) override;
|
void play(const string &url) override;
|
||||||
void pause(bool bPause) override;
|
void pause(bool pause) override;
|
||||||
void teardown() override;
|
void teardown() override;
|
||||||
EventPoller::Ptr getPoller();
|
EventPoller::Ptr getPoller();
|
||||||
|
void setOnCreateSocket(Socket::onCreateSocket cb);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EventPoller::Ptr _poller;
|
EventPoller::Ptr _poller;
|
||||||
|
Socket::onCreateSocket _on_create_socket;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace mediakit */
|
} /* namespace mediakit */
|
||||||
|
@ -19,34 +19,44 @@ namespace mediakit {
|
|||||||
MediaPusher::MediaPusher(const MediaSource::Ptr &src,
|
MediaPusher::MediaPusher(const MediaSource::Ptr &src,
|
||||||
const EventPoller::Ptr &poller) {
|
const EventPoller::Ptr &poller) {
|
||||||
_src = src;
|
_src = src;
|
||||||
_poller = poller;
|
_poller = poller ? poller : EventPollerPool::Instance().getPoller();
|
||||||
if(!_poller){
|
|
||||||
_poller = EventPollerPool::Instance().getPoller();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MediaPusher::MediaPusher(const string &schema,
|
MediaPusher::MediaPusher(const string &schema,
|
||||||
const string &strVhost,
|
const string &vhost,
|
||||||
const string &strApp,
|
const string &app,
|
||||||
const string &strStream,
|
const string &stream,
|
||||||
const EventPoller::Ptr &poller) :
|
const EventPoller::Ptr &poller) :
|
||||||
MediaPusher(MediaSource::find(schema,strVhost,strApp,strStream),poller){
|
MediaPusher(MediaSource::find(schema, vhost, app, stream), poller){
|
||||||
}
|
}
|
||||||
|
|
||||||
MediaPusher::~MediaPusher() {
|
MediaPusher::~MediaPusher() {
|
||||||
}
|
}
|
||||||
void MediaPusher::publish(const string &strUrl) {
|
|
||||||
_delegate = PusherBase::createPusher(_poller,_src.lock(),strUrl);
|
static void setOnCreateSocket_l(const std::shared_ptr<PusherBase> &delegate, const Socket::onCreateSocket &cb){
|
||||||
|
auto helper = dynamic_pointer_cast<SocketHelper>(delegate);
|
||||||
|
if (helper) {
|
||||||
|
helper->setOnCreateSocket(cb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MediaPusher::publish(const string &url) {
|
||||||
|
_delegate = PusherBase::createPusher(_poller, _src.lock(), url);
|
||||||
|
assert(_delegate);
|
||||||
|
setOnCreateSocket_l(_delegate, _on_create_socket);
|
||||||
_delegate->setOnShutdown(_shutdownCB);
|
_delegate->setOnShutdown(_shutdownCB);
|
||||||
_delegate->setOnPublished(_publishCB);
|
_delegate->setOnPublished(_publishCB);
|
||||||
_delegate->mINI::operator=(*this);
|
_delegate->mINI::operator=(*this);
|
||||||
_delegate->publish(strUrl);
|
_delegate->publish(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
EventPoller::Ptr MediaPusher::getPoller(){
|
EventPoller::Ptr MediaPusher::getPoller(){
|
||||||
return _poller;
|
return _poller;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MediaPusher::setOnCreateSocket(Socket::onCreateSocket cb){
|
||||||
|
setOnCreateSocket_l(_delegate, cb);
|
||||||
|
_on_create_socket = std::move(cb);
|
||||||
|
}
|
||||||
|
|
||||||
} /* namespace mediakit */
|
} /* namespace mediakit */
|
||||||
|
@ -24,20 +24,24 @@ public:
|
|||||||
typedef std::shared_ptr<MediaPusher> Ptr;
|
typedef std::shared_ptr<MediaPusher> Ptr;
|
||||||
|
|
||||||
MediaPusher(const string &schema,
|
MediaPusher(const string &schema,
|
||||||
const string &strVhost,
|
const string &vhost,
|
||||||
const string &strApp,
|
const string &app,
|
||||||
const string &strStream,
|
const string &stream,
|
||||||
const EventPoller::Ptr &poller = nullptr);
|
const EventPoller::Ptr &poller = nullptr);
|
||||||
|
|
||||||
MediaPusher(const MediaSource::Ptr &src,
|
MediaPusher(const MediaSource::Ptr &src,
|
||||||
const EventPoller::Ptr &poller = nullptr);
|
const EventPoller::Ptr &poller = nullptr);
|
||||||
|
|
||||||
virtual ~MediaPusher();
|
virtual ~MediaPusher();
|
||||||
void publish(const string &strUrl) override;
|
|
||||||
|
void publish(const string &url) override;
|
||||||
EventPoller::Ptr getPoller();
|
EventPoller::Ptr getPoller();
|
||||||
|
void setOnCreateSocket(Socket::onCreateSocket cb);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::weak_ptr<MediaSource> _src;
|
std::weak_ptr<MediaSource> _src;
|
||||||
EventPoller::Ptr _poller;
|
EventPoller::Ptr _poller;
|
||||||
|
Socket::onCreateSocket _on_create_socket;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace mediakit */
|
} /* namespace mediakit */
|
||||||
|
@ -120,7 +120,7 @@ void RtmpPusher::onConnect(const SockException &err){
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//推流器不需要多大的接收缓存,节省内存占用
|
//推流器不需要多大的接收缓存,节省内存占用
|
||||||
_sock->setReadBuffer(std::make_shared<BufferRaw>(1 * 1024));
|
getSock()->setReadBuffer(std::make_shared<BufferRaw>(1 * 1024));
|
||||||
|
|
||||||
weak_ptr<RtmpPusher> weak_self = dynamic_pointer_cast<RtmpPusher>(shared_from_this());
|
weak_ptr<RtmpPusher> weak_self = dynamic_pointer_cast<RtmpPusher>(shared_from_this());
|
||||||
startClientSession([weak_self]() {
|
startClientSession([weak_self]() {
|
||||||
@ -239,7 +239,7 @@ void RtmpPusher::setSocketFlags(){
|
|||||||
if (mergeWriteMS > 0) {
|
if (mergeWriteMS > 0) {
|
||||||
//提高发送性能
|
//提高发送性能
|
||||||
setSendFlags(SOCKET_DEFAULE_FLAGS | FLAG_MORE);
|
setSendFlags(SOCKET_DEFAULE_FLAGS | FLAG_MORE);
|
||||||
SockUtil::setNoDelay(_sock->rawFD(), false);
|
SockUtil::setNoDelay(getSock()->rawFD(), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,7 +153,7 @@ void RtmpSession::onCmd_publish(AMFDecoder &dec) {
|
|||||||
_publisher_src->setProtocolTranslation(enableRtxp, enableHls, enableMP4);
|
_publisher_src->setProtocolTranslation(enableRtxp, enableHls, enableMP4);
|
||||||
|
|
||||||
//如果是rtmp推流客户端,那么加大TCP接收缓存,这样能提升接收性能
|
//如果是rtmp推流客户端,那么加大TCP接收缓存,这样能提升接收性能
|
||||||
_sock->setReadBuffer(std::make_shared<BufferRaw>(256 * 1024));
|
getSock()->setReadBuffer(std::make_shared<BufferRaw>(256 * 1024));
|
||||||
setSocketFlags();
|
setSocketFlags();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -548,7 +548,7 @@ void RtmpSession::setSocketFlags(){
|
|||||||
GET_CONFIG(int, merge_write_ms, General::kMergeWriteMS);
|
GET_CONFIG(int, merge_write_ms, General::kMergeWriteMS);
|
||||||
if (merge_write_ms > 0) {
|
if (merge_write_ms > 0) {
|
||||||
//推流模式下,关闭TCP_NODELAY会增加推流端的延时,但是服务器性能将提高
|
//推流模式下,关闭TCP_NODELAY会增加推流端的延时,但是服务器性能将提高
|
||||||
SockUtil::setNoDelay(_sock->rawFD(), false);
|
SockUtil::setNoDelay(getSock()->rawFD(), false);
|
||||||
//播放模式下,开启MSG_MORE会增加延时,但是能提高发送性能
|
//播放模式下,开启MSG_MORE会增加延时,但是能提高发送性能
|
||||||
setSendFlags(SOCKET_DEFAULE_FLAGS | FLAG_MORE);
|
setSendFlags(SOCKET_DEFAULE_FLAGS | FLAG_MORE);
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ PSRtpSender::~PSRtpSender() {
|
|||||||
|
|
||||||
void PSRtpSender::startSend(const string &dst_url, uint16_t dst_port, bool is_udp, const function<void(const SockException &ex)> &cb){
|
void PSRtpSender::startSend(const string &dst_url, uint16_t dst_port, bool is_udp, const function<void(const SockException &ex)> &cb){
|
||||||
_is_udp = is_udp;
|
_is_udp = is_udp;
|
||||||
_socket = std::make_shared<Socket>(_poller, false);
|
_socket = Socket::createSocket(_poller, false);
|
||||||
_dst_url = dst_url;
|
_dst_url = dst_url;
|
||||||
_dst_port = dst_port;
|
_dst_port = dst_port;
|
||||||
weak_ptr<PSRtpSender> weak_self = shared_from_this();
|
weak_ptr<PSRtpSender> weak_self = shared_from_this();
|
||||||
|
@ -24,7 +24,7 @@ RtpServer::~RtpServer() {
|
|||||||
|
|
||||||
void RtpServer::start(uint16_t local_port, const string &stream_id, bool enable_tcp, const char *local_ip) {
|
void RtpServer::start(uint16_t local_port, const string &stream_id, bool enable_tcp, const char *local_ip) {
|
||||||
//创建udp服务器
|
//创建udp服务器
|
||||||
Socket::Ptr udp_server = std::make_shared<Socket>(nullptr, false);
|
Socket::Ptr udp_server = Socket::createSocket(nullptr, false);
|
||||||
if (!udp_server->bindUdpSock(local_port, local_ip)) {
|
if (!udp_server->bindUdpSock(local_port, local_ip)) {
|
||||||
throw std::runtime_error(StrPrinter << "bindUdpSock on " << local_ip << ":" << local_port << " failed:" << get_uv_errmsg(true));
|
throw std::runtime_error(StrPrinter << "bindUdpSock on " << local_ip << ":" << local_port << " failed:" << get_uv_errmsg(true));
|
||||||
}
|
}
|
||||||
@ -33,14 +33,10 @@ void RtpServer::start(uint16_t local_port, const string &stream_id, bool enable
|
|||||||
|
|
||||||
TcpServer::Ptr tcp_server;
|
TcpServer::Ptr tcp_server;
|
||||||
if (enable_tcp) {
|
if (enable_tcp) {
|
||||||
try {
|
|
||||||
//创建tcp服务器
|
//创建tcp服务器
|
||||||
tcp_server = std::make_shared<TcpServer>(udp_server->getPoller());
|
tcp_server = std::make_shared<TcpServer>(udp_server->getPoller());
|
||||||
(*tcp_server)[RtpSession::kStreamID] = stream_id;
|
(*tcp_server)[RtpSession::kStreamID] = stream_id;
|
||||||
tcp_server->start<RtpSession>(udp_server->get_local_port(), local_ip);
|
tcp_server->start<RtpSession>(udp_server->get_local_port(), local_ip);
|
||||||
} catch (...) {
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RtpProcess::Ptr process;
|
RtpProcess::Ptr process;
|
||||||
|
@ -70,7 +70,7 @@ void RtpSession::onRtpPacket(const char *data, uint64_t len) {
|
|||||||
_process = RtpSelector::Instance().getProcess(_stream_id, true);
|
_process = RtpSelector::Instance().getProcess(_stream_id, true);
|
||||||
_process->setListener(dynamic_pointer_cast<RtpSession>(shared_from_this()));
|
_process->setListener(dynamic_pointer_cast<RtpSession>(shared_from_this()));
|
||||||
}
|
}
|
||||||
_process->inputRtp(_sock, data + 2, len - 2, &addr);
|
_process->inputRtp(getSock(), data + 2, len - 2, &addr);
|
||||||
_ticker.resetTime();
|
_ticker.resetTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,153 +25,177 @@ MultiCastAddressMaker &MultiCastAddressMaker::Instance() {
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t addressToInt(const string &ip){
|
bool MultiCastAddressMaker::isMultiCastAddress(uint32_t addr) {
|
||||||
struct in_addr addr;
|
static uint32_t addrMin = mINI::Instance()[MultiCast::kAddrMin].as<uint32_t>();
|
||||||
bzero(&addr,sizeof(addr));
|
static uint32_t addrMax = mINI::Instance()[MultiCast::kAddrMax].as<uint32_t>();
|
||||||
addr.s_addr = inet_addr(ip.data());
|
return addr >= addrMin && addr <= addrMax;
|
||||||
return (uint32_t)ntohl((uint32_t &)addr.s_addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<uint32_t> MultiCastAddressMaker::obtain(uint32_t iTry) {
|
string MultiCastAddressMaker::toString(uint32_t addr) {
|
||||||
|
addr = htonl(addr);
|
||||||
|
return SockUtil::inet_ntoa((struct in_addr &) (addr));
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t addressToInt(const string &ip){
|
||||||
|
struct in_addr addr;
|
||||||
|
bzero(&addr, sizeof(addr));
|
||||||
|
addr.s_addr = inet_addr(ip.data());
|
||||||
|
return (uint32_t) ntohl((uint32_t &) addr.s_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<uint32_t> MultiCastAddressMaker::obtain(uint32_t max_try) {
|
||||||
lock_guard<recursive_mutex> lck(_mtx);
|
lock_guard<recursive_mutex> lck(_mtx);
|
||||||
GET_CONFIG(string,addrMinStr,MultiCast::kAddrMin);
|
GET_CONFIG(string, addrMinStr, MultiCast::kAddrMin);
|
||||||
GET_CONFIG(string,addrMaxStr,MultiCast::kAddrMax);
|
GET_CONFIG(string, addrMaxStr, MultiCast::kAddrMax);
|
||||||
uint32_t addrMin = addressToInt(addrMinStr);
|
uint32_t addrMin = addressToInt(addrMinStr);
|
||||||
uint32_t addrMax = addressToInt(addrMaxStr);
|
uint32_t addrMax = addressToInt(addrMaxStr);
|
||||||
|
|
||||||
if(_iAddr > addrMax || _iAddr == 0){
|
if (_addr > addrMax || _addr == 0) {
|
||||||
_iAddr = addrMin;
|
_addr = addrMin;
|
||||||
}
|
}
|
||||||
auto iGotAddr = _iAddr++;
|
auto iGotAddr = _addr++;
|
||||||
if(_setBadAddr.find(iGotAddr) != _setBadAddr.end()){
|
if (_used_addr.find(iGotAddr) != _used_addr.end()) {
|
||||||
//已经分配过了
|
//已经分配过了
|
||||||
if(iTry){
|
if (max_try) {
|
||||||
return obtain(--iTry);
|
return obtain(--max_try);
|
||||||
}
|
}
|
||||||
//分配完了,应该不可能到这里
|
//分配完了,应该不可能到这里
|
||||||
ErrorL;
|
ErrorL;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
_setBadAddr.emplace(iGotAddr);
|
_used_addr.emplace(iGotAddr);
|
||||||
std::shared_ptr<uint32_t> ret(new uint32_t(iGotAddr),[](uint32_t *ptr){
|
std::shared_ptr<uint32_t> ret(new uint32_t(iGotAddr), [](uint32_t *ptr) {
|
||||||
MultiCastAddressMaker::Instance().release(*ptr);
|
MultiCastAddressMaker::Instance().release(*ptr);
|
||||||
delete ptr;
|
delete ptr;
|
||||||
});
|
});
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
void MultiCastAddressMaker::release(uint32_t iAddr){
|
|
||||||
|
void MultiCastAddressMaker::release(uint32_t addr){
|
||||||
lock_guard<recursive_mutex> lck(_mtx);
|
lock_guard<recursive_mutex> lck(_mtx);
|
||||||
_setBadAddr.erase(iAddr);
|
_used_addr.erase(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
recursive_mutex RtpMultiCaster::g_mtx;
|
recursive_mutex g_mtx;
|
||||||
unordered_map<string, weak_ptr<RtpMultiCaster> > RtpMultiCaster::g_mapBroadCaster;
|
unordered_map<string, weak_ptr<RtpMultiCaster> > g_multi_caster_map;
|
||||||
|
|
||||||
void RtpMultiCaster::setDetachCB(void* listener, const onDetach& cb) {
|
void RtpMultiCaster::setDetachCB(void* listener, const onDetach& cb) {
|
||||||
lock_guard<recursive_mutex> lck(_mtx);
|
lock_guard<recursive_mutex> lck(_mtx);
|
||||||
if(cb){
|
if (cb) {
|
||||||
_mapDetach.emplace(listener,cb);
|
_detach_map.emplace(listener, cb);
|
||||||
}else{
|
} else {
|
||||||
_mapDetach.erase(listener);
|
_detach_map.erase(listener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RtpMultiCaster::~RtpMultiCaster() {
|
RtpMultiCaster::~RtpMultiCaster() {
|
||||||
_pReader->setReadCB(nullptr);
|
_rtp_reader->setReadCB(nullptr);
|
||||||
_pReader->setDetachCB(nullptr);
|
_rtp_reader->setDetachCB(nullptr);
|
||||||
DebugL;
|
DebugL;
|
||||||
}
|
}
|
||||||
|
|
||||||
RtpMultiCaster::RtpMultiCaster(const EventPoller::Ptr &poller,const string &strLocalIp,const string &strVhost,const string &strApp,const string &strStream) {
|
RtpMultiCaster::RtpMultiCaster(SocketHelper &helper, const string &local_ip, const string &vhost, const string &app, const string &stream) {
|
||||||
auto src = dynamic_pointer_cast<RtspMediaSource>(MediaSource::find(RTSP_SCHEMA,strVhost,strApp, strStream));
|
auto src = dynamic_pointer_cast<RtspMediaSource>(MediaSource::find(RTSP_SCHEMA, vhost, app, stream));
|
||||||
if(!src){
|
if (!src) {
|
||||||
auto strErr = StrPrinter << "未找到媒体源:" << strVhost << " " << strApp << " " << strStream << endl;
|
auto err = StrPrinter << "未找到媒体源:" << vhost << " " << app << " " << stream << endl;
|
||||||
throw std::runtime_error(strErr);
|
throw std::runtime_error(err);
|
||||||
}
|
}
|
||||||
_multiAddr = MultiCastAddressMaker::Instance().obtain();
|
_multicast_ip = MultiCastAddressMaker::Instance().obtain();
|
||||||
for(auto i = 0; i < 2; i++){
|
if (!_multicast_ip) {
|
||||||
_apUdpSock[i].reset(new Socket(poller));
|
throw std::runtime_error("获取组播地址失败");
|
||||||
if(!_apUdpSock[i]->bindUdpSock(0, strLocalIp.data())){
|
|
||||||
auto strErr = StrPrinter << "绑定UDP端口失败:" << strLocalIp << endl;
|
|
||||||
throw std::runtime_error(strErr);
|
|
||||||
}
|
}
|
||||||
auto fd = _apUdpSock[i]->rawFD();
|
|
||||||
GET_CONFIG(uint32_t,udpTTL,MultiCast::kUdpTTL);
|
|
||||||
|
|
||||||
|
for (auto i = 0; i < 2; ++i) {
|
||||||
|
//创建udp socket, 数组下标为TrackType
|
||||||
|
_udp_sock[i] = helper.createSocket();
|
||||||
|
if (!_udp_sock[i]->bindUdpSock(0, local_ip.data())) {
|
||||||
|
auto err = StrPrinter << "绑定UDP端口失败:" << local_ip << endl;
|
||||||
|
throw std::runtime_error(err);
|
||||||
|
}
|
||||||
|
auto fd = _udp_sock[i]->rawFD();
|
||||||
|
GET_CONFIG(uint32_t, udpTTL, MultiCast::kUdpTTL);
|
||||||
SockUtil::setMultiTTL(fd, udpTTL);
|
SockUtil::setMultiTTL(fd, udpTTL);
|
||||||
SockUtil::setMultiLOOP(fd, false);
|
SockUtil::setMultiLOOP(fd, false);
|
||||||
SockUtil::setMultiIF(fd, strLocalIp.data());
|
SockUtil::setMultiIF(fd, local_ip.data());
|
||||||
|
|
||||||
struct sockaddr_in &peerAddr = _aPeerUdpAddr[i];
|
struct sockaddr_in peer;
|
||||||
peerAddr.sin_family = AF_INET;
|
peer.sin_family = AF_INET;
|
||||||
peerAddr.sin_port = htons(_apUdpSock[i]->get_local_port());
|
//组播目标端口为本地发送端口
|
||||||
peerAddr.sin_addr.s_addr = htonl(*_multiAddr);
|
peer.sin_port = htons(_udp_sock[i]->get_local_port());
|
||||||
bzero(&(peerAddr.sin_zero), sizeof peerAddr.sin_zero);
|
//组播目标地址
|
||||||
_apUdpSock[i]->setSendPeerAddr((struct sockaddr *)&peerAddr);
|
peer.sin_addr.s_addr = htonl(*_multicast_ip);
|
||||||
|
bzero(&(peer.sin_zero), sizeof peer.sin_zero);
|
||||||
|
_udp_sock[i]->setSendPeerAddr((struct sockaddr *) &peer);
|
||||||
}
|
}
|
||||||
_pReader = src->getRing()->attach(poller);
|
|
||||||
_pReader->setReadCB([this](const RtspMediaSource::RingDataType &pkt){
|
_rtp_reader = src->getRing()->attach(helper.getPoller());
|
||||||
|
_rtp_reader->setReadCB([this](const RtspMediaSource::RingDataType &pkt) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int size = pkt->size();
|
int size = pkt->size();
|
||||||
pkt->for_each([&](const RtpPacket::Ptr &rtp) {
|
pkt->for_each([&](const RtpPacket::Ptr &rtp) {
|
||||||
auto &pSock = _apUdpSock[rtp->type];
|
auto &sock = _udp_sock[rtp->type];
|
||||||
auto &peerAddr = _aPeerUdpAddr[rtp->type];
|
sock->send(std::make_shared<BufferRtp>(rtp, 4), nullptr, 0, ++i == size);
|
||||||
BufferRtp::Ptr buffer(new BufferRtp(rtp, 4));
|
|
||||||
pSock->send(buffer, nullptr, 0, ++i == size);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
_pReader->setDetachCB([this](){
|
_rtp_reader->setDetachCB([this]() {
|
||||||
unordered_map<void * , onDetach > _mapDetach_copy;
|
unordered_map<void *, onDetach> _detach_map_copy;
|
||||||
{
|
{
|
||||||
lock_guard<recursive_mutex> lck(_mtx);
|
lock_guard<recursive_mutex> lck(_mtx);
|
||||||
_mapDetach_copy = std::move(_mapDetach);
|
_detach_map_copy = std::move(_detach_map);
|
||||||
}
|
}
|
||||||
for(auto &pr : _mapDetach_copy){
|
for (auto &pr : _detach_map_copy) {
|
||||||
pr.second();
|
pr.second();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
DebugL << MultiCastAddressMaker::toString(*_multiAddr) << " "
|
|
||||||
<< _apUdpSock[0]->get_local_port() << " "
|
DebugL << MultiCastAddressMaker::toString(*_multicast_ip) << " "
|
||||||
<< _apUdpSock[1]->get_local_port() << " "
|
<< _udp_sock[0]->get_local_port() << " "
|
||||||
<< strVhost << " "
|
<< _udp_sock[1]->get_local_port() << " "
|
||||||
<< strApp << " " << strStream;
|
<< vhost << " " << app << " " << stream;
|
||||||
}
|
}
|
||||||
uint16_t RtpMultiCaster::getPort(TrackType trackType){
|
|
||||||
return _apUdpSock[trackType]->get_local_port();
|
uint16_t RtpMultiCaster::getMultiCasterPort(TrackType trackType) {
|
||||||
|
return _udp_sock[trackType]->get_local_port();
|
||||||
}
|
}
|
||||||
string RtpMultiCaster::getIP(){
|
|
||||||
return SockUtil::inet_ntoa(_aPeerUdpAddr[0].sin_addr);
|
string RtpMultiCaster::getMultiCasterIP() {
|
||||||
|
struct in_addr addr;
|
||||||
|
addr.s_addr = htonl(*_multicast_ip);
|
||||||
|
return SockUtil::inet_ntoa(addr);
|
||||||
}
|
}
|
||||||
RtpMultiCaster::Ptr RtpMultiCaster::make(const EventPoller::Ptr &poller,const string &strLocalIp,const string &strVhost,const string &strApp,const string &strStream){
|
|
||||||
try{
|
RtpMultiCaster::Ptr RtpMultiCaster::get(SocketHelper &helper, const string &local_ip, const string &vhost, const string &app, const string &stream) {
|
||||||
auto ret = Ptr(new RtpMultiCaster(poller,strLocalIp,strVhost,strApp,strStream),[poller](RtpMultiCaster *ptr){
|
static auto on_create = [](SocketHelper &helper, const string &local_ip, const string &vhost, const string &app, const string &stream){
|
||||||
|
try {
|
||||||
|
auto poller = helper.getPoller();
|
||||||
|
auto ret = RtpMultiCaster::Ptr(new RtpMultiCaster(helper, local_ip, vhost, app, stream), [poller](RtpMultiCaster *ptr) {
|
||||||
poller->async([ptr]() {
|
poller->async([ptr]() {
|
||||||
delete ptr;
|
delete ptr;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
lock_guard<recursive_mutex> lck(g_mtx);
|
lock_guard<recursive_mutex> lck(g_mtx);
|
||||||
string strKey = StrPrinter << strLocalIp << " " << strVhost << " " << strApp << " " << strStream << endl;
|
string strKey = StrPrinter << local_ip << " " << vhost << " " << app << " " << stream << endl;
|
||||||
weak_ptr<RtpMultiCaster> weakPtr = ret;
|
g_multi_caster_map.emplace(strKey, ret);
|
||||||
g_mapBroadCaster.emplace(strKey,weakPtr);
|
|
||||||
return ret;
|
return ret;
|
||||||
}catch (std::exception &ex) {
|
} catch (std::exception &ex) {
|
||||||
WarnL << ex.what();
|
WarnL << ex.what();
|
||||||
return nullptr;
|
return RtpMultiCaster::Ptr();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
RtpMultiCaster::Ptr RtpMultiCaster::get(const EventPoller::Ptr &poller,const string &strLocalIp,const string &strVhost,const string &strApp,const string &strStream) {
|
string strKey = StrPrinter << local_ip << " " << vhost << " " << app << " " << stream << endl;
|
||||||
string strKey = StrPrinter << strLocalIp << " " << strVhost << " " << strApp << " " << strStream << endl;
|
|
||||||
lock_guard<recursive_mutex> lck(g_mtx);
|
lock_guard<recursive_mutex> lck(g_mtx);
|
||||||
auto it = g_mapBroadCaster.find(strKey);
|
auto it = g_multi_caster_map.find(strKey);
|
||||||
if (it == g_mapBroadCaster.end()) {
|
if (it == g_multi_caster_map.end()) {
|
||||||
return make(poller,strLocalIp,strVhost,strApp, strStream);
|
return on_create(helper, local_ip, vhost, app, stream);
|
||||||
}
|
}
|
||||||
auto ret = it->second.lock();
|
auto ret = it->second.lock();
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
g_mapBroadCaster.erase(it);
|
g_multi_caster_map.erase(it);
|
||||||
return make(poller,strLocalIp,strVhost,strApp, strStream);
|
return on_create(helper, local_ip, vhost, app, stream);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
#ifndef SRC_RTSP_RTPBROADCASTER_H_
|
#ifndef SRC_RTSP_RTPBROADCASTER_H_
|
||||||
#define SRC_RTSP_RTPBROADCASTER_H_
|
#define SRC_RTSP_RTPBROADCASTER_H_
|
||||||
|
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
@ -20,60 +19,52 @@
|
|||||||
#include "RtspMediaSource.h"
|
#include "RtspMediaSource.h"
|
||||||
#include "Util/mini.h"
|
#include "Util/mini.h"
|
||||||
#include "Network/Socket.h"
|
#include "Network/Socket.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace toolkit;
|
using namespace toolkit;
|
||||||
|
|
||||||
namespace mediakit{
|
namespace mediakit{
|
||||||
|
|
||||||
class MultiCastAddressMaker
|
class MultiCastAddressMaker {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
static MultiCastAddressMaker &Instance();
|
~MultiCastAddressMaker() {}
|
||||||
|
static MultiCastAddressMaker& Instance();
|
||||||
|
static bool isMultiCastAddress(uint32_t addr);
|
||||||
|
static string toString(uint32_t addr);
|
||||||
|
|
||||||
|
std::shared_ptr<uint32_t> obtain(uint32_t max_try = 10);
|
||||||
|
|
||||||
static bool isMultiCastAddress(uint32_t iAddr){
|
|
||||||
static uint32_t addrMin = mINI::Instance()[MultiCast::kAddrMin].as<uint32_t>();
|
|
||||||
static uint32_t addrMax = mINI::Instance()[MultiCast::kAddrMax].as<uint32_t>();
|
|
||||||
return iAddr >= addrMin && iAddr <= addrMax;
|
|
||||||
}
|
|
||||||
static string toString(uint32_t iAddr){
|
|
||||||
iAddr = htonl(iAddr);
|
|
||||||
return SockUtil::inet_ntoa((struct in_addr &)(iAddr));
|
|
||||||
}
|
|
||||||
virtual ~MultiCastAddressMaker(){}
|
|
||||||
std::shared_ptr<uint32_t> obtain(uint32_t iTry = 10);
|
|
||||||
private:
|
private:
|
||||||
MultiCastAddressMaker(){};
|
MultiCastAddressMaker() {};
|
||||||
void release(uint32_t iAddr);
|
void release(uint32_t addr);
|
||||||
uint32_t _iAddr = 0;
|
|
||||||
|
private:
|
||||||
|
uint32_t _addr = 0;
|
||||||
recursive_mutex _mtx;
|
recursive_mutex _mtx;
|
||||||
unordered_set<uint32_t> _setBadAddr;
|
unordered_set<uint32_t> _used_addr;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RtpMultiCaster {
|
class RtpMultiCaster {
|
||||||
public:
|
public:
|
||||||
typedef std::shared_ptr<RtpMultiCaster> Ptr;
|
typedef std::shared_ptr<RtpMultiCaster> Ptr;
|
||||||
typedef function<void()> onDetach;
|
typedef function<void()> onDetach;
|
||||||
virtual ~RtpMultiCaster();
|
~RtpMultiCaster();
|
||||||
static Ptr get(const EventPoller::Ptr &poller,const string &strLocalIp,const string &strVhost,const string &strApp,const string &strStream);
|
|
||||||
|
static Ptr get(SocketHelper &helper, const string &local_ip, const string &vhost, const string &app, const string &stream);
|
||||||
void setDetachCB(void *listener,const onDetach &cb);
|
void setDetachCB(void *listener,const onDetach &cb);
|
||||||
uint16_t getPort(TrackType trackType);
|
|
||||||
string getIP();
|
string getMultiCasterIP();
|
||||||
|
uint16_t getMultiCasterPort(TrackType trackType);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static recursive_mutex g_mtx;
|
RtpMultiCaster(SocketHelper &helper, const string &local_ip, const string &vhost, const string &app, const string &stream);
|
||||||
static unordered_map<string , weak_ptr<RtpMultiCaster> > g_mapBroadCaster;
|
|
||||||
static Ptr make(const EventPoller::Ptr &poller,const string &strLocalIp,const string &strVhost,const string &strApp,const string &strStream);
|
|
||||||
|
|
||||||
std::shared_ptr<uint32_t> _multiAddr;
|
private:
|
||||||
recursive_mutex _mtx;
|
recursive_mutex _mtx;
|
||||||
unordered_map<void * , onDetach > _mapDetach;
|
Socket::Ptr _udp_sock[2];
|
||||||
RtspMediaSource::RingType::RingReader::Ptr _pReader;
|
std::shared_ptr<uint32_t> _multicast_ip;
|
||||||
Socket::Ptr _apUdpSock[2];
|
unordered_map<void * , onDetach > _detach_map;
|
||||||
struct sockaddr_in _aPeerUdpAddr[2];
|
RtspMediaSource::RingType::RingReader::Ptr _rtp_reader;
|
||||||
|
|
||||||
RtpMultiCaster(const EventPoller::Ptr &poller,const string &strLocalIp,const string &strVhost,const string &strApp,const string &strStream);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}//namespace mediakit
|
}//namespace mediakit
|
||||||
|
|
||||||
#endif /* SRC_RTSP_RTPBROADCASTER_H_ */
|
#endif /* SRC_RTSP_RTPBROADCASTER_H_ */
|
||||||
|
@ -365,8 +365,10 @@ bool RtspUrl::setup(bool isSSL, const string &strUrl, const string &strUser, con
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<Socket::Ptr, Socket::Ptr> makeSockPair_l(const EventPoller::Ptr &poller, const string &local_ip){
|
static void makeSockPair_l(std::pair<Socket::Ptr, Socket::Ptr> &pair, const string &local_ip){
|
||||||
auto pSockRtp = std::make_shared<Socket>(poller);
|
auto &pSockRtp = pair.first;
|
||||||
|
auto &pSockRtcp = pair.second;
|
||||||
|
|
||||||
if (!pSockRtp->bindUdpSock(0, local_ip.data())) {
|
if (!pSockRtp->bindUdpSock(0, local_ip.data())) {
|
||||||
//分配端口失败
|
//分配端口失败
|
||||||
throw runtime_error("open udp socket failed");
|
throw runtime_error("open udp socket failed");
|
||||||
@ -374,7 +376,6 @@ std::pair<Socket::Ptr, Socket::Ptr> makeSockPair_l(const EventPoller::Ptr &polle
|
|||||||
|
|
||||||
//是否是偶数
|
//是否是偶数
|
||||||
bool even_numbers = pSockRtp->get_local_port() % 2 == 0;
|
bool even_numbers = pSockRtp->get_local_port() % 2 == 0;
|
||||||
auto pSockRtcp = std::make_shared<Socket>(poller);
|
|
||||||
if (!pSockRtcp->bindUdpSock(pSockRtp->get_local_port() + (even_numbers ? 1 : -1), local_ip.data())) {
|
if (!pSockRtcp->bindUdpSock(pSockRtp->get_local_port() + (even_numbers ? 1 : -1), local_ip.data())) {
|
||||||
//分配端口失败
|
//分配端口失败
|
||||||
throw runtime_error("open udp socket failed");
|
throw runtime_error("open udp socket failed");
|
||||||
@ -386,15 +387,14 @@ std::pair<Socket::Ptr, Socket::Ptr> makeSockPair_l(const EventPoller::Ptr &polle
|
|||||||
pSockRtp = pSockRtcp;
|
pSockRtp = pSockRtcp;
|
||||||
pSockRtcp = tmp;
|
pSockRtcp = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::make_pair(pSockRtp, pSockRtcp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<Socket::Ptr, Socket::Ptr> makeSockPair(const EventPoller::Ptr &poller, const string &local_ip){
|
void makeSockPair(std::pair<Socket::Ptr, Socket::Ptr> &pair, const string &local_ip){
|
||||||
int try_count = 0;
|
int try_count = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
return makeSockPair_l(poller, local_ip);
|
makeSockPair_l(pair, local_ip);
|
||||||
|
break;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
if (++try_count == 3) {
|
if (++try_count == 3) {
|
||||||
throw;
|
throw;
|
||||||
|
@ -271,7 +271,7 @@ private:
|
|||||||
_StrPrinter _printer;
|
_StrPrinter _printer;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::pair<Socket::Ptr, Socket::Ptr> makeSockPair(const EventPoller::Ptr &poller, const string &local_ip);
|
void makeSockPair(std::pair<Socket::Ptr, Socket::Ptr> &pair, const string &local_ip);
|
||||||
string printSSRC(uint32_t ui32Ssrc);
|
string printSSRC(uint32_t ui32Ssrc);
|
||||||
|
|
||||||
} //namespace mediakit
|
} //namespace mediakit
|
||||||
|
@ -211,7 +211,8 @@ void RtspPlayer::createUdpSockIfNecessary(int track_idx){
|
|||||||
auto &rtpSockRef = _rtp_sock[track_idx];
|
auto &rtpSockRef = _rtp_sock[track_idx];
|
||||||
auto &rtcpSockRef = _rtcp_sock[track_idx];
|
auto &rtcpSockRef = _rtcp_sock[track_idx];
|
||||||
if (!rtpSockRef || !rtcpSockRef) {
|
if (!rtpSockRef || !rtcpSockRef) {
|
||||||
auto pr = makeSockPair(getPoller(), get_local_ip());
|
std::pair<Socket::Ptr, Socket::Ptr> pr = std::make_pair(createSocket(), createSocket());
|
||||||
|
makeSockPair(pr, get_local_ip());
|
||||||
rtpSockRef = pr.first;
|
rtpSockRef = pr.first;
|
||||||
rtcpSockRef = pr.second;
|
rtcpSockRef = pr.second;
|
||||||
}
|
}
|
||||||
@ -280,7 +281,7 @@ void RtspPlayer::handleResSETUP(const Parser &parser, unsigned int track_idx) {
|
|||||||
if (_rtp_type == Rtsp::RTP_MULTICAST) {
|
if (_rtp_type == Rtsp::RTP_MULTICAST) {
|
||||||
//udp组播
|
//udp组播
|
||||||
auto multiAddr = FindField((strTransport + ";").data(), "destination=", ";");
|
auto multiAddr = FindField((strTransport + ";").data(), "destination=", ";");
|
||||||
pRtpSockRef.reset(new Socket(getPoller()));
|
pRtpSockRef = createSocket();
|
||||||
if (!pRtpSockRef->bindUdpSock(rtp_port, multiAddr.data())) {
|
if (!pRtpSockRef->bindUdpSock(rtp_port, multiAddr.data())) {
|
||||||
pRtpSockRef.reset();
|
pRtpSockRef.reset();
|
||||||
throw std::runtime_error("open udp sock err");
|
throw std::runtime_error("open udp sock err");
|
||||||
|
@ -122,7 +122,7 @@ void RtspPusher::onConnect(const SockException &err) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//推流器不需要多大的接收缓存,节省内存占用
|
//推流器不需要多大的接收缓存,节省内存占用
|
||||||
_sock->setReadBuffer(std::make_shared<BufferRaw>(1 * 1024));
|
getSock()->setReadBuffer(std::make_shared<BufferRaw>(1 * 1024));
|
||||||
sendAnnounce();
|
sendAnnounce();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,7 +228,7 @@ bool RtspPusher::handleAuthenticationFailure(const string ¶ms_str) {
|
|||||||
void RtspPusher::createUdpSockIfNecessary(int track_idx){
|
void RtspPusher::createUdpSockIfNecessary(int track_idx){
|
||||||
auto &rtp_sock = _udp_socks[track_idx];
|
auto &rtp_sock = _udp_socks[track_idx];
|
||||||
if (!rtp_sock) {
|
if (!rtp_sock) {
|
||||||
rtp_sock.reset(new Socket(getPoller()));
|
rtp_sock = createSocket();
|
||||||
//rtp随机端口
|
//rtp随机端口
|
||||||
if (!rtp_sock->bindUdpSock(0, get_local_ip().data())) {
|
if (!rtp_sock->bindUdpSock(0, get_local_ip().data())) {
|
||||||
rtp_sock.reset();
|
rtp_sock.reset();
|
||||||
@ -400,7 +400,7 @@ void RtspPusher::setSocketFlags(){
|
|||||||
if (merge_write_ms > 0) {
|
if (merge_write_ms > 0) {
|
||||||
//提高发送性能
|
//提高发送性能
|
||||||
setSendFlags(SOCKET_DEFAULE_FLAGS | FLAG_MORE);
|
setSendFlags(SOCKET_DEFAULE_FLAGS | FLAG_MORE);
|
||||||
SockUtil::setNoDelay(_sock->rawFD(), false);
|
SockUtil::setNoDelay(getSock()->rawFD(), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,7 +277,7 @@ void RtspSession::handleReq_RECORD(const Parser &parser){
|
|||||||
sendRtspResponse("200 OK", {"RTP-Info",rtp_info});
|
sendRtspResponse("200 OK", {"RTP-Info",rtp_info});
|
||||||
if(_rtp_type == Rtsp::RTP_TCP){
|
if(_rtp_type == Rtsp::RTP_TCP){
|
||||||
//如果是rtsp推流服务器,并且是TCP推流,那么加大TCP接收缓存,这样能提升接收性能
|
//如果是rtsp推流服务器,并且是TCP推流,那么加大TCP接收缓存,这样能提升接收性能
|
||||||
_sock->setReadBuffer(std::make_shared<BufferRaw>(256 * 1024));
|
getSock()->setReadBuffer(std::make_shared<BufferRaw>(256 * 1024));
|
||||||
setSocketFlags();
|
setSocketFlags();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -667,10 +667,10 @@ void RtspSession::handleReq_Setup(const Parser &parser) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Rtsp::RTP_UDP: {
|
case Rtsp::RTP_UDP: {
|
||||||
std::pair<Socket::Ptr, Socket::Ptr> pr;
|
std::pair<Socket::Ptr, Socket::Ptr> pr = std::make_pair(createSocket(),createSocket());
|
||||||
try{
|
try {
|
||||||
pr = makeSockPair(_sock->getPoller(), get_local_ip());
|
makeSockPair(pr, get_local_ip());
|
||||||
}catch(std::exception &ex) {
|
} catch (std::exception &ex) {
|
||||||
//分配端口失败
|
//分配端口失败
|
||||||
send_NotAcceptable();
|
send_NotAcceptable();
|
||||||
throw SockException(Err_shutdown, ex.what());
|
throw SockException(Err_shutdown, ex.what());
|
||||||
@ -681,8 +681,8 @@ void RtspSession::handleReq_Setup(const Parser &parser) {
|
|||||||
|
|
||||||
//设置客户端内网端口信息
|
//设置客户端内网端口信息
|
||||||
string strClientPort = FindField(parser["Transport"].data(), "client_port=", NULL);
|
string strClientPort = FindField(parser["Transport"].data(), "client_port=", NULL);
|
||||||
uint16_t ui16RtpPort = atoi( FindField(strClientPort.data(), NULL, "-").data());
|
uint16_t ui16RtpPort = atoi(FindField(strClientPort.data(), NULL, "-").data());
|
||||||
uint16_t ui16RtcpPort = atoi( FindField(strClientPort.data(), "-" , NULL).data());
|
uint16_t ui16RtcpPort = atoi(FindField(strClientPort.data(), "-", NULL).data());
|
||||||
|
|
||||||
struct sockaddr_in peerAddr;
|
struct sockaddr_in peerAddr;
|
||||||
//设置rtp发送目标地址
|
//设置rtp发送目标地址
|
||||||
@ -690,14 +690,14 @@ void RtspSession::handleReq_Setup(const Parser &parser) {
|
|||||||
peerAddr.sin_port = htons(ui16RtpPort);
|
peerAddr.sin_port = htons(ui16RtpPort);
|
||||||
peerAddr.sin_addr.s_addr = inet_addr(get_peer_ip().data());
|
peerAddr.sin_addr.s_addr = inet_addr(get_peer_ip().data());
|
||||||
bzero(&(peerAddr.sin_zero), sizeof peerAddr.sin_zero);
|
bzero(&(peerAddr.sin_zero), sizeof peerAddr.sin_zero);
|
||||||
pr.first->setSendPeerAddr((struct sockaddr *)(&peerAddr));
|
pr.first->setSendPeerAddr((struct sockaddr *) (&peerAddr));
|
||||||
|
|
||||||
//设置rtcp发送目标地址
|
//设置rtcp发送目标地址
|
||||||
peerAddr.sin_family = AF_INET;
|
peerAddr.sin_family = AF_INET;
|
||||||
peerAddr.sin_port = htons(ui16RtcpPort);
|
peerAddr.sin_port = htons(ui16RtcpPort);
|
||||||
peerAddr.sin_addr.s_addr = inet_addr(get_peer_ip().data());
|
peerAddr.sin_addr.s_addr = inet_addr(get_peer_ip().data());
|
||||||
bzero(&(peerAddr.sin_zero), sizeof peerAddr.sin_zero);
|
bzero(&(peerAddr.sin_zero), sizeof peerAddr.sin_zero);
|
||||||
pr.second->setSendPeerAddr((struct sockaddr *)(&peerAddr));
|
pr.second->setSendPeerAddr((struct sockaddr *) (&peerAddr));
|
||||||
|
|
||||||
//尝试获取客户端nat映射地址
|
//尝试获取客户端nat映射地址
|
||||||
startListenPeerUdpData(trackIdx);
|
startListenPeerUdpData(trackIdx);
|
||||||
@ -714,7 +714,7 @@ void RtspSession::handleReq_Setup(const Parser &parser) {
|
|||||||
break;
|
break;
|
||||||
case Rtsp::RTP_MULTICAST: {
|
case Rtsp::RTP_MULTICAST: {
|
||||||
if(!_multicaster){
|
if(!_multicaster){
|
||||||
_multicaster = RtpMultiCaster::get(getPoller(), get_local_ip(), _media_info._vhost, _media_info._app, _media_info._streamid);
|
_multicaster = RtpMultiCaster::get(*this, get_local_ip(), _media_info._vhost, _media_info._app, _media_info._streamid);
|
||||||
if (!_multicaster) {
|
if (!_multicaster) {
|
||||||
send_NotAcceptable();
|
send_NotAcceptable();
|
||||||
throw SockException(Err_shutdown, "can not get a available udp multicast socket");
|
throw SockException(Err_shutdown, "can not get a available udp multicast socket");
|
||||||
@ -728,10 +728,10 @@ void RtspSession::handleReq_Setup(const Parser &parser) {
|
|||||||
strongSelf->safeShutdown(SockException(Err_shutdown,"ring buffer detached"));
|
strongSelf->safeShutdown(SockException(Err_shutdown,"ring buffer detached"));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
int iSrvPort = _multicaster->getPort(trackRef->_type);
|
int iSrvPort = _multicaster->getMultiCasterPort(trackRef->_type);
|
||||||
//我们用trackIdx区分rtp和rtcp包
|
//我们用trackIdx区分rtp和rtcp包
|
||||||
//由于组播udp端口是共享的,而rtcp端口为组播udp端口+1,所以rtcp端口需要改成共享端口
|
//由于组播udp端口是共享的,而rtcp端口为组播udp端口+1,所以rtcp端口需要改成共享端口
|
||||||
auto pSockRtcp = UDPServer::Instance().getSock(getPoller(),get_local_ip().data(),2*trackIdx + 1,iSrvPort + 1);
|
auto pSockRtcp = UDPServer::Instance().getSock(*this, get_local_ip().data(), 2 * trackIdx + 1, iSrvPort + 1);
|
||||||
if (!pSockRtcp) {
|
if (!pSockRtcp) {
|
||||||
//分配端口失败
|
//分配端口失败
|
||||||
send_NotAcceptable();
|
send_NotAcceptable();
|
||||||
@ -742,7 +742,7 @@ void RtspSession::handleReq_Setup(const Parser &parser) {
|
|||||||
|
|
||||||
sendRtspResponse("200 OK",
|
sendRtspResponse("200 OK",
|
||||||
{"Transport", StrPrinter << "RTP/AVP;multicast;"
|
{"Transport", StrPrinter << "RTP/AVP;multicast;"
|
||||||
<< "destination=" << _multicaster->getIP() << ";"
|
<< "destination=" << _multicaster->getMultiCasterIP() << ";"
|
||||||
<< "source=" << get_local_ip() << ";"
|
<< "source=" << get_local_ip() << ";"
|
||||||
<< "port=" << iSrvPort << "-" << pSockRtcp->get_local_port() << ";"
|
<< "port=" << iSrvPort << "-" << pSockRtcp->get_local_port() << ";"
|
||||||
<< "ttl=" << udpTTL << ";"
|
<< "ttl=" << udpTTL << ";"
|
||||||
@ -1230,7 +1230,7 @@ void RtspSession::setSocketFlags(){
|
|||||||
GET_CONFIG(int, mergeWriteMS, General::kMergeWriteMS);
|
GET_CONFIG(int, mergeWriteMS, General::kMergeWriteMS);
|
||||||
if(mergeWriteMS > 0) {
|
if(mergeWriteMS > 0) {
|
||||||
//推流模式下,关闭TCP_NODELAY会增加推流端的延时,但是服务器性能将提高
|
//推流模式下,关闭TCP_NODELAY会增加推流端的延时,但是服务器性能将提高
|
||||||
SockUtil::setNoDelay(_sock->rawFD(), false);
|
SockUtil::setNoDelay(getSock()->rawFD(), false);
|
||||||
//播放模式下,开启MSG_MORE会增加延时,但是能提高发送性能
|
//播放模式下,开启MSG_MORE会增加延时,但是能提高发送性能
|
||||||
setSendFlags(SOCKET_DEFAULE_FLAGS | FLAG_MORE);
|
setSendFlags(SOCKET_DEFAULE_FLAGS | FLAG_MORE);
|
||||||
}
|
}
|
||||||
|
@ -25,72 +25,71 @@ UDPServer::~UDPServer() {
|
|||||||
InfoL;
|
InfoL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Socket::Ptr UDPServer::getSock(const EventPoller::Ptr &poller,const char* strLocalIp, int intervaled,uint16_t iLocalPort) {
|
Socket::Ptr UDPServer::getSock(SocketHelper &helper, const char* local_ip, int interleaved, uint16_t local_port) {
|
||||||
lock_guard<mutex> lck(_mtxUpdSock);
|
lock_guard<mutex> lck(_mtx_udp_sock);
|
||||||
string strKey = StrPrinter << strLocalIp << ":" << intervaled << endl;
|
string key = StrPrinter << local_ip << ":" << interleaved << endl;
|
||||||
auto it = _mapUpdSock.find(strKey);
|
auto it = _udp_sock_map.find(key);
|
||||||
if (it == _mapUpdSock.end()) {
|
if (it == _udp_sock_map.end()) {
|
||||||
Socket::Ptr pSock(new Socket(poller));
|
Socket::Ptr sock = helper.createSocket();
|
||||||
//InfoL<<localIp;
|
if (!sock->bindUdpSock(local_port, local_ip)) {
|
||||||
if (!pSock->bindUdpSock(iLocalPort, strLocalIp)) {
|
|
||||||
//分配失败
|
//分配失败
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
pSock->setOnRead(bind(&UDPServer::onRcvData, this, intervaled, placeholders::_1,placeholders::_2));
|
sock->setOnErr(bind(&UDPServer::onErr, this, key, placeholders::_1));
|
||||||
pSock->setOnErr(bind(&UDPServer::onErr, this, strKey, placeholders::_1));
|
sock->setOnRead(bind(&UDPServer::onRecv, this, interleaved, placeholders::_1, placeholders::_2));
|
||||||
_mapUpdSock[strKey] = pSock;
|
_udp_sock_map[key] = sock;
|
||||||
DebugL << strLocalIp << " " << pSock->get_local_port() << " " << intervaled;
|
DebugL << local_ip << " " << sock->get_local_port() << " " << interleaved;
|
||||||
return pSock;
|
return sock;
|
||||||
}
|
}
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UDPServer::listenPeer(const char* strPeerIp, void* pSelf, const onRecvData& cb) {
|
void UDPServer::listenPeer(const char* peer_ip, void* obj, const onRecvData &cb) {
|
||||||
lock_guard<mutex> lck(_mtxDataHandler);
|
lock_guard<mutex> lck(_mtx_on_recv);
|
||||||
auto &mapRef = _mapDataHandler[strPeerIp];
|
auto &ref = _on_recv_map[peer_ip];
|
||||||
mapRef.emplace(pSelf, cb);
|
ref.emplace(obj, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UDPServer::stopListenPeer(const char* strPeerIp, void* pSelf) {
|
void UDPServer::stopListenPeer(const char* peer_ip, void* obj) {
|
||||||
lock_guard<mutex> lck(_mtxDataHandler);
|
lock_guard<mutex> lck(_mtx_on_recv);
|
||||||
auto it0 = _mapDataHandler.find(strPeerIp);
|
auto it0 = _on_recv_map.find(peer_ip);
|
||||||
if (it0 == _mapDataHandler.end()) {
|
if (it0 == _on_recv_map.end()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto &mapRef = it0->second;
|
auto &ref = it0->second;
|
||||||
auto it1 = mapRef.find(pSelf);
|
auto it1 = ref.find(obj);
|
||||||
if (it1 != mapRef.end()) {
|
if (it1 != ref.end()) {
|
||||||
mapRef.erase(it1);
|
ref.erase(it1);
|
||||||
}
|
}
|
||||||
if (mapRef.size() == 0) {
|
if (ref.size() == 0) {
|
||||||
_mapDataHandler.erase(it0);
|
_on_recv_map.erase(it0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
void UDPServer::onErr(const string& strKey, const SockException& err) {
|
|
||||||
|
void UDPServer::onErr(const string &key, const SockException &err) {
|
||||||
WarnL << err.what();
|
WarnL << err.what();
|
||||||
lock_guard<mutex> lck(_mtxUpdSock);
|
lock_guard<mutex> lck(_mtx_udp_sock);
|
||||||
_mapUpdSock.erase(strKey);
|
_udp_sock_map.erase(key);
|
||||||
}
|
}
|
||||||
void UDPServer::onRcvData(int intervaled, const Buffer::Ptr &pBuf, struct sockaddr* pPeerAddr) {
|
|
||||||
//TraceL << trackIndex;
|
void UDPServer::onRecv(int interleaved, const Buffer::Ptr &buf, struct sockaddr* peer_addr) {
|
||||||
struct sockaddr_in *in = (struct sockaddr_in *) pPeerAddr;
|
struct sockaddr_in *in = (struct sockaddr_in *) peer_addr;
|
||||||
string peerIp = SockUtil::inet_ntoa(in->sin_addr);
|
string peer_ip = SockUtil::inet_ntoa(in->sin_addr);
|
||||||
lock_guard<mutex> lck(_mtxDataHandler);
|
lock_guard<mutex> lck(_mtx_on_recv);
|
||||||
auto it0 = _mapDataHandler.find(peerIp);
|
auto it0 = _on_recv_map.find(peer_ip);
|
||||||
if (it0 == _mapDataHandler.end()) {
|
if (it0 == _on_recv_map.end()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto &mapRef = it0->second;
|
auto &ref = it0->second;
|
||||||
for (auto it1 = mapRef.begin(); it1 != mapRef.end(); ++it1) {
|
for (auto it1 = ref.begin(); it1 != ref.end(); ++it1) {
|
||||||
onRecvData &funRef = it1->second;
|
auto &func = it1->second;
|
||||||
if (!funRef(intervaled, pBuf, pPeerAddr)) {
|
if (!func(interleaved, buf, peer_addr)) {
|
||||||
it1 = mapRef.erase(it1);
|
it1 = ref.erase(it1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mapRef.size() == 0) {
|
if (ref.size() == 0) {
|
||||||
_mapDataHandler.erase(it0);
|
_on_recv_map.erase(it0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,18 +30,20 @@ public:
|
|||||||
typedef function< bool(int intervaled, const Buffer::Ptr &buffer, struct sockaddr *peer_addr)> onRecvData;
|
typedef function< bool(int intervaled, const Buffer::Ptr &buffer, struct sockaddr *peer_addr)> onRecvData;
|
||||||
~UDPServer();
|
~UDPServer();
|
||||||
static UDPServer &Instance();
|
static UDPServer &Instance();
|
||||||
Socket::Ptr getSock(const EventPoller::Ptr &poller,const char *strLocalIp, int intervaled,uint16_t iLocalPort = 0);
|
Socket::Ptr getSock(SocketHelper &helper, const char *local_ip, int interleaved, uint16_t local_port = 0);
|
||||||
void listenPeer(const char *strPeerIp, void *pSelf, const onRecvData &cb);
|
void listenPeer(const char *peer_ip, void *obj, const onRecvData &cb);
|
||||||
void stopListenPeer(const char *strPeerIp, void *pSelf);
|
void stopListenPeer(const char *peer_ip, void *obj);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
UDPServer();
|
UDPServer();
|
||||||
void onRcvData(int intervaled, const Buffer::Ptr &pBuf,struct sockaddr *pPeerAddr);
|
void onRecv(int interleaved, const Buffer::Ptr &buf, struct sockaddr *peer_addr);
|
||||||
void onErr(const string &strKey,const SockException &err);
|
void onErr(const string &strKey,const SockException &err);
|
||||||
unordered_map<string, Socket::Ptr> _mapUpdSock;
|
|
||||||
mutex _mtxUpdSock;
|
|
||||||
|
|
||||||
unordered_map<string, unordered_map<void *, onRecvData> > _mapDataHandler;
|
private:
|
||||||
mutex _mtxDataHandler;
|
mutex _mtx_udp_sock;
|
||||||
|
mutex _mtx_on_recv;
|
||||||
|
unordered_map<string, Socket::Ptr> _udp_sock_map;
|
||||||
|
unordered_map<string, unordered_map<void *, onRecvData> > _on_recv_map;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace mediakit */
|
} /* namespace mediakit */
|
||||||
|
Loading…
Reference in New Issue
Block a user