From 3223b3404323268b56030a6a6843b01bd18f6570 Mon Sep 17 00:00:00 2001 From: winlin Date: Thu, 2 Nov 2023 22:30:10 +0800 Subject: [PATCH] RTC: Resolve candidate for lo and docker. v5.11.10 --- DEVELOPER.md | 22 ++++++++++++++++--- focal/Dockerfile | 2 +- platform/candidate.go | 15 +++++++++++-- .../containers/conf/srs.release-local.conf | 3 +++ platform/containers/conf/srs.release-mac.conf | 3 +++ platform/containers/conf/srs.release.conf | 3 +++ platform/main.go | 5 +++-- platform/utils.go | 22 +++++++++++++++---- ui/src/setupProxy.js | 16 +++++++------- 9 files changed, 71 insertions(+), 20 deletions(-) diff --git a/DEVELOPER.md b/DEVELOPER.md index 2d6dc183..1083b95a 100644 --- a/DEVELOPER.md +++ b/DEVELOPER.md @@ -16,8 +16,6 @@ docker run --name srs --rm -it \ -v $(pwd)/platform/containers/conf/srs.release-mac.conf:/usr/local/srs/conf/docker.conf \ -v $(pwd)/platform/containers/objs/nginx:/usr/local/srs/objs/nginx \ -p 1935:1935 -p 1985:1985 -p 8080:8080 -p 8000:8000/udp -p 10080:10080/udp \ - -e SRS_RTC_SERVER_USE_AUTO_DETECT_NETWORK_IP=off -e SRS_RTC_SERVER_API_AS_CANDIDATES=off \ - --env CANDIDATE=$(ifconfig en0 |grep 'inet ' |awk '{print $2}') \ -d ossrs/srs:5 ``` @@ -27,6 +25,8 @@ docker run --name srs --rm -it \ > Note: Also, you can run SRS by `(cd platform && ~/git/srs/trunk/objs/srs -c containers/conf/srs.release-local.conf)` +> Note: You can set the candidate for WebRTC by `--env CANDIDATE=$(ifconfig en0 |grep 'inet ' |awk '{print $2}')` + Run the platform backend, or run in GoLand: ```bash @@ -739,6 +739,22 @@ docker run --rm -it -p 2022:2022 -p 2443:2443 -p 1935:1935 \ Note that the logs should be written to file, there is no log `write log to console`, instead there should be a log like `you can check log by`. +## WebRTC Candidate + +SRS Stack follows the rules for WebRTC candidate, see [CANDIDATE](https://ossrs.io/lts/en-us/docs/v5/doc/webrtc#config-candidate), +but also has extra improvements for we can do more after proxy the API. + +1. Disable `use_auto_detect_network_ip` and `api_as_candidates` in SRS config. +1. Always use `?eip=xxx` and ignore any other config, if user force to use the specified IP. +1. If `NAME_LOOKUP` (default is `on`) isn't `off`, try to resolve the candidate from `Host` of HTTP API by SRS Stack. + 1. If access SRS Stack by `localhost` for debugging or run in localhost. + 1. If `PLATFORM_DOCKER` is `off`, such as directly run in host, not in docker, use the private ip of SRS Stack. + 1. If run in macOS docker, try to resolve `host.docker.internal` as the private ip of SRS Stack. + 1. Use `127.0.0.1` for OBS WHIP or native client to access SRS Stack by localhost. + 1. Use `Host` if it's a valid IP address, for example, to access SRS Stack by public ip address. + 1. Use DNS lookup if `Host` is a domain, for example, to access SRS Stack by domain name. +1. If no candidate, use docker IP address discovered by SRS. + ## Docker Allocated Ports The ports allocated: @@ -895,6 +911,7 @@ For testing the specified service: * `NODE_ENV`: `development|production`, if development, use local redis; otherwise, use `mgmt.srs.local` in docker. * `LOCAL_RELEASE`: `on|off`, whether use local release service. Default: off +* `PLATFORM_DOCKER`: `on|off`, whether run platform in docker. Default: off For mgmt and containers to connect to redis: @@ -921,7 +938,6 @@ Deprecated and unused variables: * `SRS_DOCKERIZED`: `on|off`, indicates the OS is in docker. * `SRS_DOCKER`: `srs` to enfore use `ossrs/srs` docker image. * `MGMT_DOCKER`: `on|off`, whether run mgmt in docker. Default: false -* `PLATFORM_DOCKER`: `on|off`, whether run platform in docker. Default: on * `USE_DOCKER`: `on|off`, if false, disable all docker containers. * `SRS_UTEST`: `on|off`, if on, running in utest mode. * `SOURCE`: `github|gitee`, The source code for upgrading. diff --git a/focal/Dockerfile b/focal/Dockerfile index a1f6898a..c8fd1dd8 100644 --- a/focal/Dockerfile +++ b/focal/Dockerfile @@ -18,7 +18,7 @@ COPY --from=lego /lego /usr/local/bin/ # We write the common config for platform to base image, however you can # overwrite it if not for platform, for example, used in releases. -ENV PORT=":2024" NODE_ENV=production CLOUD=DOCKER +ENV PORT=":2024" NODE_ENV=production CLOUD=DOCKER PLATFORM_DOCKER=on # Setup the work directory to platform. WORKDIR /usr/local/srs-stack/platform diff --git a/platform/candidate.go b/platform/candidate.go index 826210b7..f8a88587 100644 --- a/platform/candidate.go +++ b/platform/candidate.go @@ -61,9 +61,20 @@ func (v *CandidateWorker) Resolve(host string) (net.IP, error) { } } - // Ignore localhost. + // Resolve the localhost to possible IP address. if host == "localhost" { - return nil, nil + // If directly run in host, like debugging, use the private ipv4. + if os.Getenv("PLATFORM_DOCKER") == "off" { + return conf.ipv4, nil + } + + // For macOS to access by host.docker.internal. + if conf.macIpv4 != nil { + return conf.macIpv4, nil + } + + // Return lo for OBS WHIP or native client to access it. + return net.IPv4(127, 0, 0, 1), nil } // Directly use the ip if not name. diff --git a/platform/containers/conf/srs.release-local.conf b/platform/containers/conf/srs.release-local.conf index 8b9adaa8..5465bf75 100644 --- a/platform/containers/conf/srs.release-local.conf +++ b/platform/containers/conf/srs.release-local.conf @@ -27,6 +27,9 @@ rtc_server { listen 8000; # UDP port # @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#config-candidate candidate $CANDIDATE; + # Disable for SRS Stack. + use_auto_detect_network_ip off; + api_as_candidates off; } # See https://github.com/ossrs/srs/issues/1147 diff --git a/platform/containers/conf/srs.release-mac.conf b/platform/containers/conf/srs.release-mac.conf index 0a6610b0..cf745369 100644 --- a/platform/containers/conf/srs.release-mac.conf +++ b/platform/containers/conf/srs.release-mac.conf @@ -27,6 +27,9 @@ rtc_server { listen 8000; # UDP port # @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#config-candidate candidate $CANDIDATE; + # Disable for SRS Stack. + use_auto_detect_network_ip off; + api_as_candidates off; } # See https://github.com/ossrs/srs/issues/1147 diff --git a/platform/containers/conf/srs.release.conf b/platform/containers/conf/srs.release.conf index c1fecf8e..a44f3a42 100644 --- a/platform/containers/conf/srs.release.conf +++ b/platform/containers/conf/srs.release.conf @@ -28,6 +28,9 @@ rtc_server { listen 8000; # UDP port # @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#config-candidate candidate $CANDIDATE; + # Disable for SRS Stack. + use_auto_detect_network_ip off; + api_as_candidates off; } # See https://github.com/ossrs/srs/issues/1147 diff --git a/platform/main.go b/platform/main.go index 0861a09d..6d1d6b70 100644 --- a/platform/main.go +++ b/platform/main.go @@ -96,7 +96,6 @@ func doMain(ctx context.Context) error { // Migrate from mgmt. setEnvDefault("REDIS_PORT", "6379") setEnvDefault("MGMT_LISTEN", "2022") - setEnvDefault("PLATFORM_DOCKER", "on") // For HTTPS. setEnvDefault("HTTPS_LISTEN", "2443") @@ -104,19 +103,21 @@ func doMain(ctx context.Context) error { // For feature control. setEnvDefault("NAME_LOOKUP", "on") + setEnvDefault("PLATFORM_DOCKER", "off") logger.Tf(ctx, "load .env as MGMT_PASSWORD=%vB, "+ "SRS_PLATFORM_SECRET=%vB, CLOUD=%v, REGION=%v, SOURCE=%v, "+ "NODE_ENV=%v, LOCAL_RELEASE=%v, REDIS_PASSWORD=%vB, REDIS_PORT=%v, "+ "PUBLIC_URL=%v, BUILD_PATH=%v, REACT_APP_LOCALE=%v, PLATFORM_LISTEN=%v, "+ "REGISTRY=%v, MGMT_LISTEN=%v, HTTPS_LISTEN=%v, AUTO_SELF_SIGNED_CERTIFICATE=%v, "+ - "NAME_LOOKUP=%v", + "NAME_LOOKUP=%v, PLATFORM_DOCKER=%v", len(os.Getenv("MGMT_PASSWORD")), len(os.Getenv("SRS_PLATFORM_SECRET")), os.Getenv("CLOUD"), os.Getenv("REGION"), os.Getenv("SOURCE"), os.Getenv("NODE_ENV"), os.Getenv("LOCAL_RELEASE"), len(os.Getenv("REDIS_PASSWORD")), os.Getenv("REDIS_PORT"), os.Getenv("PUBLIC_URL"), os.Getenv("BUILD_PATH"), os.Getenv("REACT_APP_LOCALE"), os.Getenv("PLATFORM_LISTEN"), os.Getenv("REGISTRY"), os.Getenv("MGMT_LISTEN"), os.Getenv("HTTPS_LISTEN"), os.Getenv("AUTO_SELF_SIGNED_CERTIFICATE"), os.Getenv("NAME_LOOKUP"), + os.Getenv("PLATFORM_DOCKER"), ) // Setup the base OS for redis, which should never depends on redis. diff --git a/platform/utils.go b/platform/utils.go index 1ba906cf..e72e92cc 100644 --- a/platform/utils.go +++ b/platform/utils.go @@ -55,8 +55,11 @@ type Config struct { Source string Registry string + // Discover by iface. ipv4 net.IP Iface string + // Discover by host.docker.internal for macOS. + macIpv4 net.IP // The latest and stable version from SRS Stack API. Versions Versions @@ -427,11 +430,22 @@ func refreshIPv4(ctx context.Context) error { ipv4Cancel() } - duration := time.Duration(24*3600) * time.Second - if os.Getenv("NODE_ENV") == "development" { - duration = time.Duration(30) * time.Second + // The ip address might change, so we should always resolve it. + time.Sleep(time.Duration(30) * time.Second) + } + }() + + go func() { + ctx := logger.WithContext(ctx) + for ctx.Err() == nil { + if ips, err := net.LookupHost("host.docker.internal"); err == nil && len(ips) > 0 { + if ip := net.ParseIP(ips[0]); ip != nil && !ip.IsLoopback() { + conf.macIpv4 = ip + } } - time.Sleep(duration) + + // The ip address might change, so we should always resolve it. + time.Sleep(time.Duration(30) * time.Second) } }() diff --git a/ui/src/setupProxy.js b/ui/src/setupProxy.js index 27d5044a..7ffb3b3e 100644 --- a/ui/src/setupProxy.js +++ b/ui/src/setupProxy.js @@ -13,20 +13,20 @@ console.log('setupProxy for development reactjs'); // See https://create-react-app.dev/docs/proxying-api-requests-in-development/#configuring-the-proxy-manually module.exports = function(app) { // Proxy all default mounts to mgmt. - app.use('/console/', createProxyMiddleware({target: 'http://127.0.0.1:2024/'})); - app.use('/players/', createProxyMiddleware({target: 'http://127.0.0.1:2024/'})); - app.use('/terraform/', createProxyMiddleware({target: 'http://127.0.0.1:2024/'})); - app.use('/tools/', createProxyMiddleware({target: 'http://127.0.0.1:2024/'})); + app.use('/console/', createProxyMiddleware({target: 'http://127.0.0.1:2022/'})); + app.use('/players/', createProxyMiddleware({target: 'http://127.0.0.1:2022/'})); + app.use('/terraform/', createProxyMiddleware({target: 'http://127.0.0.1:2022/'})); + app.use('/tools/', createProxyMiddleware({target: 'http://127.0.0.1:2022/'})); // Proxy to SRS API and streaming. const withLogs = (options) => { return createProxyMiddleware(options); }; - app.use('/api/', withLogs({target: 'http://127.0.0.1:1985/'})); - app.use('/rtc/', withLogs({target: 'http://127.0.0.1:1985/'})); - app.use('/*/*.(flv|m3u8|ts|aac|mp3)', withLogs({target: 'http://127.0.0.1:8080/'})); + app.use('/api/', withLogs({target: 'http://127.0.0.1:2022/'})); + app.use('/rtc/', withLogs({target: 'http://127.0.0.1:2022/'})); + app.use('/*/*.(flv|m3u8|ts|aac|mp3)', withLogs({target: 'http://127.0.0.1:2022/'})); // The redefined home page. - app.use('/index.html', createProxyMiddleware({target: 'http://127.0.0.1:2024/'})); + app.use('/index.html', createProxyMiddleware({target: 'http://127.0.0.1:2022/'})); };