diff --git a/trunk/src/app/srs_app_http_api.cpp b/trunk/src/app/srs_app_http_api.cpp index a9e775db5..eb751852d 100644 --- a/trunk/src/app/srs_app_http_api.cpp +++ b/trunk/src/app/srs_app_http_api.cpp @@ -26,7 +26,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifdef SRS_AUTO_HTTP_API #include -#include using namespace std; #include @@ -522,30 +521,14 @@ bool SrsApiVhosts::can_handle(const char* path, int length, const char** /*pchil int SrsApiVhosts::do_process_request(SrsStSocket* skt, SrsHttpMessage* req) { + int ret = ERROR_SUCCESS; + std::stringstream ss; - std::set vhost_set; - std::map* pool = SrsStatistic::instance()->get_pool(); - std::map::iterator it; - for (it = pool->begin(); it != pool->end(); it++) { - if (it->second->_req == NULL) - continue; - vhost_set.insert(it->second->_req->vhost); + SrsStatistic* stat = SrsStatistic::instance(); + if ((ret = stat->dumps_vhosts(ss)) != ERROR_SUCCESS) { + return ret; } - - ss << __SRS_JARRAY_START; - bool first = true; - std::set::iterator it_set; - for (it_set = vhost_set.begin(); it_set != vhost_set.end(); it_set++) { - if (first) { - first = false; - } else { - ss << __SRS_JFIELD_CONT; - } - - ss << "\"" << (*it_set) << "\""; - } - ss << __SRS_JARRAY_END; return res_json(skt, req, ss.str()); } @@ -565,40 +548,13 @@ bool SrsApiStreams::can_handle(const char* path, int length, const char** /*pchi int SrsApiStreams::do_process_request(SrsStSocket* skt, SrsHttpMessage* req) { + int ret = ERROR_SUCCESS; + std::stringstream ss; - std::string query_name = req->query_get("name"); - std::string query_vhost = req->query_get("vhost"); - if (query_name.size() > 0 || query_vhost.size() > 0) { - ss << __SRS_JARRAY_START; - bool first = true; - std::map* pool = SrsStatistic::instance()->get_pool(); - std::map::iterator it; - for (it = pool->begin(); it != pool->end(); it++) { - SrsRequest* reqinfo = it->second->_req; - if (reqinfo == NULL) - continue; - - if (reqinfo->stream == query_name || reqinfo->vhost == query_vhost) { - if (first) { - first = false; - } else { - ss << __SRS_JFIELD_CONT; - } - - ss << __SRS_JOBJECT_START - << __SRS_JFIELD_STR("name", reqinfo->stream) << __SRS_JFIELD_CONT - << __SRS_JFIELD_STR("url", reqinfo->tcUrl) << __SRS_JFIELD_CONT - << __SRS_JFIELD_ORG("clients", 0) << __SRS_JFIELD_CONT - << __SRS_JFIELD_STR("status", "idle") << __SRS_JFIELD_CONT - << __SRS_JFIELD_STR("type", "") << __SRS_JFIELD_CONT - << __SRS_JFIELD_STR("codec", "") - << __SRS_JOBJECT_END; - } - } - ss << __SRS_JARRAY_END; - } else { - return res_error(skt, req, 400, "Bad Request", "unknown query"); + SrsStatistic* stat = SrsStatistic::instance(); + if ((ret = stat->dumps_streams(ss)) != ERROR_SUCCESS) { + return ret; } return res_json(skt, req, ss.str()); diff --git a/trunk/src/app/srs_app_rtmp_conn.cpp b/trunk/src/app/srs_app_rtmp_conn.cpp index 9cac70327..b7bb4d815 100644 --- a/trunk/src/app/srs_app_rtmp_conn.cpp +++ b/trunk/src/app/srs_app_rtmp_conn.cpp @@ -396,7 +396,12 @@ int SrsRtmpConn::stream_service_cycle() } srs_assert(source != NULL); - SrsStatistic::instance()->add_request_info(source, req); + // update the statistic when source disconveried. + SrsStatistic* stat = SrsStatistic::instance(); + if ((ret = stat->on_client(_srs_context->get_id(), req)) != ERROR_SUCCESS) { + srs_error("stat client failed. ret=%d", ret); + return ret; + } // check ASAP, to fail it faster if invalid. if (type != SrsRtmpConnPlay && !vhost_is_edge) { diff --git a/trunk/src/app/srs_app_statistic.cpp b/trunk/src/app/srs_app_statistic.cpp index 331672adb..7b5c60944 100644 --- a/trunk/src/app/srs_app_statistic.cpp +++ b/trunk/src/app/srs_app_statistic.cpp @@ -25,17 +25,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include -SrsStreamInfo::SrsStreamInfo() -{ - _req = NULL; -} - -SrsStreamInfo::~SrsStreamInfo() -{ - srs_freep(_req); -} - -SrsStatistic* SrsStatistic::_instance = NULL; +SrsStatistic* SrsStatistic::_instance = new SrsStatistic(); SrsStatistic::SrsStatistic() { @@ -43,43 +33,48 @@ SrsStatistic::SrsStatistic() SrsStatistic::~SrsStatistic() { - std::map::iterator it; - for (it = pool.begin(); it != pool.end(); it++) { - SrsStreamInfo* si = it->second; - srs_freep(si); + if (true) { + std::map::iterator it; + for (it = vhosts.begin(); it != vhosts.end(); it++) { + SrsStatisticVhost* vhost = it->second; + srs_freep(vhost); + } + } + if (true) { + std::map::iterator it; + for (it = streams.begin(); it != streams.end(); it++) { + SrsStatisticStream* stream = it->second; + srs_freep(stream); + } + } + if (true) { + std::map::iterator it; + for (it = clients.begin(); it != clients.end(); it++) { + SrsStatisticClient* client = it->second; + srs_freep(client); + } } } SrsStatistic* SrsStatistic::instance() { - if (_instance == NULL) { - _instance = new SrsStatistic(); - } return _instance; } -std::map* SrsStatistic::get_pool() +int SrsStatistic::on_client(int id, SrsRequest *req) { - return &pool; + int ret = ERROR_SUCCESS; + return ret; } -SrsStreamInfo* SrsStatistic::get(void *p) +int SrsStatistic::dumps_vhosts(std::stringstream& ss) { - std::map::iterator it = pool.find(p); - if (it == pool.end()) { - SrsStreamInfo* si = new SrsStreamInfo(); - pool[p] = si; - return si; - } else { - SrsStreamInfo* si = it->second; - return si; - } + int ret = ERROR_SUCCESS; + return ret; } -void SrsStatistic::add_request_info(void *p, SrsRequest *req) +int SrsStatistic::dumps_streams(std::stringstream& ss) { - SrsStreamInfo* info = get(p); - if (info->_req == NULL) { - info->_req = req->copy(); - } -} \ No newline at end of file + int ret = ERROR_SUCCESS; + return ret; +} diff --git a/trunk/src/app/srs_app_statistic.hpp b/trunk/src/app/srs_app_statistic.hpp index 41cbbeace..e7ec72ed6 100644 --- a/trunk/src/app/srs_app_statistic.hpp +++ b/trunk/src/app/srs_app_statistic.hpp @@ -31,33 +31,62 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include +#include class SrsRequest; -class SrsStreamInfo +struct SrsStatisticVhost { public: - SrsStreamInfo(); - virtual ~SrsStreamInfo(); + std::string vhost; +}; + +struct SrsStatisticStream +{ public: - SrsRequest *_req; + SrsStatisticVhost* vhost; + std::string app; + std::string stream; +}; + +struct SrsStatisticClient +{ +public: + SrsStatisticStream* stream; + int id; }; class SrsStatistic { -public: - static SrsStatistic* instance(); -public: - virtual std::map* get_pool(); - virtual void add_request_info(void *p, SrsRequest *req); +private: + static SrsStatistic *_instance; + // key: vhost name, value: vhost object. + std::map vhosts; + // key: stream name, value: stream object. + std::map streams; + // key: client id, value: stream object. + std::map clients; private: SrsStatistic(); virtual ~SrsStatistic(); -private: - static SrsStatistic *_instance; - std::map pool; -private: - virtual SrsStreamInfo *get(void *p); +public: + static SrsStatistic* instance(); +public: + /** + * when got a client to publish/play stream, + * @param id, the client srs id. + * @param req, the client request object. + */ + virtual int on_client(int id, SrsRequest *req); +public: + /** + * dumps the vhosts to sstream in json. + */ + virtual int dumps_vhosts(std::stringstream& ss); + /** + * dumps the streams to sstream in json. + */ + virtual int dumps_streams(std::stringstream& ss); }; #endif