@@ -41,16 +41,26 @@ using namespace std;
4141
4242#define SRS_CONTEXT_IN_HLS " hls_ctx"
4343
44- SrsM3u8CtxInfo::SrsM3u8CtxInfo ()
44+ SrsHlsVirtualConn::SrsHlsVirtualConn ()
4545{
4646 req = NULL ;
47+ interrupt = false ;
4748}
4849
49- SrsM3u8CtxInfo ::~SrsM3u8CtxInfo ()
50+ SrsHlsVirtualConn ::~SrsHlsVirtualConn ()
5051{
5152 srs_freep (req);
5253}
5354
55+ void SrsHlsVirtualConn::expire ()
56+ {
57+ interrupt = true ;
58+
59+ // remove statistic quickly
60+ SrsStatistic* stat = SrsStatistic::instance ();
61+ stat->on_disconnect (ctx, srs_success);
62+ }
63+
5464SrsHlsStream::SrsHlsStream ()
5565{
5666 _srs_hybrid->timer5s ()->subscribe (this );
@@ -60,9 +70,9 @@ SrsHlsStream::~SrsHlsStream()
6070{
6171 _srs_hybrid->timer5s ()->unsubscribe (this );
6272
63- std::map<std::string, SrsM3u8CtxInfo *>::iterator it;
73+ std::map<std::string, SrsHlsVirtualConn *>::iterator it;
6474 for (it = map_ctx_info_.begin (); it != map_ctx_info_.end (); ++it) {
65- SrsM3u8CtxInfo * info = it->second ;
75+ SrsHlsVirtualConn * info = it->second ;
6676 srs_freep (info);
6777 }
6878 map_ctx_info_.clear ();
@@ -94,6 +104,12 @@ srs_error_t SrsHlsStream::serve_m3u8_ctx(ISrsHttpResponseWriter* w, ISrsHttpMess
94104 *served = false ;
95105 return srs_success;
96106 }
107+
108+ if (is_interrupt (ctx)) {
109+ srs_warn (" Reject: HLS stream is EOF, ctx=%s" , ctx.c_str ());
110+ return srs_go_http_error (w, SRS_CONSTS_HTTP_NotFound, srs_fmt (" HLS stream %s is EOF" , ctx.c_str ()));
111+ }
112+
97113 err = serve_exists_session (w, r, factory, fullpath);
98114 } else {
99115 // Create a m3u8 in memory, contains the session id(ctx).
@@ -238,20 +254,31 @@ bool SrsHlsStream::ctx_is_exist(std::string ctx)
238254
239255void SrsHlsStream::alive (std::string ctx, SrsRequest* req)
240256{
241- std::map<std::string, SrsM3u8CtxInfo *>::iterator it = map_ctx_info_.find (ctx);
257+ std::map<std::string, SrsHlsVirtualConn *>::iterator it = map_ctx_info_.find (ctx);
242258
243259 // Create new context.
244260 if (it == map_ctx_info_.end ()) {
245- SrsM3u8CtxInfo *info = new SrsM3u8CtxInfo ();
246- info->req = req->copy ();
247- info->request_time = srs_get_system_time ();
248- map_ctx_info_.insert (make_pair (ctx, info));
261+ SrsHlsVirtualConn* conn = new SrsHlsVirtualConn ();
262+ conn->req = req->copy ();
263+ conn->ctx = ctx;
264+ conn->request_time = srs_get_system_time ();
265+ map_ctx_info_.insert (make_pair (ctx, conn));
266+
267+ // Update the conn of stat client, which is used for receiving the event of kickoff.
268+ SrsStatistic* stat = SrsStatistic::instance ();
269+ SrsStatisticClient* client = stat->find_client (ctx);
270+ if (client) {
271+ client->conn = conn;
272+ }
273+
249274 return ;
250275 }
251276
252- // Update alive time of context.
253- SrsM3u8CtxInfo* info = it->second ;
254- info->request_time = srs_get_system_time ();
277+ // Update alive time of context for virtual connection.
278+ SrsHlsVirtualConn* conn = it->second ;
279+ if (!conn->interrupt ) {
280+ conn->request_time = srs_get_system_time ();
281+ }
255282}
256283
257284srs_error_t SrsHlsStream::http_hooks_on_play (SrsRequest* req)
@@ -321,10 +348,10 @@ srs_error_t SrsHlsStream::on_timer(srs_utime_t interval)
321348{
322349 srs_error_t err = srs_success;
323350
324- std::map<std::string, SrsM3u8CtxInfo *>::iterator it;
351+ std::map<std::string, SrsHlsVirtualConn *>::iterator it;
325352 for (it = map_ctx_info_.begin (); it != map_ctx_info_.end (); ++it) {
326353 string ctx = it->first ;
327- SrsM3u8CtxInfo * info = it->second ;
354+ SrsHlsVirtualConn * info = it->second ;
328355
329356 srs_utime_t hls_window = _srs_config->get_hls_window (info->req ->vhost );
330357 if (info->request_time + (2 * hls_window) < srs_get_system_time ()) {
@@ -347,6 +374,14 @@ srs_error_t SrsHlsStream::on_timer(srs_utime_t interval)
347374 return err;
348375}
349376
377+ bool SrsHlsStream::is_interrupt (std::string id) {
378+ std::map<std::string, SrsHlsVirtualConn*>::iterator it = map_ctx_info_.find (id);
379+ if (it != map_ctx_info_.end ()) {
380+ return it->second ->interrupt ;
381+ }
382+ return false ;
383+ }
384+
350385SrsVodStream::SrsVodStream (string root_dir) : SrsHttpFileServer(root_dir)
351386{
352387}
0 commit comments