RTC: Notify handler when session timeout

pull/1809/head
winlin 5 years ago
parent 6a191e4077
commit 690c64e046

@ -405,8 +405,17 @@ srs_error_t SrsUdpMuxSender::on_reload_rtc_server()
return srs_success;
}
ISrsRtcServerHandler::ISrsRtcServerHandler()
{
}
ISrsRtcServerHandler::~ISrsRtcServerHandler()
{
}
SrsRtcServer::SrsRtcServer()
{
handler = NULL;
timer = new SrsHourGlass(this, 1 * SRS_UTIME_SECONDS);
}
@ -429,6 +438,14 @@ SrsRtcServer::~SrsRtcServer()
srs_freep(sender);
}
}
if (true) {
std::vector<SrsRtcSession*>::iterator it;
for (it = zombies_.begin(); it != zombies_.end(); ++it) {
SrsRtcSession* session = *it;
srs_freep(session);
}
}
}
srs_error_t SrsRtcServer::initialize()
@ -448,6 +465,11 @@ srs_error_t SrsRtcServer::initialize()
return err;
}
void SrsRtcServer::set_handler(ISrsRtcServerHandler* h)
{
handler = h;
}
srs_error_t SrsRtcServer::listen_udp()
{
srs_error_t err = srs_success;
@ -693,6 +715,10 @@ void SrsRtcServer::destroy(SrsRtcSession* session)
if ((it = map_id_session.find(session->peer_id())) != map_id_session.end()) {
map_id_session.erase(it);
}
if (::find(zombies_.begin(), zombies_.end(), session) == zombies_.end()) {
zombies_.push_back(session);
}
}
bool SrsRtcServer::insert_into_id_sessions(const string& peer_id, SrsRtcSession* session)
@ -705,12 +731,13 @@ void SrsRtcServer::check_and_clean_timeout_session()
map<string, SrsRtcSession*>::iterator iter = map_username_session.begin();
while (iter != map_username_session.end()) {
SrsRtcSession* session = iter->second;
if (session == NULL) {
map_username_session.erase(iter++);
srs_assert(session);
if (!session->is_stun_timeout()) {
++iter;
continue;
}
if (session->is_stun_timeout()) {
// Now, we got the RTC session to cleanup, switch to its context
// to make all logs write to the "correct" pid+cid.
session->switch_to_context();
@ -718,11 +745,14 @@ void SrsRtcServer::check_and_clean_timeout_session()
srs_trace("rtc session=%s, STUN timeout", session->id().c_str());
map_username_session.erase(iter++);
map_id_session.erase(session->peer_id());
delete session;
continue;
if (handler) {
handler->on_timeout(session);
}
++iter;
if (::find(zombies_.begin(), zombies_.end(), session) == zombies_.end()) {
zombies_.push_back(session);
}
}
}
@ -753,8 +783,26 @@ SrsRtcSession* SrsRtcServer::find_session_by_username(const std::string& usernam
srs_error_t SrsRtcServer::notify(int type, srs_utime_t interval, srs_utime_t tick)
{
srs_error_t err = srs_success;
// Check session timeout, put to zombies queue.
check_and_clean_timeout_session();
return srs_success;
// Cleanup zombie sessions.
if (zombies_.empty()) {
return err;
}
std::vector<SrsRtcSession*> zombies;
zombies.swap(zombies_);
std::vector<SrsRtcSession*>::iterator it;
for (it = zombies.begin(); it != zombies.end(); ++it) {
SrsRtcSession* session = *it;
srs_freep(session);
}
return err;
}
RtcServerAdapter::RtcServerAdapter()

@ -84,20 +84,35 @@ public:
virtual srs_error_t on_reload_rtc_server();
};
class ISrsRtcServerHandler
{
public:
ISrsRtcServerHandler();
virtual ~ISrsRtcServerHandler();
public:
// When server detect the timeout for session object.
virtual void on_timeout(SrsRtcSession* session) = 0;
};
class SrsRtcServer : virtual public ISrsUdpMuxHandler, virtual public ISrsHourGlass
{
private:
SrsHourGlass* timer;
std::vector<SrsUdpMuxListener*> listeners;
std::vector<SrsUdpMuxSender*> senders;
ISrsRtcServerHandler* handler;
private:
std::map<std::string, SrsRtcSession*> map_username_session; // key: username(local_ufrag + ":" + remote_ufrag)
std::map<std::string, SrsRtcSession*> map_id_session; // key: peerip(ip + ":" + port)
// The zombie sessions, we will free them.
std::vector<SrsRtcSession*> zombies_;
public:
SrsRtcServer();
virtual ~SrsRtcServer();
public:
virtual srs_error_t initialize();
// Set the handler for server events.
void set_handler(ISrsRtcServerHandler* h);
public:
// TODO: FIXME: Support gracefully quit.
// TODO: FIXME: Support reload.

Loading…
Cancel
Save