mirror of
https://github.com/aler9/gortsplib
synced 2025-10-03 14:26:42 +08:00
server: add error to OnSessionClose()
This commit is contained in:
@@ -38,7 +38,7 @@ func (sh *serverHandler) OnSessionOpen(ss *gortsplib.ServerSession) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// called when a session is closed.
|
// called when a session is closed.
|
||||||
func (sh *serverHandler) OnSessionClose(ss *gortsplib.ServerSession) {
|
func (sh *serverHandler) OnSessionClose(ss *gortsplib.ServerSession, err error) {
|
||||||
log.Printf("session closed")
|
log.Printf("session closed")
|
||||||
|
|
||||||
sh.mutex.Lock()
|
sh.mutex.Lock()
|
||||||
|
@@ -37,7 +37,7 @@ func (sh *serverHandler) OnSessionOpen(ss *gortsplib.ServerSession) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// called when a session is closed.
|
// called when a session is closed.
|
||||||
func (sh *serverHandler) OnSessionClose(ss *gortsplib.ServerSession) {
|
func (sh *serverHandler) OnSessionClose(ss *gortsplib.ServerSession, err error) {
|
||||||
log.Printf("session closed")
|
log.Printf("session closed")
|
||||||
|
|
||||||
sh.mutex.Lock()
|
sh.mutex.Lock()
|
||||||
|
@@ -7,6 +7,22 @@ import (
|
|||||||
"github.com/aler9/gortsplib/pkg/headers"
|
"github.com/aler9/gortsplib/pkg/headers"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ErrServerTerminated is an error that can be returned by a server.
|
||||||
|
type ErrServerTerminated struct{}
|
||||||
|
|
||||||
|
// Error implements the error interface.
|
||||||
|
func (e ErrServerTerminated) Error() string {
|
||||||
|
return "terminated"
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrServerSessionTimedOut is an error that can be returned by a server.
|
||||||
|
type ErrServerSessionTimedOut struct{}
|
||||||
|
|
||||||
|
// Error implements the error interface.
|
||||||
|
func (e ErrServerSessionTimedOut) Error() string {
|
||||||
|
return "timed out"
|
||||||
|
}
|
||||||
|
|
||||||
// ErrServerTCPFramesEnable is an error that can be returned by a server.
|
// ErrServerTCPFramesEnable is an error that can be returned by a server.
|
||||||
type ErrServerTCPFramesEnable struct{}
|
type ErrServerTCPFramesEnable struct{}
|
||||||
|
|
||||||
@@ -192,11 +208,11 @@ func (e ErrServerLinkedToOtherSession) Error() string {
|
|||||||
return "connection is linked to another session"
|
return "connection is linked to another session"
|
||||||
}
|
}
|
||||||
|
|
||||||
// ErrServerTeardown is an error that can be returned by a server.
|
// ErrServerSessionTeardown is an error that can be returned by a server.
|
||||||
type ErrServerTeardown struct{}
|
type ErrServerSessionTeardown struct{}
|
||||||
|
|
||||||
// Error implements the error interface.
|
// Error implements the error interface.
|
||||||
func (e ErrServerTeardown) Error() string {
|
func (e ErrServerSessionTeardown) Error() string {
|
||||||
return "teardown"
|
return "teardown"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -500,7 +500,7 @@ func TestServerPublish(t *testing.T) {
|
|||||||
onSessionOpen: func(ss *ServerSession) {
|
onSessionOpen: func(ss *ServerSession) {
|
||||||
close(sessionOpened)
|
close(sessionOpened)
|
||||||
},
|
},
|
||||||
onSessionClose: func(ss *ServerSession) {
|
onSessionClose: func(ss *ServerSession, err error) {
|
||||||
close(sessionClosed)
|
close(sessionClosed)
|
||||||
},
|
},
|
||||||
onAnnounce: func(ctx *ServerHandlerOnAnnounceCtx) (*base.Response, error) {
|
onAnnounce: func(ctx *ServerHandlerOnAnnounceCtx) (*base.Response, error) {
|
||||||
@@ -997,7 +997,7 @@ func TestServerPublishErrorTimeout(t *testing.T) {
|
|||||||
|
|
||||||
s := &Server{
|
s := &Server{
|
||||||
Handler: &testServerHandler{
|
Handler: &testServerHandler{
|
||||||
onSessionClose: func(ss *ServerSession) {
|
onSessionClose: func(ss *ServerSession, err error) {
|
||||||
close(sessionClosed)
|
close(sessionClosed)
|
||||||
},
|
},
|
||||||
onAnnounce: func(ctx *ServerHandlerOnAnnounceCtx) (*base.Response, error) {
|
onAnnounce: func(ctx *ServerHandlerOnAnnounceCtx) (*base.Response, error) {
|
||||||
|
@@ -288,7 +288,7 @@ func TestServerRead(t *testing.T) {
|
|||||||
onSessionOpen: func(ss *ServerSession) {
|
onSessionOpen: func(ss *ServerSession) {
|
||||||
close(sessionOpened)
|
close(sessionOpened)
|
||||||
},
|
},
|
||||||
onSessionClose: func(ss *ServerSession) {
|
onSessionClose: func(ss *ServerSession, err error) {
|
||||||
close(sessionClosed)
|
close(sessionClosed)
|
||||||
},
|
},
|
||||||
onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, error) {
|
onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, error) {
|
||||||
|
@@ -19,7 +19,7 @@ type testServerHandler struct {
|
|||||||
onConnOpen func(*ServerConn)
|
onConnOpen func(*ServerConn)
|
||||||
onConnClose func(*ServerConn, error)
|
onConnClose func(*ServerConn, error)
|
||||||
onSessionOpen func(*ServerSession)
|
onSessionOpen func(*ServerSession)
|
||||||
onSessionClose func(*ServerSession)
|
onSessionClose func(*ServerSession, error)
|
||||||
onDescribe func(*ServerHandlerOnDescribeCtx) (*base.Response, []byte, error)
|
onDescribe func(*ServerHandlerOnDescribeCtx) (*base.Response, []byte, error)
|
||||||
onAnnounce func(*ServerHandlerOnAnnounceCtx) (*base.Response, error)
|
onAnnounce func(*ServerHandlerOnAnnounceCtx) (*base.Response, error)
|
||||||
onSetup func(*ServerHandlerOnSetupCtx) (*base.Response, error)
|
onSetup func(*ServerHandlerOnSetupCtx) (*base.Response, error)
|
||||||
@@ -49,9 +49,9 @@ func (sh *testServerHandler) OnSessionOpen(ss *ServerSession) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sh *testServerHandler) OnSessionClose(ss *ServerSession) {
|
func (sh *testServerHandler) OnSessionClose(ss *ServerSession, err error) {
|
||||||
if sh.onSessionClose != nil {
|
if sh.onSessionClose != nil {
|
||||||
sh.onSessionClose(ss)
|
sh.onSessionClose(ss, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,7 +211,7 @@ func TestServerHighLevelPublishRead(t *testing.T) {
|
|||||||
|
|
||||||
s := &Server{
|
s := &Server{
|
||||||
Handler: &testServerHandler{
|
Handler: &testServerHandler{
|
||||||
onSessionClose: func(ss *ServerSession) {
|
onSessionClose: func(ss *ServerSession, err error) {
|
||||||
mutex.Lock()
|
mutex.Lock()
|
||||||
defer mutex.Unlock()
|
defer mutex.Unlock()
|
||||||
|
|
||||||
|
@@ -168,9 +168,9 @@ func (sc *ServerConn) run() {
|
|||||||
}()
|
}()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
var err error
|
err := func() error {
|
||||||
select {
|
select {
|
||||||
case err = <-readDone:
|
case err := <-readDone:
|
||||||
if sc.tcpFrameEnabled {
|
if sc.tcpFrameEnabled {
|
||||||
sc.tcpFrameWriteBuffer.Close()
|
sc.tcpFrameWriteBuffer.Close()
|
||||||
<-sc.tcpFrameBackgroundWriteDone
|
<-sc.tcpFrameBackgroundWriteDone
|
||||||
@@ -178,6 +178,7 @@ func (sc *ServerConn) run() {
|
|||||||
sc.nconn.Close()
|
sc.nconn.Close()
|
||||||
sc.s.connClose <- sc
|
sc.s.connClose <- sc
|
||||||
<-sc.terminate
|
<-sc.terminate
|
||||||
|
return err
|
||||||
|
|
||||||
case <-sc.terminate:
|
case <-sc.terminate:
|
||||||
if sc.tcpFrameEnabled {
|
if sc.tcpFrameEnabled {
|
||||||
@@ -185,8 +186,10 @@ func (sc *ServerConn) run() {
|
|||||||
<-sc.tcpFrameBackgroundWriteDone
|
<-sc.tcpFrameBackgroundWriteDone
|
||||||
}
|
}
|
||||||
sc.nconn.Close()
|
sc.nconn.Close()
|
||||||
err = <-readDone
|
<-readDone
|
||||||
|
return liberrors.ErrServerTerminated{}
|
||||||
}
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
if sc.tcpFrameEnabled {
|
if sc.tcpFrameEnabled {
|
||||||
sc.s.sessionClose <- sc.tcpFrameLinkedSession
|
sc.s.sessionClose <- sc.tcpFrameLinkedSession
|
||||||
|
@@ -26,7 +26,7 @@ type ServerHandlerOnSessionOpen interface {
|
|||||||
|
|
||||||
// ServerHandlerOnSessionClose can be implemented by a ServerHandler.
|
// ServerHandlerOnSessionClose can be implemented by a ServerHandler.
|
||||||
type ServerHandlerOnSessionClose interface {
|
type ServerHandlerOnSessionClose interface {
|
||||||
OnSessionClose(*ServerSession)
|
OnSessionClose(*ServerSession, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServerHandlerOnRequest can be implemented by a ServerHandler.
|
// ServerHandlerOnRequest can be implemented by a ServerHandler.
|
||||||
|
@@ -210,7 +210,7 @@ func (ss *ServerSession) run() {
|
|||||||
receiverReportTicker := time.NewTicker(ss.s.receiverReportPeriod)
|
receiverReportTicker := time.NewTicker(ss.s.receiverReportPeriod)
|
||||||
defer receiverReportTicker.Stop()
|
defer receiverReportTicker.Stop()
|
||||||
|
|
||||||
outer:
|
err := func() error {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case req := <-ss.request:
|
case req := <-ss.request:
|
||||||
@@ -225,9 +225,9 @@ outer:
|
|||||||
res.Header["Session"] = base.HeaderValue{ss.id}
|
res.Header["Session"] = base.HeaderValue{ss.id}
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := err.(liberrors.ErrServerTeardown); ok {
|
if _, ok := err.(liberrors.ErrServerSessionTeardown); ok {
|
||||||
req.res <- requestRes{res, nil}
|
req.res <- requestRes{res, nil}
|
||||||
break outer
|
return liberrors.ErrServerSessionTeardown{}
|
||||||
}
|
}
|
||||||
|
|
||||||
req.res <- requestRes{res, err}
|
req.res <- requestRes{res, err}
|
||||||
@@ -239,7 +239,7 @@ outer:
|
|||||||
now := time.Now()
|
now := time.Now()
|
||||||
lft := atomic.LoadInt64(ss.udpLastFrameTime)
|
lft := atomic.LoadInt64(ss.udpLastFrameTime)
|
||||||
if now.Sub(time.Unix(lft, 0)) >= ss.s.ReadTimeout {
|
if now.Sub(time.Unix(lft, 0)) >= ss.s.ReadTimeout {
|
||||||
break outer
|
return liberrors.ErrServerSessionTimedOut{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// in case there's a linked TCP connection, timeout is handled in the connection
|
// in case there's a linked TCP connection, timeout is handled in the connection
|
||||||
@@ -249,7 +249,7 @@ outer:
|
|||||||
default:
|
default:
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
if now.Sub(ss.lastRequestTime) >= serverSessionCloseAfterNoRequestsFor {
|
if now.Sub(ss.lastRequestTime) >= serverSessionCloseAfterNoRequestsFor {
|
||||||
break outer
|
return liberrors.ErrServerSessionTimedOut{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,9 +265,10 @@ outer:
|
|||||||
}
|
}
|
||||||
|
|
||||||
case <-ss.terminate:
|
case <-ss.terminate:
|
||||||
break outer
|
return liberrors.ErrServerTerminated{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
for req := range ss.request {
|
for req := range ss.request {
|
||||||
@@ -298,7 +299,7 @@ outer:
|
|||||||
close(ss.request)
|
close(ss.request)
|
||||||
|
|
||||||
if h, ok := ss.s.Handler.(ServerHandlerOnSessionClose); ok {
|
if h, ok := ss.s.Handler.(ServerHandlerOnSessionClose); ok {
|
||||||
h.OnSessionClose(ss)
|
h.OnSessionClose(ss, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -758,7 +759,7 @@ func (ss *ServerSession) handleRequest(sc *ServerConn, req *base.Request) (*base
|
|||||||
|
|
||||||
return &base.Response{
|
return &base.Response{
|
||||||
StatusCode: base.StatusOK,
|
StatusCode: base.StatusOK,
|
||||||
}, liberrors.ErrServerTeardown{}
|
}, liberrors.ErrServerSessionTeardown{}
|
||||||
|
|
||||||
case base.GetParameter:
|
case base.GetParameter:
|
||||||
if h, ok := sc.s.Handler.(ServerHandlerOnGetParameter); ok {
|
if h, ok := sc.s.Handler.(ServerHandlerOnGetParameter); ok {
|
||||||
|
Reference in New Issue
Block a user