gortsplib icon indicating copy to clipboard operation
gortsplib copied to clipboard

Add a field to ServerSession where user defined object can be stored

Open nu774 opened this issue 3 years ago • 2 comments

When users want to keep track of per-session state for the application, users have to maintain per-session map and do mutex lock/map lookup on any subsequent callbacks including OnFrame(), which is expensive. Why don't you just add a field to ServerSession where users can store any user-defined per-session object?

nu774 avatar Jun 15 '21 03:06 nu774

I believe that this issue has a broader scope and it also applies to other entities as well. For example, I don't believe that currently there is a way to provide user defined context.Context to the following entities:

  • gortsplib.Server (ctx is assigned here),
  • gortsplib.ServerConn (ctx is assigned here),
  • gortsplib.ServerSession (ctx is assigned here).

So it looks like the original context is created in (s *Server) Start() and it is wrapped with context.WithCancel() in newServerConn and newServerSession later on. Anyway, it would be great to have a way of providing user defined context since it would improve usability and extensibility of gortsplib greatly.

iamdavidcz avatar Feb 25 '22 13:02 iamdavidcz

Hello @iamdavidcz, while it's true that context.Context allows to store user-defined values, it is used primarily to terminate routines through context.Close() and context.Done(), i don't think it's good to mix two separate functionalities and i wish that the Go team had called that object differently.

The problem of adding a generic field (like an interface{} or a context.Context) to the structs you listed, is that it lacks type-checking. You would be forced to perform a type casting (i.e. userdata.(*MyStruct)). Type castings cause lot of errors, and nowadays most programming languages are switching to typed entities to mitigate this specific issue.

The feature you need can be implemented by creating a map that associates sessions to users, like:

sessions := make(map[*gortsplib.ServerSession]*MySessionStruct)

This can be used to retrieve MySessionStruct when a session callback is called:

func (s *rtspServer) OnPacketRTCP(ctx *gortsplib.ServerHandlerOnPacketRTCPCtx) {
	s.mutex.RLock()
	se := s.sessions[ctx.Session]
	s.mutex.RUnlock()
	se.onPacketRTCP(ctx)
}

This is the method used by rtsp-simple-server (check here) and avoids any type casting.

Nonetheless i agree that using a userData field is more efficient than using a map and must be taken into consideration.

aler9 avatar Mar 08 '22 18:03 aler9

SetUserData() and UserData() have been added to ServerSession. A type-checking based implementation would have required a significant change in the public API of the library, therefore i decided towards an approach that doesn't require any change in existing code.

aler9 avatar Nov 03 '22 11:11 aler9

This issue is being locked automatically because it has been closed for more than 6 months. Please open a new issue in case you encounter a similar problem.

github-actions[bot] avatar May 08 '23 15:05 github-actions[bot]