diff --git a/trunk/src/app/srs_app_http_api.cpp b/trunk/src/app/srs_app_http_api.cpp index 41c752dde..10f932f1c 100644 --- a/trunk/src/app/srs_app_http_api.cpp +++ b/trunk/src/app/srs_app_http_api.cpp @@ -530,9 +530,7 @@ int SrsApiVhosts::do_process_request(SrsStSocket* skt, SrsHttpMessage* req) ss << __SRS_JOBJECT_START << __SRS_JFIELD_ERROR(ret) << __SRS_JFIELD_CONT << __SRS_JFIELD_ORG("server", stat->server_id()) << __SRS_JFIELD_CONT - << __SRS_JFIELD_ORG("vhosts", __SRS_JARRAY_START) - << data.str() - << __SRS_JARRAY_END + << __SRS_JFIELD_ORG("vhosts", data.str()) << __SRS_JOBJECT_END; return res_json(skt, req, ss.str()); @@ -562,9 +560,7 @@ int SrsApiStreams::do_process_request(SrsStSocket* skt, SrsHttpMessage* req) ss << __SRS_JOBJECT_START << __SRS_JFIELD_ERROR(ret) << __SRS_JFIELD_CONT << __SRS_JFIELD_ORG("server", stat->server_id()) << __SRS_JFIELD_CONT - << __SRS_JFIELD_ORG("streams", __SRS_JARRAY_START) - << data.str() - << __SRS_JARRAY_END + << __SRS_JFIELD_ORG("streams", data.str()) << __SRS_JOBJECT_END; 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 b7bb4d815..9881e4e01 100644 --- a/trunk/src/app/srs_app_rtmp_conn.cpp +++ b/trunk/src/app/srs_app_rtmp_conn.cpp @@ -398,7 +398,8 @@ int SrsRtmpConn::stream_service_cycle() // update the statistic when source disconveried. SrsStatistic* stat = SrsStatistic::instance(); - if ((ret = stat->on_client(_srs_context->get_id(), req)) != ERROR_SUCCESS) { + int client_id = _srs_context->get_id(); + if ((ret = stat->on_client(client_id, req)) != ERROR_SUCCESS) { srs_error("stat client failed. ret=%d", ret); return ret; } @@ -445,9 +446,15 @@ int SrsRtmpConn::stream_service_cycle() return ret; } + if ((ret = stat->on_client_play_start(client_id)) != ERROR_SUCCESS) { + srs_error("stat client play start failed. ret=%d", ret); + return ret; + } + srs_info("start to play stream %s success", req->stream.c_str()); ret = playing(source); http_hooks_on_stop(); + stat->on_client_play_stop(client_id); return ret; } diff --git a/trunk/src/app/srs_app_statistic.cpp b/trunk/src/app/srs_app_statistic.cpp index 45e0019c7..f03b78fbc 100644 --- a/trunk/src/app/srs_app_statistic.cpp +++ b/trunk/src/app/srs_app_statistic.cpp @@ -50,6 +50,7 @@ SrsStatisticStream::SrsStatisticStream() { id = __srs_generate_id(); vhost = NULL; + clients = 0; } SrsStatisticStream::~SrsStatisticStream() @@ -121,10 +122,46 @@ int SrsStatistic::on_client(int id, SrsRequest* req) } else { stream = streams[url]; } + + // create client if not exists + SrsStatisticClient* client = NULL; + if (clients.find(id) == clients.end()) { + client = new SrsStatisticClient(); + client->stream = stream; + clients[id] = client; + } else { + client = clients[id]; + } return ret; } +int SrsStatistic::on_client_play_start(int id) +{ + int ret = ERROR_SUCCESS; + + std::map::iterator it; + it = clients.find(id); + if (it != clients.end()) { + it->second->stream->clients++; + } + + return ret; +} + +int SrsStatistic::on_client_play_stop(int id) +{ + int ret = ERROR_SUCCESS; + + std::map::iterator it; + it = clients.find(id); + if (it != clients.end()) { + it->second->stream->clients--; + } + + return ret; +} + int64_t SrsStatistic::server_id() { return _server_id; @@ -134,15 +171,24 @@ int SrsStatistic::dumps_vhosts(stringstream& ss) { int ret = ERROR_SUCCESS; + ss << __SRS_JARRAY_START; + bool first = true; std::map::iterator it; for (it = vhosts.begin(); it != vhosts.end(); it++) { SrsStatisticVhost* vhost = it->second; + if (first) { + first = false; + } else { + ss << __SRS_JFIELD_CONT; + } + ss << __SRS_JOBJECT_START << __SRS_JFIELD_ORG("id", vhost->id) << __SRS_JFIELD_CONT << __SRS_JFIELD_STR("name", vhost->vhost) << __SRS_JOBJECT_END; } - + ss << __SRS_JARRAY_END; + return ret; } @@ -150,15 +196,25 @@ int SrsStatistic::dumps_streams(stringstream& ss) { int ret = ERROR_SUCCESS; + ss << __SRS_JARRAY_START; + bool first = true; std::map::iterator it; for (it = streams.begin(); it != streams.end(); it++) { SrsStatisticStream* stream = it->second; + if (first) { + first = false; + } else { + ss << __SRS_JFIELD_CONT; + } + ss << __SRS_JOBJECT_START << __SRS_JFIELD_ORG("id", stream->id) << __SRS_JFIELD_CONT << __SRS_JFIELD_STR("name", stream->stream) << __SRS_JFIELD_CONT - << __SRS_JFIELD_ORG("vhost", stream->vhost->id) + << __SRS_JFIELD_ORG("vhost", stream->vhost->id) << __SRS_JFIELD_CONT + << __SRS_JFIELD_ORG("clients", stream->clients) << __SRS_JOBJECT_END; } + ss << __SRS_JARRAY_END; return ret; } diff --git a/trunk/src/app/srs_app_statistic.hpp b/trunk/src/app/srs_app_statistic.hpp index f261962ea..452254bde 100644 --- a/trunk/src/app/srs_app_statistic.hpp +++ b/trunk/src/app/srs_app_statistic.hpp @@ -53,6 +53,7 @@ public: std::string app; std::string stream; std::string url; + int64_t clients; public: SrsStatisticStream(); virtual ~SrsStatisticStream(); @@ -89,6 +90,14 @@ public: * @param req, the client request object. */ virtual int on_client(int id, SrsRequest* req); + /** + * client start play + */ + virtual int on_client_play_start(int id); + /** + * client stop play + */ + virtual int on_client_play_stop(int id); public: /** * get the server id, used to identify the server.