Skip to content

Commit 6de2a53

Browse files
ossrs-aiwinlinvip
authored andcommitted
Fix #3: RTC listen endpoint issue.
1 parent ad923a9 commit 6de2a53

File tree

7 files changed

+84
-16
lines changed

7 files changed

+84
-16
lines changed

api.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,13 @@ func (v *srsHTTPAPIServer) Run(ctx context.Context) error {
101101

102102
err := v.server.ListenAndServe()
103103
if err != nil {
104-
if ctx.Err() != context.Canceled {
104+
if err == http.ErrServerClosed {
105+
logger.Df(ctx, "HTTP API server done")
106+
} else if ctx.Err() != nil {
107+
logger.Df(ctx, "HTTP API server done with context canceled")
108+
} else {
105109
// TODO: If HTTP API server closed unexpectedly, we should notice the main loop to quit.
106110
logger.Wf(ctx, "HTTP API accept err %+v", err)
107-
} else {
108-
logger.Df(ctx, "HTTP API server done")
109111
}
110112
}
111113
}()
@@ -259,11 +261,13 @@ func (v *systemAPI) Run(ctx context.Context) error {
259261

260262
err := v.server.ListenAndServe()
261263
if err != nil {
262-
if ctx.Err() != context.Canceled {
264+
if err == http.ErrServerClosed {
265+
logger.Df(ctx, "System API server done")
266+
} else if ctx.Err() != nil {
267+
logger.Df(ctx, "System API server done with context canceled")
268+
} else {
263269
// TODO: If System API server closed unexpectedly, we should notice the main loop to quit.
264270
logger.Wf(ctx, "System API accept err %+v", err)
265-
} else {
266-
logger.Df(ctx, "System API server done")
267271
}
268272
}
269273
}()

env.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,8 @@ func buildDefaultEnvironmentVariables(ctx context.Context) {
8080
setEnvDefault("PROXY_SRT_SERVER", "20080")
8181
// The API server of proxy itself.
8282
setEnvDefault("PROXY_SYSTEM_API", "12025")
83-
// The static directory for web server.
84-
setEnvDefault("PROXY_STATIC_FILES", "../trunk/research")
83+
// The static directory for web server, optional.
84+
setEnvDefault("PROXY_STATIC_FILES", "")
8585

8686
// The load balancer, use redis or memory.
8787
setEnvDefault("PROXY_LOAD_BALANCER_TYPE", "memory")

http.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,11 +162,13 @@ func (v *srsHTTPStreamServer) Run(ctx context.Context) error {
162162

163163
err := v.server.ListenAndServe()
164164
if err != nil {
165-
if ctx.Err() != context.Canceled {
165+
if err == http.ErrServerClosed {
166+
logger.Df(ctx, "HTTP Stream server done")
167+
} else if ctx.Err() != nil {
168+
logger.Df(ctx, "HTTP Stream server done with context canceled")
169+
} else {
166170
// TODO: If HTTP Stream server closed unexpectedly, we should notice the main loop to quit.
167171
logger.Wf(ctx, "HTTP Stream accept err %+v", err)
168-
} else {
169-
logger.Df(ctx, "HTTP Stream server done")
170172
}
171173
}
172174
}()

rtc.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,11 @@ func (v *srsWebRTCServer) Run(ctx context.Context) error {
258258
buf := make([]byte, 4096)
259259
n, caddr, err := listener.ReadFromUDP(buf)
260260
if err != nil {
261+
// If context is canceled or connection is closed, exit gracefully without logging error.
262+
if ctx.Err() != nil || isClosedNetworkError(err) {
263+
logger.Df(ctx, "WebRTC server done")
264+
return
265+
}
261266
// TODO: If WebRTC server closed unexpectedly, we should notice the main loop to quit.
262267
logger.Wf(ctx, "WebRTC read from udp failed, err=%+v", err)
263268
time.Sleep(1 * time.Second)

rtmp.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,12 @@ func (v *srsRTMPServer) Run(ctx context.Context) error {
7474
for {
7575
conn, err := v.listener.AcceptTCP()
7676
if err != nil {
77-
if ctx.Err() != context.Canceled {
77+
// If context is canceled or connection is closed, exit gracefully without logging error.
78+
if ctx.Err() != nil || isClosedNetworkError(err) {
79+
logger.Df(ctx, "RTMP server done")
80+
} else {
7881
// TODO: If RTMP server closed unexpectedly, we should notice the main loop to quit.
7982
logger.Wf(ctx, "RTMP server accept err %+v", err)
80-
} else {
81-
logger.Df(ctx, "RTMP server done")
8283
}
8384
return
8485
}

srt.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ func (v *srsSRTServer) Run(ctx context.Context) error {
8282
buf := make([]byte, 4096)
8383
n, caddr, err := v.listener.ReadFromUDP(buf)
8484
if err != nil {
85+
// If context is canceled or connection is closed, exit gracefully without logging error.
86+
if ctx.Err() != nil || isClosedNetworkError(err) {
87+
logger.Df(ctx, "SRT server done")
88+
return
89+
}
8590
// TODO: If SRT server closed unexpectedly, we should notice the main loop to quit.
8691
logger.Wf(ctx, "SRT read from udp failed, err=%+v", err)
8792
time.Sleep(1 * time.Second)

utils.go

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ func apiError(ctx context.Context, w http.ResponseWriter, r *http.Request, err e
4545
logger.Wf(ctx, "HTTP API error %+v", err)
4646
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
4747
w.WriteHeader(http.StatusInternalServerError)
48-
fmt.Fprintln(w, fmt.Sprintf("%v", err))
48+
fmt.Fprintf(w, "%v\n", err)
4949
}
5050

5151
func apiCORS(ctx context.Context, w http.ResponseWriter, r *http.Request) bool {
@@ -142,6 +142,20 @@ func isPeerClosedError(err error) bool {
142142
return false
143143
}
144144

145+
// isClosedNetworkError indicates whether the error is due to a closed network connection.
146+
func isClosedNetworkError(err error) bool {
147+
if err == nil {
148+
return false
149+
}
150+
151+
// Check for "use of closed network connection" error
152+
if netErr, ok := err.(*net.OpError); ok {
153+
return netErr.Err.Error() == "use of closed network connection"
154+
}
155+
156+
return false
157+
}
158+
145159
// convertURLToStreamURL convert the URL in HTTP request to special URLs. The unifiedURL is the URL
146160
// in unified, foramt as scheme://vhost/app/stream without extensions. While the fullURL is the unifiedURL
147161
// with extension.
@@ -263,7 +277,44 @@ func parseListenEndpoint(ep string) (protocol string, ip net.IP, port uint16, er
263277
}
264278
}
265279

266-
// Must be protocol://ip:port schema.
280+
// Handle URL-style format: protocol://host:port or protocol://port
281+
if strings.Contains(ep, "://") {
282+
parts := strings.SplitN(ep, "://", 2)
283+
if len(parts) != 2 {
284+
return "", nil, 0, errors.Errorf("invalid endpoint %v", ep)
285+
}
286+
287+
protocol = parts[0]
288+
hostPort := parts[1]
289+
290+
// Check if there's a port specified
291+
if strings.Contains(hostPort, ":") {
292+
// Format: protocol://host:port
293+
host, portStr, err := net.SplitHostPort(hostPort)
294+
if err != nil {
295+
return "", nil, 0, errors.Wrapf(err, "parse host:port %v", hostPort)
296+
}
297+
298+
p, err := strconv.Atoi(portStr)
299+
if err != nil {
300+
return "", nil, 0, errors.Wrapf(err, "parse port %v", portStr)
301+
}
302+
303+
if host != "" {
304+
ip = net.ParseIP(host)
305+
}
306+
return protocol, ip, uint16(p), nil
307+
} else {
308+
// Format: protocol://port
309+
p, err := strconv.Atoi(hostPort)
310+
if err != nil {
311+
return "", nil, 0, errors.Wrapf(err, "parse port %v", hostPort)
312+
}
313+
return protocol, nil, uint16(p), nil
314+
}
315+
}
316+
317+
// Legacy format: protocol:ip:port
267318
parts := strings.Split(ep, ":")
268319
if len(parts) != 3 {
269320
return "", nil, 0, errors.Errorf("invalid endpoint %v", ep)

0 commit comments

Comments
 (0)