Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unexpected & random stream closures using the read() function. #24

Open
vuoz opened this issue Jan 18, 2025 · 2 comments
Open

Unexpected & random stream closures using the read() function. #24

vuoz opened this issue Jan 18, 2025 · 2 comments

Comments

@vuoz
Copy link

vuoz commented Jan 18, 2025

Using the read function provided by the framer, I get frequent stream closures, even though the server has not sent a close signal. This happens so frequently that it might even occur 3–4 times in a row.

My usage

// helper to construct the options
pub fn create_tcp_conn_and_client(
    addr: &str,
) -> anyhow::Result<(TcpStream, WebSocketOptions, WebSocketClient<ThreadRng>)> {
    let stream = TcpStream::connect(addr)?;
    let client = WebSocketClient::new_client(rand::thread_rng());
    let websocket_options = WebSocketOptions {
        path: "/subscribe",
        host: "",
        origin: "",
        sub_protocols: None,
        additional_headers: None,
    };
    return Ok((stream, websocket_options, client));
}

//main usage
fn main(){
        let mut read_cursor = 0;
        let mut write_buf = [0; 500];
        let mut read_buf = [0; 500];
        let mut frame_buf = [0; 1000];


        let (mut stream, options, mut client) = create_tcp_conn_and_client(server_addr)?;
        let mut framer = Framer::new(&mut read_buf, &mut read_cursor, &mut write_buf, &mut client);

        match framer.connect(&mut stream, &options) {
            Ok(_) => (),
            Err(e) => {
                log::info!("Error: {}", e);
                continue;
            }
        };
       let mut frame_buf = [0,2000];
       loop {
            match framer.read(&mut stream, &mut frame_buf) {
                Ok(v) => match v {
                    ReadResult::Text(t) => {..},
                    ReadResult::Binary(v)=>{..},
                    ReadResult::Closed => {..},
                    _ => {}
                },
                Err(e) => {
                    log::info!("Error reading ws socket:{:?}", e);
                }
            }
        }
}

In particular, these errors started to occur once I began receiving binary data encoded with protobuf (I don't really think this detail matters, though).
I am 100% certain that the server side never sends a close signal or drops the connection unexpectedly.
I have tried tungstenite and had no random disconnects, which goes to show that the server does not send any random close signals that could be the cause.

I have looked through the source code and found that the unexpected closures, in my particular case, ONLY occurred once the read_len field of the framer struct became 0 (in the read() function of the framer).
This part of the read function:

pub fn read<'b, E>(
    &mut self,
     stream: &mut impl Stream<E>,
     frame_buf: &'b mut [u8],
) -> Result<ReadResult<'b>, FramerError<E>> {
       /*{..}*/
       if self.read_len == 0 {
            return Ok(ReadResult::Closed);
       }
       /*{..}*/
   }

Is there something I am doing wrong ? As mentioned previously I am sure that there should not be any unexpected close signals from the server. As of now the implementation is very unreliable.

I am not quite sure if this is a usage error on my side or if there is an issue in the implementation.
If you need any additional information, I would be very happy to provide anything necessary.
If needed, I can also try creating a small, minimal, reproducible example.

@kskalski
Copy link
Contributor

I would make sure that you are not receiving Ping messages that you are ignoring (you have _ => {} branch, so at least log / err there)

@vuoz
Copy link
Author

vuoz commented Jan 22, 2025

I would make sure that you are not receiving Ping messages that you are ignoring (you have _ => {} branch, so at least log / err there)

Hi, thank you for your hint. Unfortunately I was not able to fix the issue with this change.
If you want to see my full usage its over here.
Covering all variants was not sufficient to fix the random & unexpected closure issues.
The implementation with tungstenite is on the main branch.
Is there anything else I can try ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants