[Live-devel] Updated RTSP server implementation to support multiple TCP connections per session - new experimental release

Lionel Orry lionel.orry at em-sys.fr
Fri Jul 27 06:36:16 PDT 2012


Hi Ross,

thank you for your replies. My comment below.

Regards,
Lionel

On Fri, 2012-07-27 at 06:04 -0700, Ross Finlayson wrote:
> Oops, my mistake:
> 
> 
> I just took another look at your message, and realized that - because
> you want to modify the response buffer while handling a "SETUP"
> command - you probably do, indeed, need to subclass
> "RTSPServer::RTSPClientSession" as well (because "handleCmd_SETUP()"
> is a member function of "RTSPServer::RTSPClientSession").
> 

Yes that's what I was about to answer. :)

> 
> But you can probably solve your 'protected fResponseBuffer' problem
> quite easily, by defining - in your "RTSPServer::RTSPClientConnection"
> subclass - a function:
> unsigned char* responseBuffer() { return fResponseBuffer; }
> 

Not at all, the problem is the other way around. I'll try to give more
details.

If you check my code outlines again, you will notice that
'ourClientConnection' is of type RTSPServer::RTSPClientConnection (see
prototype of SETUP handler method). Any method called against
ourClientConnection is resolved on RTSPServer::RTSPClientConnection,
thus the responseBuffer() method would not help. I tried, it throws:

‘class RTSPServer::RTSPClientConnection’ has no member named
‘responseBuffer’


You may also suggest me to consider why I need to subclass
RTSPClientConnection, but the fact is I also need to override some of
its handlers (i.e. out-of-session handlers) for OPTIONS, GET_PARAMETERS,
for example. So I really need to subclass both RTSPClientSession and
RTSPClientConnection.

My first idea, to be honest, was to pass
(MyOwnRTSPServer::RTSPClientConnection*) as the type of the handler
first parameter, but when I do that it is not detected as an override of
the original handler, because prototypes differ. The original
implementation only was called.

To keep things clean, maybe I should implement wrappers, like this:

-------------------------------------------------------------
void MyOwnRTSPServer::RTSPClientSession::handleCmd_SETUP(
  RTSPServer::RTSPClientConnection* ourClientConnection,
  char const* urlPreSuffix, char const* urlSuffix,
  char const* fullRequestStr) {
  // dynamic_cast to get our own subclass type,
  // then call our implementation
  RTSPClientConnection* conn = dynamic_cast<RTSPClientConnection*>(
    ourClientConnection);
  handleMyCmd_SETUP(conn, urlPreSuffix, urlSuffix, fullRequestStr);
}

void MyOwnRTSPServer::RTSPClientSession::handleMyCmd_SETUP(
  RTSPClientConnection* conn,
  char const* urlPreSuffix, char const* urlSuffix,
  char const* fullRequestStr) {
  // specific stuff with my instance
  // call original implementation
  RTSPServer::RTSPClientSession::handleCmd_SETUP(conn, urlPreSuffix,
urlSuffix, fullRequestStr);

  // Here, I can access conn->fResponseBuffer because
  // MyOwnRTSPServer::RTSPClientSession is a friend class of
  // MyOwnRTSPServer::RTSPClientConnection.
}
-------------------------------------------------------------

The ideal solution I think would be to make
MyOwnRTSPServer::RTSPClientSession a friend call of
RTSPServer::RTSPClientConnection but that means modifying the original
headers, which I obviously don't want to do to keep away from license
issues, and that would also mean make RTSPServer aware of my own class
which is not desirable either.

> 
> And then - in your "RTSPServer::RTSPClientSession" subclass - doing a
> "strstr()" to "ourClientConnection->responseBuffer()", rather than to
> "conn->fResponseBuffer".
> 
> 
> Ross Finlayson
> Live Networks, Inc.
> http://www.live555.com/
> 
> _______________________________________________
> live-devel mailing list
> live-devel at lists.live555.com
> http://lists.live555.com/mailman/listinfo/live-devel




More information about the live-devel mailing list