add new Server struct

This commit is contained in:
aler9
2020-12-06 17:31:51 +01:00
parent 30232b8de6
commit 6d201429f1
3 changed files with 115 additions and 49 deletions

51
server.go Normal file
View File

@@ -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
}

56
serverconf.go Normal file
View File

@@ -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
}

View File

@@ -14,29 +14,10 @@ const (
serverWriteBufferSize = 4096 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. // ServerConn is a server-side RTSP connection.
type ServerConn struct { type ServerConn struct {
conf ServerConnConf c ServerConf
nconn net.Conn
br *bufio.Reader br *bufio.Reader
bw *bufio.Writer bw *bufio.Writer
request *base.Request request *base.Request
@@ -44,41 +25,19 @@ type ServerConn struct {
tcpFrameBuffer *multibuffer.MultiBuffer 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. // Close closes all the ServerConn resources.
func (s *ServerConn) Close() error { func (s *ServerConn) Close() error {
return s.conf.Conn.Close() return s.nconn.Close()
} }
// NetConn returns the underlying net.Conn. // NetConn returns the underlying net.Conn.
func (s *ServerConn) NetConn() net.Conn { func (s *ServerConn) NetConn() net.Conn {
return s.conf.Conn return s.nconn
} }
// ReadRequest reads a Request. // ReadRequest reads a Request.
func (s *ServerConn) ReadRequest() (*base.Request, error) { 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) err := s.request.Read(s.br)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -92,7 +51,7 @@ func (s *ServerConn) ReadFrameTCPOrRequest(timeout bool) (interface{}, error) {
s.frame.Content = s.tcpFrameBuffer.Next() s.frame.Content = s.tcpFrameBuffer.Next()
if timeout { 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) 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. // WriteResponse writes a Response.
func (s *ServerConn) WriteResponse(res *base.Response) error { 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) return res.Write(s.bw)
} }
@@ -112,6 +71,6 @@ func (s *ServerConn) WriteFrameTCP(trackID int, streamType StreamType, content [
Content: 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) return frame.Write(s.bw)
} }