diff --git a/trunk/src/app/srs_app_rtc_server.cpp b/trunk/src/app/srs_app_rtc_server.cpp index 6858802ad..b7f42133f 100644 --- a/trunk/src/app/srs_app_rtc_server.cpp +++ b/trunk/src/app/srs_app_rtc_server.cpp @@ -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::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,24 +731,28 @@ void SrsRtcServer::check_and_clean_timeout_session() map::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(); + // 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(); - 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; + srs_trace("rtc session=%s, STUN timeout", session->id().c_str()); + map_username_session.erase(iter++); + map_id_session.erase(session->peer_id()); + + 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 zombies; + zombies.swap(zombies_); + + std::vector::iterator it; + for (it = zombies.begin(); it != zombies.end(); ++it) { + SrsRtcSession* session = *it; + srs_freep(session); + } + + return err; } RtcServerAdapter::RtcServerAdapter() diff --git a/trunk/src/app/srs_app_rtc_server.hpp b/trunk/src/app/srs_app_rtc_server.hpp index db75bdcaa..409755d84 100644 --- a/trunk/src/app/srs_app_rtc_server.hpp +++ b/trunk/src/app/srs_app_rtc_server.hpp @@ -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 listeners; std::vector senders; + ISrsRtcServerHandler* handler; private: std::map map_username_session; // key: username(local_ufrag + ":" + remote_ufrag) std::map map_id_session; // key: peerip(ip + ":" + port) + // The zombie sessions, we will free them. + std::vector 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.