diff --git a/server.go b/server.go new file mode 100644 index 00000000..6270b010 --- /dev/null +++ b/server.go @@ -0,0 +1,51 @@ +package gortsplib + +import ( + "bufio" + "net" + "time" + + "github.com/aler9/gortsplib/pkg/base" + "github.com/aler9/gortsplib/pkg/multibuffer" +) + +type ServerHandler interface { +} + +type Server struct { + c ServerConf + listener *net.TCPListener +} + +func (s *Server) Close() error { + return s.listener.Close() +} + +func (s *Server) Accept() (*ServerConn, error) { + nconn, err := s.listener.Accept() + if err != nil { + return nil, err + } + + if s.c.ReadTimeout == 0 { + s.c.ReadTimeout = 10 * time.Second + } + if s.c.WriteTimeout == 0 { + s.c.WriteTimeout = 10 * time.Second + } + if s.c.ReadBufferCount == 0 { + s.c.ReadBufferCount = 1 + } + + sc := &ServerConn{ + c: s.c, + nconn: nconn, + br: bufio.NewReaderSize(nconn, serverReadBufferSize), + bw: bufio.NewWriterSize(nconn, serverWriteBufferSize), + request: &base.Request{}, + frame: &base.InterleavedFrame{}, + tcpFrameBuffer: multibuffer.New(s.c.ReadBufferCount, clientTCPFrameReadBufferSize), + } + + return sc, nil +} diff --git a/serverconf.go b/serverconf.go new file mode 100644 index 00000000..18d54d65 --- /dev/null +++ b/serverconf.go @@ -0,0 +1,56 @@ +package gortsplib + +import ( + "net" + "time" +) + +// DefaultServerConf is the default ServerConf. +var DefaultServerConf = ServerConf{} + +// Serve starts a server on the given address. +func Serve(address string, handler ServerHandler) (*Server, error) { + return DefaultServerConf.Serve(address, handler) +} + +// ServerConf allows to configure a Server. +// All fields are optional. +type ServerConf struct { + // timeout of read operations. + // It defaults to 10 seconds + ReadTimeout time.Duration + + // timeout of write operations. + // It defaults to 10 seconds + WriteTimeout time.Duration + + // read buffer count. + // If greater than 1, allows to pass buffers to routines different than the one + // that is reading frames. + // It defaults to 1 + ReadBufferCount int + + // function used to initialize the TCP listener. + // It defaults to net.ListenTCP. + ListenTCP func(network string, address *net.TCPAddr) (*net.TCPListener, error) +} + +// Serve starts a server on the given address. +func (c ServerConf) Serve(address string, handler ServerHandler) (*Server, error) { + addr, err := net.ResolveTCPAddr("tcp", address) + if err != nil { + return nil, err + } + + listener, err := c.ListenTCP("tcp", addr) + if err != nil { + return nil, err + } + + s := &Server{ + c: c, + listener: listener, + } + + return s, nil +} diff --git a/serverconn.go b/serverconn.go index ee86ab1b..8717dfcc 100644 --- a/serverconn.go +++ b/serverconn.go @@ -14,29 +14,10 @@ const ( serverWriteBufferSize = 4096 ) -// ServerConnConf allows to configure a ServerConn. -type ServerConnConf struct { - // pre-existing TCP connection to wrap - Conn net.Conn - - // (optional) timeout of read operations. - // It defaults to 10 seconds - ReadTimeout time.Duration - - // (optional) timeout of write operations. - // It defaults to 10 seconds - WriteTimeout time.Duration - - // (optional) read buffer count. - // If greater than 1, allows to pass buffers to routines different than the one - // that is reading frames. - // It defaults to 1 - ReadBufferCount int -} - // ServerConn is a server-side RTSP connection. type ServerConn struct { - conf ServerConnConf + c ServerConf + nconn net.Conn br *bufio.Reader bw *bufio.Writer request *base.Request @@ -44,41 +25,19 @@ type ServerConn struct { tcpFrameBuffer *multibuffer.MultiBuffer } -// NewServerConn allocates a ServerConn. -func NewServerConn(conf ServerConnConf) *ServerConn { - if conf.ReadTimeout == 0 { - conf.ReadTimeout = 10 * time.Second - } - if conf.WriteTimeout == 0 { - conf.WriteTimeout = 10 * time.Second - } - if conf.ReadBufferCount == 0 { - conf.ReadBufferCount = 1 - } - - return &ServerConn{ - conf: conf, - br: bufio.NewReaderSize(conf.Conn, serverReadBufferSize), - bw: bufio.NewWriterSize(conf.Conn, serverWriteBufferSize), - request: &base.Request{}, - frame: &base.InterleavedFrame{}, - tcpFrameBuffer: multibuffer.New(conf.ReadBufferCount, clientTCPFrameReadBufferSize), - } -} - // Close closes all the ServerConn resources. func (s *ServerConn) Close() error { - return s.conf.Conn.Close() + return s.nconn.Close() } // NetConn returns the underlying net.Conn. func (s *ServerConn) NetConn() net.Conn { - return s.conf.Conn + return s.nconn } // ReadRequest reads a Request. func (s *ServerConn) ReadRequest() (*base.Request, error) { - s.conf.Conn.SetReadDeadline(time.Time{}) // disable deadline + s.nconn.SetReadDeadline(time.Time{}) // disable deadline err := s.request.Read(s.br) if err != nil { return nil, err @@ -92,7 +51,7 @@ func (s *ServerConn) ReadFrameTCPOrRequest(timeout bool) (interface{}, error) { s.frame.Content = s.tcpFrameBuffer.Next() if timeout { - s.conf.Conn.SetReadDeadline(time.Now().Add(s.conf.ReadTimeout)) + s.nconn.SetReadDeadline(time.Now().Add(s.c.ReadTimeout)) } return base.ReadInterleavedFrameOrRequest(s.frame, s.request, s.br) @@ -100,7 +59,7 @@ func (s *ServerConn) ReadFrameTCPOrRequest(timeout bool) (interface{}, error) { // WriteResponse writes a Response. func (s *ServerConn) WriteResponse(res *base.Response) error { - s.conf.Conn.SetWriteDeadline(time.Now().Add(s.conf.WriteTimeout)) + s.nconn.SetWriteDeadline(time.Now().Add(s.c.WriteTimeout)) return res.Write(s.bw) } @@ -112,6 +71,6 @@ func (s *ServerConn) WriteFrameTCP(trackID int, streamType StreamType, content [ Content: content, } - s.conf.Conn.SetWriteDeadline(time.Now().Add(s.conf.WriteTimeout)) + s.nconn.SetWriteDeadline(time.Now().Add(s.c.WriteTimeout)) return frame.Write(s.bw) }