diff --git a/Dockerfile b/Dockerfile
index 8aa7827daa..77d5346529 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -41,7 +41,7 @@ ARG TARGETPLATFORM
RUN echo "BUILDPLATFORM: $BUILDPLATFORM, TARGETPLATFORM: $TARGETPLATFORM"
# Expose ports for streaming @see https://github.com/ossrs/srs#ports
-EXPOSE 1935 1985 8080 8000/udp 10080/udp
+EXPOSE 1935 1985 8080 5060 9000 8000/udp 10080/udp
# FFMPEG 4.1
COPY --from=build /usr/local/bin/ffmpeg /usr/local/srs/objs/ffmpeg/bin/ffmpeg
diff --git a/trunk/conf/full.conf b/trunk/conf/full.conf
index 76d305663b..78805a126e 100644
--- a/trunk/conf/full.conf
+++ b/trunk/conf/full.conf
@@ -647,8 +647,8 @@ stream_caster {
# The available variables:
# [stream] The video channel codec ID.
output rtmp://127.0.0.1/live/[stream];
- # The listen TCP/UDP port for stream converter.
- # For gb28181 converter, listen at TCP/UDP port. for example, 9000.
+ # The listen TCP port for stream converter.
+ # For gb28181 converter, listen at TCP port. for example, 9000.
# @remark We always enable bundle for media streams at this port.
listen 9000;
# SIP server for GB28181. Please note that this is only a demonstrated SIP server, please never use it in your
@@ -658,7 +658,7 @@ stream_caster {
# Whether enable embedded SIP server.
# Default: on
enabled on;
- # The SIP listen port, for both TCP and UDP protocol.
+ # The SIP listen port, for TCP protocol.
# Default: 5060
listen 5060;
# The SIP or media transport timeout in seconds.
diff --git a/trunk/doc/CHANGELOG.md b/trunk/doc/CHANGELOG.md
index 442ebf224d..8758eac269 100644
--- a/trunk/doc/CHANGELOG.md
+++ b/trunk/doc/CHANGELOG.md
@@ -7,6 +7,7 @@ The changelog for SRS.
## SRS 5.0 Changelog
+* v5.0, 2023-08-30, Merge [#3779](https://github.com/ossrs/srs/pull/3779): Support HTTP-API for fetching reload result. v5.0.176 (#3779)
* v5.0, 2023-08-28, Merge [#3503](https://github.com/ossrs/srs/pull/3503): SrsContextId assignment can be improved without create a duplicated one. v5.0.175 (#3503)
* v5.0, 2023-08-28, Merge [#3781](https://github.com/ossrs/srs/pull/3781): HLS: Fix on_hls and hls_dispose critical zone issue. v5.0.174 (#3781)
* v5.0, 2023-08-28, Merge [#3768](https://github.com/ossrs/srs/pull/3768): Support include empty config file. v5.0.173 (#3768)
diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp
index ecfbee3777..92386d8e5e 100644
--- a/trunk/src/app/srs_app_config.cpp
+++ b/trunk/src/app/srs_app_config.cpp
@@ -1333,18 +1333,22 @@ void SrsConfig::unsubscribe(ISrsReloadHandler* handler)
}
// LCOV_EXCL_START
-srs_error_t SrsConfig::reload()
+srs_error_t SrsConfig::reload(SrsReloadState *pstate)
{
+ *pstate = SrsReloadStateInit;
+
srs_error_t err = srs_success;
-
+
SrsConfig conf;
-
+
+ *pstate = SrsReloadStateParsing;
if ((err = conf.parse_file(config_file.c_str())) != srs_success) {
return srs_error_wrap(err, "parse file");
}
srs_info("config reloader parse file success.");
// transform config to compatible with previous style of config.
+ *pstate = SrsReloadStateTransforming;
if ((err = srs_config_transform_vhost(conf.root)) != srs_success) {
return srs_error_wrap(err, "transform config");
}
@@ -1352,11 +1356,13 @@ srs_error_t SrsConfig::reload()
if ((err = conf.check_config()) != srs_success) {
return srs_error_wrap(err, "check config");
}
-
+
+ *pstate = SrsReloadStateApplying;
if ((err = reload_conf(&conf)) != srs_success) {
return srs_error_wrap(err, "reload config");
}
-
+
+ *pstate = SrsReloadStateFinished;
return err;
}
// LCOV_EXCL_STOP
diff --git a/trunk/src/app/srs_app_config.hpp b/trunk/src/app/srs_app_config.hpp
index b0ee9a71ab..be1a35ec98 100644
--- a/trunk/src/app/srs_app_config.hpp
+++ b/trunk/src/app/srs_app_config.hpp
@@ -256,6 +256,19 @@ class SrsConfDirective
virtual srs_error_t read_token(srs_internal::SrsConfigBuffer* buffer, std::vector& args, int& line_start, SrsDirectiveState& state);
};
+// The state for reloading config.
+enum SrsReloadState {
+ SrsReloadStateInit = 0,
+ // Start to parse the new config file.
+ SrsReloadStateParsing = 10,
+ // Start to transform the new config file to new version.
+ SrsReloadStateTransforming = 20,
+ // Start to apply the new config file.
+ SrsReloadStateApplying = 30,
+ // The reload is finished.
+ SrsReloadStateFinished = 90,
+};
+
// The config service provider.
// For the config supports reload, so never keep the reference cross st-thread,
// that is, never save the SrsConfDirective* get by any api of config,
@@ -308,7 +321,7 @@ class SrsConfig
virtual void unsubscribe(ISrsReloadHandler* handler);
// Reload the config file.
// @remark, user can test the config before reload it.
- virtual srs_error_t reload();
+ virtual srs_error_t reload(SrsReloadState *pstate);
private:
// Reload the vhost section of config.
virtual srs_error_t reload_vhost(SrsConfDirective* old_root);
diff --git a/trunk/src/app/srs_app_http_api.cpp b/trunk/src/app/srs_app_http_api.cpp
index 3696f2c1bd..8c6d16385d 100644
--- a/trunk/src/app/srs_app_http_api.cpp
+++ b/trunk/src/app/srs_app_http_api.cpp
@@ -863,7 +863,7 @@ srs_error_t SrsGoApiClients::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessa
}
} else {
SrsJsonObject* data = SrsJsonAny::object();
- obj->set("client", data);;
+ obj->set("client", data);
if ((err = client->dumps(data)) != srs_success) {
int code = srs_error_code(err);
@@ -907,6 +907,10 @@ SrsGoApiRaw::~SrsGoApiRaw()
_srs_config->unsubscribe(this);
}
+extern srs_error_t _srs_reload_err;
+extern SrsReloadState _srs_reload_state;
+extern std::string _srs_reload_id;
+
srs_error_t SrsGoApiRaw::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
{
srs_error_t err = srs_success;
@@ -937,8 +941,8 @@ srs_error_t SrsGoApiRaw::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage*
//////////////////////////////////////////////////////////////////////////
// the rpc is required.
- // the allowd rpc method check.
- if (rpc.empty() || rpc != "reload") {
+ // the allowed rpc method check.
+ if (rpc.empty() || (rpc != "reload" && rpc != "reload-fetch")) {
return srs_api_response_code(w, r, ERROR_SYSTEM_CONFIG_RAW);
}
@@ -950,6 +954,16 @@ srs_error_t SrsGoApiRaw::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage*
server->on_signal(SRS_SIGNAL_RELOAD);
return srs_api_response_code(w, r, ERROR_SUCCESS);
+ } else if (rpc == "reload-fetch") {
+ SrsJsonObject* data = SrsJsonAny::object();
+ obj->set("data", data);
+
+ data->set("err", SrsJsonAny::integer(srs_error_code(_srs_reload_err)));
+ data->set("msg", SrsJsonAny::str(srs_error_summary(_srs_reload_err).c_str()));
+ data->set("state", SrsJsonAny::integer(_srs_reload_state));
+ data->set("rid", SrsJsonAny::str(_srs_reload_id.c_str()));
+
+ return srs_api_response(w, r, obj->dumps());
}
return err;
diff --git a/trunk/src/app/srs_app_server.cpp b/trunk/src/app/srs_app_server.cpp
index 587f41649b..4817d34ed9 100644
--- a/trunk/src/app/srs_app_server.cpp
+++ b/trunk/src/app/srs_app_server.cpp
@@ -870,7 +870,9 @@ srs_error_t SrsServer::cycle()
}
// Do server main cycle.
- err = do_cycle();
+ if ((err = do_cycle()) != srs_success) {
+ srs_error("server err %s", srs_error_desc(err).c_str());
+ }
// OK, SRS server is done.
wg_->done();
@@ -942,6 +944,10 @@ void SrsServer::on_signal(int signo)
}
}
+srs_error_t _srs_reload_err;
+SrsReloadState _srs_reload_state;
+std::string _srs_reload_id;
+
srs_error_t SrsServer::do_cycle()
{
srs_error_t err = srs_success;
@@ -991,12 +997,27 @@ srs_error_t SrsServer::do_cycle()
// do reload the config.
if (signal_reload) {
signal_reload = false;
- srs_info("get signal to reload the config.");
-
- if ((err = _srs_config->reload()) != srs_success) {
- return srs_error_wrap(err, "config reload");
+ srs_trace("starting reload config.");
+
+ SrsReloadState state = SrsReloadStateInit;
+ _srs_reload_state = SrsReloadStateInit; srs_freep(_srs_reload_err); _srs_reload_id = srs_random_str(7);
+ err = _srs_config->reload(&state);
+ _srs_reload_state = state; _srs_reload_err = srs_error_copy(err);
+ if (err != srs_success) {
+ // If the parsing and transformation of the configuration fail, we can tolerate it by simply
+ // ignoring the new configuration and continuing to use the current one. However, if the
+ // application of the new configuration fails, some configurations may be applied while
+ // others may not. For instance, the listening port may be closed when the configuration
+ // is set to listen on an unavailable port. In such cases, we should terminate the service.
+ if (state == SrsReloadStateApplying) {
+ return srs_error_wrap(err, "reload fatal error state=%d", state);
+ }
+
+ srs_warn("reload failed, state=%d, err %s", state, srs_error_desc(err).c_str());
+ srs_freep(err);
+ } else {
+ srs_trace("reload config success, state=%d.", state);
}
- srs_trace("reload config success.");
}
srs_usleep(1 * SRS_UTIME_SECONDS);
diff --git a/trunk/src/app/srs_app_threads.cpp b/trunk/src/app/srs_app_threads.cpp
index d1d14bfcec..82aaad2a58 100644
--- a/trunk/src/app/srs_app_threads.cpp
+++ b/trunk/src/app/srs_app_threads.cpp
@@ -295,6 +295,10 @@ srs_error_t SrsCircuitBreaker::on_timer(srs_utime_t interval)
SrsCircuitBreaker* _srs_circuit_breaker = NULL;
SrsAsyncCallWorker* _srs_dvr_async = NULL;
+extern srs_error_t _srs_reload_err;
+extern SrsReloadState _srs_reload_state;
+extern std::string _srs_reload_id;
+
srs_error_t srs_global_initialize()
{
srs_error_t err = srs_success;
@@ -446,6 +450,10 @@ srs_error_t srs_global_initialize()
_srs_apm = new SrsApmClient();
#endif
+ _srs_reload_err = srs_success;
+ _srs_reload_state = SrsReloadStateInit;
+ _srs_reload_id = srs_random_str(7);
+
return err;
}
diff --git a/trunk/src/core/srs_core_version5.hpp b/trunk/src/core/srs_core_version5.hpp
index 87387ba437..7528834d62 100644
--- a/trunk/src/core/srs_core_version5.hpp
+++ b/trunk/src/core/srs_core_version5.hpp
@@ -9,6 +9,6 @@
#define VERSION_MAJOR 5
#define VERSION_MINOR 0
-#define VERSION_REVISION 175
+#define VERSION_REVISION 176
#endif