harlanc / xiu

A simple,high performance and secure live media server in pure Rust (RTMP[cluster]/RTSP/WebRTC[whip/whep]/HTTP-FLV/HLS).🦀
https://www.rustxiu.com
MIT License
1.6k stars 168 forks source link

read a complete frame every time when use rtspovertcp #126

Open bailb opened 2 months ago

bailb commented 2 months ago

under rtspovertcp mode. the length of frame is after the '$', and the content is after that. but the previous logic after decoding the length field just read from socket only once, so it's very frequency to occur that the length we decoded not match the real length we read.

harlanc commented 1 month ago

@bailb Thanks for your contributions, judging from the current logic, if the length is still not satisfied after an additional read of data, the entire RtspServerSession process will exit. Have you ever encountered this situation?

If that is the case, can this problem be solved by replacing if with while?

 pub async fn run(&mut self) -> Result<(), SessionError> {
     loop {
         while self.reader.len() < 4 {
             let data = self.io.lock().await.read().await?;
             self.reader.extend_from_slice(&data[..]);
         }

         if let Ok(data) = InterleavedBinaryData::new(&mut self.reader) {
             match data {
                 Some(a) => {
                     if self.reader.len() < a.length as usize { // replace if with while
                         let data = self.io.lock().await.read().await?;
                         self.reader.extend_from_slice(&data[..]);
                     }
                     self.on_rtp_over_rtsp_message(a.channel_identifier, a.length as usize)
                         .await?;
                 }
                 None => {
                     self.on_rtsp_message().await?;
                 }
             }
         }
     }
 }
bailb commented 1 month ago

@bailb Thanks for your contributions, judging from the current logic, if the length is still not satisfied after an additional read of data, the entire RtspServerSession process will exit. Have you ever encountered this situation?

If that is the case, can this problem be solved by replacing if with while?

 pub async fn run(&mut self) -> Result<(), SessionError> {
     loop {
         while self.reader.len() < 4 {
             let data = self.io.lock().await.read().await?;
             self.reader.extend_from_slice(&data[..]);
         }

         if let Ok(data) = InterleavedBinaryData::new(&mut self.reader) {
             match data {
                 Some(a) => {
                     if self.reader.len() < a.length as usize { // replace if with while
                         let data = self.io.lock().await.read().await?;
                         self.reader.extend_from_slice(&data[..]);
                     }
                     self.on_rtp_over_rtsp_message(a.channel_identifier, a.length as usize)
                         .await?;
                 }
                 None => {
                     self.on_rtsp_message().await?;
                 }
             }
         }
     }
 }

yes, I really encountered this error. and I solved the problem with a loop before. just think it's better use a function with timeout.

harlanc commented 1 month ago

@bailb Thanks for your contributions, judging from the current logic, if the length is still not satisfied after an additional read of data, the entire RtspServerSession process will exit. Have you ever encountered this situation? If that is the case, can this problem be solved by replacing if with while?

 pub async fn run(&mut self) -> Result<(), SessionError> {
     loop {
         while self.reader.len() < 4 {
             let data = self.io.lock().await.read().await?;
             self.reader.extend_from_slice(&data[..]);
         }

         if let Ok(data) = InterleavedBinaryData::new(&mut self.reader) {
             match data {
                 Some(a) => {
                     if self.reader.len() < a.length as usize { // replace if with while
                         let data = self.io.lock().await.read().await?;
                         self.reader.extend_from_slice(&data[..]);
                     }
                     self.on_rtp_over_rtsp_message(a.channel_identifier, a.length as usize)
                         .await?;
                 }
                 None => {
                     self.on_rtsp_message().await?;
                 }
             }
         }
     }
 }

yes, I really encountered this error. and I solved the problem with a loop before. just think it's better use a function with timeout.

From your perspective, why it is better to use timeout?