live555 RTSP服務器建立及消息處理流程
DynamicRTSPServer::creatnew():
1.調用繼承自RTPSever::setUpOurSocket:
1.調用 GroupsockHelper 的 setupStreamSocket創建一個socket連接,并綁定,
2.設置socket的發送緩存大小,
3.調用listen開始監聽端口,設置同時最大能處理連接數 LISTEN_BACKLOG_SIZE=20,如果達到這個上限則client端將收到ECONNERREFUSED的錯誤
4.測試綁定端口是否為0,為0的話重新綁定斷口,并返回系統自己選擇的新的端口。
5.返回建立的socket文件描述符
2.調用自己和RTPSever的構造函數:
RTPSever構造函數:
1.用一個UsageEnvironment對象的引用構造其父類Medium
2.設置最大等待回收連接時間 reclamationTestSeconds ,超過這個時間從客戶端沒有RTSP命令或者RTSP的RR包則收回其RTSPClientSession
3.建立一個HashTable[實際上是一個BasicHashTable], fServerMediaSessions指向這個表。
4.調用參數UsageEnvironment對象env的成員,一個TaskScheduler指針所指對象[實際就是一個BasicTaskScheduler 對象]的成員函數
turnOnBackgroundReadHandling():
1.調用一個HandlerSet::assignHandler()創建一個Handler,把socketNum[此處為服務器監聽的socket描述符]和處理函數RTSPServer::incomingConnectionHandler(),還有指向RTSPSever的指針綁定在一起。
incomingConnectionHandler作用:
1.調用accept返回服務器與客戶端連接的socket描述符
2.設置客戶端描述符為非阻塞
3.增加客戶端socket描述符的發送緩存為50*1024
4.為此客戶端隨機分配一個sessionId
5.用客戶端socket描述符clientSocket,sessionId,和客戶端地址clientAddr調用creatNewClientSession創建一個clientSession。
RTSPClientSession::RTSPClientSession()構造函數:
1.重置請求緩存
2.調用envir().taskScheduler().turnOnBackgroundReadHandling(),這次socket number 為客戶端socket描述符這次的處理函數是RTSPServer::RTSPClientSession::incomingRequestHandler()
RTSPServer::RTSPClientSession::incomingRequestHandler():
調用handleAlternativeRequestByte1(uint8_t requestByte):
1.fRequestBuffer[fRequestBytesAlreadySeen] = requestByte;把請求字符放入請求緩存fRequestBuffer
2.調用handleRequestBytes(1) 處理請求緩存
handleRequestBytes(int newBytesRead):
1.調用noteLiveness()查看請求是否到期,如果服務器的reclamationTestSeconds > 0,調用taskScheduler對象的rescheduleDelayedTask
函數: 參數為( fLivenessCheckTask, fOurServer.fReclamationTestSeconds*1000000, (TaskFunc*)livenessTimeoutTask, this )
其中livenessTimeoutTask()函數作用是刪除new出來的clientSession.
1.調用unscheduleDelayedTask(TaskToken& prevTask):
從DelayQueue中刪除prevTask項, prevTask置空.
2.調用scheduleDelayedTask(int64_t microseconds, TaskFunc* proc, void* clientData):
1.創建一個DelayInterval對象timeToDelay,用microseconds初始化。
2.創建一個AlarmHandler對象,用proc, clientData, timeToDelay初始化
3.調用fDelayQueue.addEntry(),把這個AlarmHandler對象加入到延遲隊列中
4.返回AlarmHandler對象的token[long類型]的指針
2.如果請求的的長度超過請求緩存可讀長度fRequestBufferBytesLeft,結束這個連接。
3.找到請求消息的結尾:<CR><LF><CR><LF>。
4.如果找到消息結尾,調用RTSPServer::RTSPClientSession::handleRequestBytes()[值得關注此函數]把請求字符串轉換成命令各部分包括:cmdName[方法],urlPreSuffix[url地址],urlSuffix[要讀取的文件名],sceq[消息的Cseq],否則函數返回需要繼續從連接中讀取請求。分別存入對 應的數組。
5.如果轉換成功,調用handleCmd_xxx()處理對應的cmdName: xxx [此處實現了:OPTIONS,DESCRIBE,SETUP,TEARDOWN,PLAY,PAUSE,GET_PARAMETER,SET_PARAMETER]
其中PLAY,PAUSE,GET_PARAMETER,SET_PARAMETER 調用handleCmd_withinSession(cmdName,urlPreSuffix, urlSuffix, cseq,(char const*)fRequestBuffer);
6.清空 RequestBuffer.
RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成