【live555】RTSPServer中ClientSession创建与析构

【创建】

服务端与客户端建立一个连接,就会生成一个ClientConnection。
ClientConnection在处理SETUP Command时,会生成与自身对应的ClientSession(createNewClientSessionWithId)。

void RTSPServer::RTSPClientConnection::handleRequestBytes(int newBytesRead) {
  int numBytesRemaining = 0;
  ++fRecursionCount;
  
  do {
    RTSPServer::RTSPClientSession* clientSession = NULL;
	...
} else if (strcmp(cmdName, "SETUP") == 0) {
        Boolean areAuthenticated = True;

        if (!requestIncludedSessionId) {
          // No session id was present in the request.
          // So create a new "RTSPClientSession" object for this request.

          // But first, make sure that we're authenticated to perform this command:
          char urlTotalSuffix[2*RTSP_PARAM_STRING_MAX];
              // enough space for urlPreSuffix/urlSuffix'\0'
          urlTotalSuffix[0] = '\0';
          if (urlPreSuffix[0] != '\0') {
            strcat(urlTotalSuffix, urlPreSuffix);
            strcat(urlTotalSuffix, "/");
          }
          strcat(urlTotalSuffix, urlSuffix);
          if (authenticationOK("SETUP", urlTotalSuffix, (char const*)fRequestBuffer)) {
            clientSession
              = (RTSPServer::RTSPClientSession*)fOurRTSPServer.createNewClientSessionWithId();
          } else {
            areAuthenticated = False;
          }
        }
        if (clientSession != NULL) {
          clientSession->handleCmd_SETUP(this, urlPreSuffix, urlSuffix, (char const*)fRequestBuffer);
          playAfterSetup = clientSession->fStreamAfterSETUP;

在ClientSession::handleCmd_SETUP中将ClientConnectioin与ClientSession通过noteTcpStreamingOnSocket进行了关联。

void RTSPServer::RTSPClientSession
::handleCmd_SETUP(RTSPServer::RTSPClientConnection* ourClientConnection,
          char const* urlPreSuffix, char const* urlSuffix, char const* fullRequestStr) {
...
    // Then, get server parameters from the 'subsession':
    if (streamingMode == RTP_TCP) {
      // Note that we'll be streaming over the RTSP TCP connection:
      fStreamStates[trackNum].tcpSocketNum = ourClientConnection->fClientOutputSocket;
      fOurRTSPServer.noteTCPStreamingOnSocket(fStreamStates[trackNum].tcpSocketNum, this, trackNum);
    }


建立关系通过stremingOverTcpRecord的结构

void RTSPServer
::noteTCPStreamingOnSocket(int socketNum, RTSPClientSession* clientSession, unsigned trackNum) {
  streamingOverTCPRecord* sotcpCur
    = (streamingOverTCPRecord*)fTCPStreamingDatabase->Lookup((char const*)socketNum);
  streamingOverTCPRecord* sotcpNew
    = new streamingOverTCPRecord(clientSession->fOurSessionId, trackNum, sotcpCur);
  fTCPStreamingDatabase->Add((char const*)socketNum, sotcpNew);
}

【析构】

1、从RTSPClientConnection析构看起,断开连接就应该将Connection进行删除

RTSPServer::RTSPClientConnection::~RTSPClientConnection() {
  if (fOurSessionCookie != NULL) {
    // We were being used for RTSP-over-HTTP tunneling. Also remove ourselves from the 'session cookie' hash table before we go:
    fOurRTSPServer.fClientConnectionsForHTTPTunneling->Remove(fOurSessionCookie);
    delete[] fOurSessionCookie;
  }
  
  closeSocketsRTSP();
}

2、接下来看closeSocketsRTSP

void RTSPServer::RTSPClientConnection::closeSocketsRTSP() {
  // First, tell our server to stop any streaming that it might be doing over our output socket:
  fOurRTSPServer.stopTCPStreamingOnSocket(fClientOutputSocket);

  // Turn off background handling on our input socket (and output socket, if different); then close it (or them):
  if (fClientOutputSocket != fClientInputSocket) {
    envir().taskScheduler().disableBackgroundHandling(fClientOutputSocket);
    ::closeSocket(fClientOutputSocket);
  }
  fClientOutputSocket = -1;
  
  closeSockets(); // closes fClientInputSocket
}

3、看stopTCPStreamingOnSocket

void RTSPServer::stopTCPStreamingOnSocket(int socketNum) {
  // Close any stream that is streaming over "socketNum" (using RTP/RTCP-over-TCP streaming):
  streamingOverTCPRecord* sotcp
    = (streamingOverTCPRecord*)fTCPStreamingDatabase->Lookup((char const*)socketNum);
  if (sotcp != NULL) {
    do {
      RTSPClientSession* clientSession
    = (RTSPServer::RTSPClientSession*)lookupClientSession(sotcp->fSessionId);
      if (clientSession != NULL) {
    clientSession->deleteStreamByTrack(sotcp->fTrackNum);
      }

      streamingOverTCPRecord* sotcpNext = sotcp->fNext;
      sotcp->fNext = NULL;
      delete sotcp;
      sotcp = sotcpNext;
    } while (sotcp != NULL);
    fTCPStreamingDatabase->Remove((char const*)socketNum);
  }
}

4、看deleteStreamByTrack

void RTSPServer::RTSPClientSession::deleteStreamByTrack(unsigned trackNum) {
  if (trackNum >= fNumStreamStates) return; // sanity check; shouldn't happen
  if (fStreamStates[trackNum].subsession != NULL) {
    fStreamStates[trackNum].subsession->deleteStream(fOurSessionId, fStreamStates[trackNum].streamToken);
    fStreamStates[trackNum].subsession = NULL;
  }
  
  // Optimization: If all subsessions have now been deleted, then we can delete ourself now:
  Boolean noSubsessionsRemain = True;
  for (unsigned i = 0; i < fNumStreamStates; ++i) {
    if (fStreamStates[i].subsession != NULL) {
      noSubsessionsRemain = False;
      break;
    }
  }
  if (noSubsessionsRemain) delete this;
}

最后一行的delete this将ClientSession进行了析构

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值