Browse Source

move clientrtmp inside serverrtmp

pull/372/head
aler9 4 years ago
parent
commit
22ba5f3f18
  1. 28
      internal/clientman/clientman.go
  2. 2
      internal/clientrtmp/client.go
  3. 149
      internal/serverrtmp/server.go
  4. 56
      main.go

28
internal/clientman/clientman.go

@ -1,7 +1,6 @@
package clientman package clientman
import ( import (
"net"
"sync" "sync"
"time" "time"
@ -9,10 +8,8 @@ import (
"github.com/aler9/rtsp-simple-server/internal/client" "github.com/aler9/rtsp-simple-server/internal/client"
"github.com/aler9/rtsp-simple-server/internal/clienthls" "github.com/aler9/rtsp-simple-server/internal/clienthls"
"github.com/aler9/rtsp-simple-server/internal/clientrtmp"
"github.com/aler9/rtsp-simple-server/internal/logger" "github.com/aler9/rtsp-simple-server/internal/logger"
"github.com/aler9/rtsp-simple-server/internal/serverhls" "github.com/aler9/rtsp-simple-server/internal/serverhls"
"github.com/aler9/rtsp-simple-server/internal/serverrtmp"
"github.com/aler9/rtsp-simple-server/internal/stats" "github.com/aler9/rtsp-simple-server/internal/stats"
) )
@ -41,7 +38,6 @@ type ClientManager struct {
protocols map[base.StreamProtocol]struct{} protocols map[base.StreamProtocol]struct{}
stats *stats.Stats stats *stats.Stats
pathMan PathManager pathMan PathManager
serverRTMP *serverrtmp.Server
serverHLS *serverhls.Server serverHLS *serverhls.Server
parent Parent parent Parent
@ -70,7 +66,6 @@ func New(
protocols map[base.StreamProtocol]struct{}, protocols map[base.StreamProtocol]struct{},
stats *stats.Stats, stats *stats.Stats,
pathMan PathManager, pathMan PathManager,
serverRTMP *serverrtmp.Server,
serverHLS *serverhls.Server, serverHLS *serverhls.Server,
parent Parent) *ClientManager { parent Parent) *ClientManager {
@ -86,7 +81,6 @@ func New(
protocols: protocols, protocols: protocols,
stats: stats, stats: stats,
pathMan: pathMan, pathMan: pathMan,
serverRTMP: serverRTMP,
serverHLS: serverHLS, serverHLS: serverHLS,
parent: parent, parent: parent,
clients: make(map[client.Client]struct{}), clients: make(map[client.Client]struct{}),
@ -115,13 +109,6 @@ func (cm *ClientManager) Log(level logger.Level, format string, args ...interfac
func (cm *ClientManager) run() { func (cm *ClientManager) run() {
defer close(cm.done) defer close(cm.done)
rtmpAccept := func() chan net.Conn {
if cm.serverRTMP != nil {
return cm.serverRTMP.Accept()
}
return make(chan net.Conn)
}()
hlsRequest := func() chan serverhls.Request { hlsRequest := func() chan serverhls.Request {
if cm.serverHLS != nil { if cm.serverHLS != nil {
return cm.serverHLS.Request() return cm.serverHLS.Request()
@ -132,21 +119,6 @@ func (cm *ClientManager) run() {
outer: outer:
for { for {
select { select {
case nconn := <-rtmpAccept:
c := clientrtmp.New(
cm.rtspAddress,
cm.readTimeout,
cm.writeTimeout,
cm.readBufferCount,
cm.runOnConnect,
cm.runOnConnectRestart,
&cm.wg,
cm.stats,
nconn,
cm.pathMan,
cm)
cm.clients[c] = struct{}{}
case req := <-hlsRequest: case req := <-hlsRequest:
c, ok := cm.clientsByHLSPath[req.Path] c, ok := cm.clientsByHLSPath[req.Path]
if !ok { if !ok {

2
internal/clientrtmp/client.go

@ -75,7 +75,7 @@ type PathMan interface {
// Parent is implemented by clientman.ClientMan. // Parent is implemented by clientman.ClientMan.
type Parent interface { type Parent interface {
Log(logger.Level, string, ...interface{}) Log(logger.Level, string, ...interface{})
OnClientClose(client.Client) OnClientClose(*Client)
} }
// Client is a RTMP client. // Client is a RTMP client.

149
internal/serverrtmp/server.go

@ -2,9 +2,13 @@ package serverrtmp
import ( import (
"net" "net"
"sync/atomic" "sync"
"time"
"github.com/aler9/rtsp-simple-server/internal/clientrtmp"
"github.com/aler9/rtsp-simple-server/internal/logger" "github.com/aler9/rtsp-simple-server/internal/logger"
"github.com/aler9/rtsp-simple-server/internal/pathman"
"github.com/aler9/rtsp-simple-server/internal/stats"
) )
// Parent is implemented by program. // Parent is implemented by program.
@ -14,19 +18,39 @@ type Parent interface {
// Server is a RTMP listener. // Server is a RTMP listener.
type Server struct { type Server struct {
readTimeout time.Duration
writeTimeout time.Duration
readBufferCount int
rtspAddress string
runOnConnect string
runOnConnectRestart bool
stats *stats.Stats
pathMan *pathman.PathManager
parent Parent parent Parent
l net.Listener l net.Listener
closed uint32 wg sync.WaitGroup
clients map[*clientrtmp.Client]struct{}
// in
clientClose chan *clientrtmp.Client
terminate chan struct{}
// out // out
accept chan net.Conn
done chan struct{} done chan struct{}
} }
// New allocates a Server. // New allocates a Server.
func New( func New(
address string, address string,
readTimeout time.Duration,
writeTimeout time.Duration,
readBufferCount int,
rtspAddress string,
runOnConnect string,
runOnConnectRestart bool,
stats *stats.Stats,
pathMan *pathman.PathManager,
parent Parent) (*Server, error) { parent Parent) (*Server, error) {
l, err := net.Listen("tcp", address) l, err := net.Listen("tcp", address)
@ -35,55 +59,134 @@ func New(
} }
s := &Server{ s := &Server{
readTimeout: readTimeout,
writeTimeout: writeTimeout,
readBufferCount: readBufferCount,
rtspAddress: rtspAddress,
runOnConnect: runOnConnect,
runOnConnectRestart: runOnConnectRestart,
stats: stats,
pathMan: pathMan,
parent: parent, parent: parent,
l: l, l: l,
accept: make(chan net.Conn), clients: make(map[*clientrtmp.Client]struct{}),
clientClose: make(chan *clientrtmp.Client),
terminate: make(chan struct{}),
done: make(chan struct{}), done: make(chan struct{}),
} }
s.log(logger.Info, "opened on %s", address) s.Log(logger.Info, "listener opened on %s", address)
go s.run() go s.run()
return s, nil return s, nil
} }
func (s *Server) log(level logger.Level, format string, args ...interface{}) { // Log is the main logging function.
s.parent.Log(level, "[RTMP listener] "+format, append([]interface{}{}, args...)...) func (s *Server) Log(level logger.Level, format string, args ...interface{}) {
s.parent.Log(level, "[RTMP] "+format, append([]interface{}{}, args...)...)
} }
// Close closes a Server. // Close closes a Server.
func (s *Server) Close() { func (s *Server) Close() {
go func() { close(s.terminate)
for co := range s.accept {
co.Close()
}
}()
atomic.StoreUint32(&s.closed, 1)
s.l.Close()
<-s.done <-s.done
} }
func (s *Server) run() { func (s *Server) run() {
defer close(s.done) defer close(s.done)
s.wg.Add(1)
clientNew := make(chan net.Conn)
acceptErr := make(chan error)
go func() {
defer s.wg.Done()
acceptErr <- func() error {
for { for {
nconn, err := s.l.Accept() conn, err := s.l.Accept()
if err != nil { if err != nil {
if atomic.LoadUint32(&s.closed) == 1 { return err
break }
clientNew <- conn
} }
s.log(logger.Warn, "ERR: %s", err) }()
}()
outer:
for {
select {
case err := <-acceptErr:
s.Log(logger.Warn, "ERR: %s", err)
break outer
case nconn := <-clientNew:
c := clientrtmp.New(
s.rtspAddress,
s.readTimeout,
s.writeTimeout,
s.readBufferCount,
s.runOnConnect,
s.runOnConnectRestart,
&s.wg,
s.stats,
nconn,
s.pathMan,
s)
s.clients[c] = struct{}{}
case c := <-s.clientClose:
if _, ok := s.clients[c]; !ok {
continue continue
} }
s.doClientClose(c)
s.accept <- nconn case <-s.terminate:
break outer
} }
}
go func() {
for {
select {
case _, ok := <-acceptErr:
if !ok {
return
}
case conn, ok := <-clientNew:
if !ok {
return
}
conn.Close()
case _, ok := <-s.clientClose:
if !ok {
return
}
}
}
}()
s.l.Close()
for c := range s.clients {
s.doClientClose(c)
}
s.wg.Wait()
close(acceptErr)
close(clientNew)
close(s.clientClose)
}
close(s.accept) func (s *Server) doClientClose(c *clientrtmp.Client) {
delete(s.clients, c)
c.Close()
} }
// Accept returns a channel to accept incoming connections. // OnClientClose is called by a client.
func (s *Server) Accept() chan net.Conn { func (s *Server) OnClientClose(c *clientrtmp.Client) {
return s.accept s.clientClose <- c
} }

56
main.go

@ -191,17 +191,6 @@ func (p *program) createResources(initial bool) error {
} }
} }
if !p.conf.RTMPDisable {
if p.serverRTMP == nil {
p.serverRTMP, err = serverrtmp.New(
p.conf.RTMPAddress,
p)
if err != nil {
return err
}
}
}
if !p.conf.HLSDisable { if !p.conf.HLSDisable {
if p.serverHLS == nil { if p.serverHLS == nil {
p.serverHLS, err = serverhls.New( p.serverHLS, err = serverhls.New(
@ -239,7 +228,6 @@ func (p *program) createResources(initial bool) error {
p.conf.ProtocolsParsed, p.conf.ProtocolsParsed,
p.stats, p.stats,
p.pathMan, p.pathMan,
p.serverRTMP,
p.serverHLS, p.serverHLS,
p) p)
} }
@ -303,6 +291,25 @@ func (p *program) createResources(initial bool) error {
} }
} }
if !p.conf.RTMPDisable {
if p.serverRTMP == nil {
p.serverRTMP, err = serverrtmp.New(
p.conf.RTMPAddress,
p.conf.ReadTimeout,
p.conf.WriteTimeout,
p.conf.ReadBufferCount,
p.conf.RTSPAddress,
p.conf.RunOnConnect,
p.conf.RunOnConnectRestart,
p.stats,
p.pathMan,
p)
if err != nil {
return err
}
}
}
return nil return nil
} }
@ -335,15 +342,6 @@ func (p *program) closeResources(newConf *conf.Conf) {
closePPROF = true closePPROF = true
} }
closeServerRTMP := false
if newConf == nil ||
newConf.RTMPDisable != p.conf.RTMPDisable ||
newConf.RTMPAddress != p.conf.RTMPAddress ||
newConf.ReadTimeout != p.conf.ReadTimeout ||
closeStats {
closeServerRTMP = true
}
closeServerHLS := false closeServerHLS := false
if newConf == nil || if newConf == nil ||
newConf.HLSDisable != p.conf.HLSDisable || newConf.HLSDisable != p.conf.HLSDisable ||
@ -368,7 +366,6 @@ func (p *program) closeResources(newConf *conf.Conf) {
closeClientMan := false closeClientMan := false
if newConf == nil || if newConf == nil ||
closeServerRTMP ||
closeServerHLS || closeServerHLS ||
closePathMan || closePathMan ||
newConf.HLSSegmentCount != p.conf.HLSSegmentCount || newConf.HLSSegmentCount != p.conf.HLSSegmentCount ||
@ -423,6 +420,21 @@ func (p *program) closeResources(newConf *conf.Conf) {
closeServerTLS = true closeServerTLS = true
} }
closeServerRTMP := false
if newConf == nil ||
newConf.RTMPDisable != p.conf.RTMPDisable ||
newConf.RTMPAddress != p.conf.RTMPAddress ||
newConf.ReadTimeout != p.conf.ReadTimeout ||
newConf.WriteTimeout != p.conf.WriteTimeout ||
newConf.ReadBufferCount != p.conf.ReadBufferCount ||
newConf.RTSPAddress != p.conf.RTSPAddress ||
newConf.RunOnConnect != p.conf.RunOnConnect ||
newConf.RunOnConnectRestart != p.conf.RunOnConnectRestart ||
closeStats ||
closePathMan {
closeServerRTMP = true
}
if closeServerTLS && p.serverRTSPTLS != nil { if closeServerTLS && p.serverRTSPTLS != nil {
p.serverRTSPTLS.Close() p.serverRTSPTLS.Close()
p.serverRTSPTLS = nil p.serverRTSPTLS = nil

Loading…
Cancel
Save