live555MediaServer has a hard-coded 45-second timeout in it for
detecting clients that go away without telling the server. The timer
gets reset when a client sends another RTSP command, which a conforming
client does periodically to convince the server that it is still alive.
RFC 2326 (RTSP) says the default timeout should be 60 seconds. (Section
12.37) My patch doesn't change this, but you should consider doing so.
It's line 44 in mediaServer/DynamicRTSPServer.cpp.
That section of the RFC also says that if the server wants a different
timeout, it should tell the client what value it uses in response to the
client's SETUP command, so it will know to change how often it sends its
keepalive packets. The attached patch does this.
live555MediaServer passes this hard-coded timeout value to its
RTSPServer instance, which stores it in a member variable called
fReclamationTestSeconds. The patch adds a constructor parameter to
RTSPServer::RTSPClientSession to accept a similar value, stored in a
member variable called fSessionTimeout. (I chose the different name
because its meaning changes somewhat in this object.) The session
object adds this value to the Session: headers in response to SETUP
commands from the client, per the RFC.
The patch doesn't handle the case where PLAY and SETUP are combined. I
decided not to mess with this for a few reasons. First, I don't have
such a client. Second, it's nonstandard behavior, but I presume at
least one client that does this has been tested against the server, and
it works now, so I guess it doesn't need to be told the timeout.
diff -ruN 2008.07.25/liveMedia/include/RTSPServer.hh local/liveMedia/include/RTSPServer.hh
--- 2008.07.25/liveMedia/include/RTSPServer.hh 2008-07-24 18:40:05.000000000 -0600
+++ local/liveMedia/include/RTSPServer.hh 2008-08-19 22:23:42.000000000 -0600
@@ -117,7 +117,8 @@
class RTSPClientSession {
public:
RTSPClientSession(RTSPServer& ourServer, unsigned sessionId,
- int clientSocket, struct sockaddr_in clientAddr);
+ int clientSocket, struct sockaddr_in clientAddr,
+ unsigned sessionTimeout);
virtual ~RTSPClientSession();
private:
UsageEnvironment& envir() { return fOurServer.envir(); }
@@ -173,6 +174,7 @@
ServerMediaSubsession* subsession;
void* streamToken;
} * fStreamStates;
+ unsigned fSessionTimeout;
};
private:
diff -ruN 2008.07.25/liveMedia/RTSPServer.cpp local/liveMedia/RTSPServer.cpp
--- 2008.07.25/liveMedia/RTSPServer.cpp 2008-07-24 18:40:05.000000000 -0600
+++ local/liveMedia/RTSPServer.cpp 2008-08-19 22:24:59.000000000 -0600
@@ -241,7 +241,7 @@
// Create a new object for this RTSP session:
new RTSPClientSession(*this, ++fSessionIdCounter,
- clientSocket, clientAddr);
+ clientSocket, clientAddr, fReclamationTestSeconds);
}
@@ -249,13 +249,15 @@
RTSPServer::RTSPClientSession
::RTSPClientSession(RTSPServer& ourServer, unsigned sessionId,
- int clientSocket, struct sockaddr_in clientAddr)
+ int clientSocket, struct sockaddr_in clientAddr,
+ unsigned sessionTimeout)
: fOurServer(ourServer), fOurSessionId(sessionId),
fOurServerMediaSession(NULL),
fClientSocket(clientSocket), fClientAddr(clientAddr),
fLivenessCheckTask(NULL),
fIsMulticast(False), fSessionIsActive(True), fStreamAfterSETUP(False),
- fTCPStreamIdCount(0), fNumStreamStates(0), fStreamStates(NULL) {
+ fTCPStreamIdCount(0), fNumStreamStates(0), fStreamStates(NULL),
+ fSessionTimeout(sessionTimeout) {
// Arrange to handle incoming requests:
resetRequestBuffer();
envir().taskScheduler().turnOnBackgroundReadHandling(fClientSocket,
@@ -744,11 +746,12 @@
"CSeq: %s\r\n"
"%s"
"Transport: RTP/AVP;multicast;destination=%s;source=%s;port=%d-%d;ttl=%d\r\n"
- "Session: %d\r\n\r\n",
+ "Session: %d;timeout=%u\r\n\r\n",
cseq,
dateHeader(),
destAddrStr, sourceAddrStr, ntohs(serverRTPPort.num()), ntohs(serverRTCPPort.num()), destinationTTL,
- fOurSessionId);
+ fOurSessionId,
+ fSessionTimeout);
break;
case RTP_TCP:
// multicast streams can't be sent via TCP
@@ -760,11 +763,12 @@
"CSeq: %s\r\n"
"%s"
"Transport: %s;multicast;destination=%s;source=%s;port=%d;ttl=%d\r\n"
- "Session: %d\r\n\r\n",
+ "Session: %d;timeout=%u\r\n\r\n",
cseq,
dateHeader(),
streamingModeString, destAddrStr, sourceAddrStr, ntohs(serverRTPPort.num()), destinationTTL,
- fOurSessionId);
+ fOurSessionId,
+ fSessionTimeout);
break;
}
} else {
@@ -775,11 +779,12 @@
"CSeq: %s\r\n"
"%s"
"Transport: RTP/AVP;unicast;destination=%s;source=%s;client_port=%d-%d;server_port=%d-%d\r\n"
- "Session: %d\r\n\r\n",
+ "Session: %d;timeout=%u\r\n\r\n",
cseq,
dateHeader(),
destAddrStr, sourceAddrStr, ntohs(clientRTPPort.num()), ntohs(clientRTCPPort.num()), ntohs(serverRTPPort.num()), ntohs(serverRTCPPort.num()),
- fOurSessionId);
+ fOurSessionId,
+ fSessionTimeout);
break;
}
case RTP_TCP: {
@@ -788,11 +793,12 @@
"CSeq: %s\r\n"
"%s"
"Transport: RTP/AVP/TCP;unicast;destination=%s;source=%s;interleaved=%d-%d\r\n"
- "Session: %d\r\n\r\n",
+ "Session: %d;timeout=%u\r\n\r\n",
cseq,
dateHeader(),
destAddrStr, sourceAddrStr, rtpChannelId, rtcpChannelId,
- fOurSessionId);
+ fOurSessionId,
+ fSessionTimeout);
break;
}
case RAW_UDP: {
@@ -801,11 +807,12 @@
"CSeq: %s\r\n"
"%s"
"Transport: %s;unicast;destination=%s;source=%s;client_port=%d;server_port=%d\r\n"
- "Session: %d\r\n\r\n",
+ "Session: %d;timeout=%u\r\n\r\n",
cseq,
dateHeader(),
streamingModeString, destAddrStr, sourceAddrStr, ntohs(clientRTPPort.num()), ntohs(serverRTPPort.num()),
- fOurSessionId);
+ fOurSessionId,
+ fSessionTimeout);
break;
}
}
_______________________________________________
live-devel mailing list
[email protected]
http://lists.live555.com/mailman/listinfo/live-devel