From 191b07668d91d4a380dadeb6eaa5ad54b0200478 Mon Sep 17 00:00:00 2001 From: winlin Date: Tue, 17 Dec 2019 16:54:06 +0800 Subject: [PATCH] Refactor HTTP stream to disconnect client when unpublish --- trunk/src/app/srs_app_conn.cpp | 6 ++++-- trunk/src/app/srs_app_http_stream.cpp | 4 +++- trunk/src/app/srs_app_rtmp_conn.cpp | 4 ++-- trunk/src/app/srs_app_rtsp.cpp | 3 +-- trunk/src/kernel/srs_kernel_error.cpp | 16 ++++++---------- trunk/src/kernel/srs_kernel_error.hpp | 6 ++++-- trunk/src/utest/srs_utest_kernel.cpp | 12 ++++++------ 7 files changed, 26 insertions(+), 25 deletions(-) diff --git a/trunk/src/app/srs_app_conn.cpp b/trunk/src/app/srs_app_conn.cpp index 79188ea95..b54970ab9 100644 --- a/trunk/src/app/srs_app_conn.cpp +++ b/trunk/src/app/srs_app_conn.cpp @@ -181,10 +181,12 @@ srs_error_t SrsConnection::cycle() // client close peer. // TODO: FIXME: Only reset the error when client closed it. - if (srs_is_client_gracefully_close(srs_error_code(err))) { + if (srs_is_client_gracefully_close(err)) { srs_warn("client disconnect peer. ret=%d", srs_error_code(err)); + } else if (srs_is_server_gracefully_close(err)) { + srs_warn("server disconnect. ret=%d", srs_error_code(err)); } else { - srs_error("connect error %s", srs_error_desc(err).c_str()); + srs_error("serve error %s", srs_error_desc(err).c_str()); } srs_freep(err); diff --git a/trunk/src/app/srs_app_http_stream.cpp b/trunk/src/app/srs_app_http_stream.cpp index 64356c4df..1f4064528 100755 --- a/trunk/src/app/srs_app_http_stream.cpp +++ b/trunk/src/app/srs_app_http_stream.cpp @@ -661,7 +661,9 @@ srs_error_t SrsLiveStream::do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMess } } - return err; + // Here, the entry is disabled by encoder un-publishing or reloading, + // so we must return a io.EOF error to disconnect the client, or the client will never quit. + return srs_error_new(ERROR_HTTP_STREAM_EOF, "Stream EOF"); } srs_error_t SrsLiveStream::http_hooks_on_play(ISrsHttpMessage* r) diff --git a/trunk/src/app/srs_app_rtmp_conn.cpp b/trunk/src/app/srs_app_rtmp_conn.cpp index 867c4aea1..dc480dbeb 100644 --- a/trunk/src/app/srs_app_rtmp_conn.cpp +++ b/trunk/src/app/srs_app_rtmp_conn.cpp @@ -390,8 +390,8 @@ srs_error_t SrsRtmpConn::service_cycle() // stream service must terminated with error, never success. // when terminated with success, it's user required to stop. - if (srs_error_code(err) == ERROR_SUCCESS) { - srs_freep(err); + // TODO: FIXME: Support RTMP client timeout, https://github.com/ossrs/srs/issues/1134 + if (err == srs_success) { continue; } diff --git a/trunk/src/app/srs_app_rtsp.cpp b/trunk/src/app/srs_app_rtsp.cpp index b96b2190e..4f5fb7b6a 100644 --- a/trunk/src/app/srs_app_rtsp.cpp +++ b/trunk/src/app/srs_app_rtsp.cpp @@ -387,10 +387,9 @@ srs_error_t SrsRtspConn::cycle() if (err == srs_success) { srs_trace("client finished."); - } else if (srs_is_client_gracefully_close(srs_error_code(err))) { + } else if (srs_is_client_gracefully_close(err)) { srs_warn("client disconnect peer. code=%d", srs_error_code(err)); srs_freep(err); - err = srs_success; } if (video_rtp) { diff --git a/trunk/src/kernel/srs_kernel_error.cpp b/trunk/src/kernel/srs_kernel_error.cpp index de13304db..de52f710b 100644 --- a/trunk/src/kernel/srs_kernel_error.cpp +++ b/trunk/src/kernel/srs_kernel_error.cpp @@ -30,30 +30,26 @@ #include using namespace std; -bool srs_is_system_control_error(int error_code) +bool srs_is_system_control_error(srs_error_t err) { + int error_code = srs_error_code(err); return error_code == ERROR_CONTROL_RTMP_CLOSE || error_code == ERROR_CONTROL_REPUBLISH || error_code == ERROR_CONTROL_REDIRECT; } -bool srs_is_system_control_error(srs_error_t err) +bool srs_is_client_gracefully_close(srs_error_t err) { int error_code = srs_error_code(err); - return srs_is_system_control_error(error_code); -} - -bool srs_is_client_gracefully_close(int error_code) -{ return error_code == ERROR_SOCKET_READ || error_code == ERROR_SOCKET_READ_FULLY || error_code == ERROR_SOCKET_WRITE; } -bool srs_is_client_gracefully_close(srs_error_t err) +bool srs_is_server_gracefully_close(srs_error_t err) { - int error_code = srs_error_code(err); - return srs_is_client_gracefully_close(error_code); + int code = srs_error_code(err); + return code == ERROR_HTTP_STREAM_EOF; } SrsCplxError::SrsCplxError() diff --git a/trunk/src/kernel/srs_kernel_error.hpp b/trunk/src/kernel/srs_kernel_error.hpp index ae543662f..a5c19da61 100644 --- a/trunk/src/kernel/srs_kernel_error.hpp +++ b/trunk/src/kernel/srs_kernel_error.hpp @@ -320,6 +320,7 @@ #define ERROR_HTTP_REQUEST_EOF 4029 #define ERROR_HTTP_302_INVALID 4038 #define ERROR_BASE64_DECODE 4039 +#define ERROR_HTTP_STREAM_EOF 4040 /////////////////////////////////////////////////////// // HTTP API error. @@ -336,10 +337,11 @@ // Whether the error code is an system control error. // TODO: FIXME: Remove it from underlayer for confused with error and logger. -extern bool srs_is_system_control_error(int error_code); extern bool srs_is_system_control_error(srs_error_t err); -extern bool srs_is_client_gracefully_close(int error_code); +// It's closed by client. extern bool srs_is_client_gracefully_close(srs_error_t err); +// It's closed by server, such as streaming EOF. +extern bool srs_is_server_gracefully_close(srs_error_t err); // The complex error carries code, message, callstack and instant variables, // which is more strong and easy to locate problem by log, diff --git a/trunk/src/utest/srs_utest_kernel.cpp b/trunk/src/utest/srs_utest_kernel.cpp index 2843c304e..fcd39dd6f 100644 --- a/trunk/src/utest/srs_utest_kernel.cpp +++ b/trunk/src/utest/srs_utest_kernel.cpp @@ -2641,9 +2641,9 @@ VOID TEST(KernelUtility, RTMPUtils2) VOID TEST(KernelErrorTest, CoverAll) { if (true) { - EXPECT_TRUE(srs_is_system_control_error(ERROR_CONTROL_RTMP_CLOSE)); - EXPECT_TRUE(srs_is_system_control_error(ERROR_CONTROL_REPUBLISH)); - EXPECT_TRUE(srs_is_system_control_error(ERROR_CONTROL_REDIRECT)); + EXPECT_TRUE(srs_is_system_control_error(srs_error_new(ERROR_CONTROL_RTMP_CLOSE, "err"))); + EXPECT_TRUE(srs_is_system_control_error(srs_error_new(ERROR_CONTROL_REPUBLISH, "err"))); + EXPECT_TRUE(srs_is_system_control_error(srs_error_new(ERROR_CONTROL_REDIRECT, "err"))); } if (true) { @@ -2653,9 +2653,9 @@ VOID TEST(KernelErrorTest, CoverAll) } if (true) { - EXPECT_TRUE(srs_is_client_gracefully_close(ERROR_SOCKET_READ)); - EXPECT_TRUE(srs_is_client_gracefully_close(ERROR_SOCKET_READ_FULLY)); - EXPECT_TRUE(srs_is_client_gracefully_close(ERROR_SOCKET_WRITE)); + EXPECT_TRUE(srs_is_client_gracefully_close(srs_error_new(ERROR_SOCKET_READ, "err"))); + EXPECT_TRUE(srs_is_client_gracefully_close(srs_error_new(ERROR_SOCKET_READ_FULLY, "err"))); + EXPECT_TRUE(srs_is_client_gracefully_close(srs_error_new(ERROR_SOCKET_WRITE, "err"))); } if (true) {