snapview / tokio-tungstenite

Future-based Tungstenite for Tokio. Lightweight stream-based WebSocket implementation
MIT License
1.88k stars 236 forks source link

Websocket stops receiving messages unexpectedly #343

Closed Lazauya closed 3 months ago

Lazauya commented 3 months ago

OK, maybe someone here can help me. I've been trying to get tokio-tungstenite to work, but it randomly stops receiving messages (even though the messages appear to send successfully(?)). I made a small reproducable example here.

It sort of randomly drops out after a few seconds. Here's an excerpt of the end of the logs:

...<beginning omitted>
Requesting 100000
95904 remaining, just received 4096
91808 remaining, just received 4096
87712 remaining, just received 4096
83616 remaining, just received 4096
79520 remaining, just received 4096
75424 remaining, just received 4096
71328 remaining, just received 4096
67232 remaining, just received 4096
63136 remaining, just received 4096
59040 remaining, just received 4096
54944 remaining, just received 4096
50848 remaining, just received 4096
46752 remaining, just received 4096
42656 remaining, just received 4096
38560 remaining, just received 4096
34464 remaining, just received 4096
30368 remaining, just received 4096
26272 remaining, just received 4096
22176 remaining, just received 4096
18080 remaining, just received 4096
13984 remaining, just received 4096
9888 remaining, just received 4096
5792 remaining, just received 4096
1696 remaining, just received 4096
0 remaining, just received 1696
Received everything
Requesting 100000
95904 remaining, just received 4096
91808 remaining, just received 4096
87712 remaining, just received 4096
83616 remaining, just received 4096
79520 remaining, just received 4096
75424 remaining, just received 4096
71328 remaining, just received 4096
67232 remaining, just received 4096
63136 remaining, just received 4096
59040 remaining, just received 4096
54944 remaining, just received 4096
50848 remaining, just received 4096
46752 remaining, just received 4096
42656 remaining, just received 4096
38560 remaining, just received 4096
34464 remaining, just received 4096
30368 remaining, just received 4096
26272 remaining, just received 4096
22176 remaining, just received 4096
<end of logs>

As you can see it just drops out randomly. The server claims that it has sent the messages but the client never receives them.

agalakhov commented 3 months ago

Sorry, the link you've posted returns 404 for me.

Anyway, the most frequent cause of such a problem is the lack of reading. WebSocket only work properly if the code is ready to receive a message at any time. It isn't just Tungstenite requirement, it comes from WebSocket RFC. If the code receives not all the time, usually because it doesn't receive while sending or while doing something else, the WebSocket protocol will be violated and the behavior will be quite unpredictable. Be sure the receive code is running all the time. The easiest way to do so is to use a dedicated Tokio task for receiving.

Lazauya commented 3 months ago

Sorry, the link you've posted returns 404 for me.

Anyway, the most frequent cause of such a problem is the lack of reading. WebSocket only work properly if the code is ready to receive a message at any time. It isn't just Tungstenite requirement, it comes from WebSocket RFC. If the code receives not all the time, usually because it doesn't receive while sending or while doing something else, the WebSocket protocol will be violated and the behavior will be quite unpredictable. Be sure the receive code is running all the time. The easiest way to do so is to use a dedicated Tokio task for receiving.

I fixed the repo, it got set to private when I transferred ownership 😠. Anyway, as far as I know, I am ready to read at any time. Here's the message sender/receiver that runs in a separate thread (visible in src/client/client.rs):

|_ctx| async move {
    let (mut socket, other) = connect_async("ws://127.0.0.1:9002").await.unwrap();
    let (mut write, mut read) = socket.split();
    loop {
        let mut iter = req_rec.try_iter();

        if let Some(message) = iter.next() {
            write
                .send(Binary(to_stdvec(&message).unwrap()))
                .await
                .expect("TODO: panic message");
        }

        match poll!(read.next()) {
            Poll::Ready(Some(Ok(Binary(bin)))) => {
                match from_bytes::<NetworkResponse>(&bin).unwrap() {
                    Numbers(fetched) => {
                        terrain_resp_sen
                            .send(fetched)
                            .expect("Could not send terrain update");
                    }
                }
            }
            Poll::Ready(_) => {
                println!("Unk ready");
            }
            _ => {}
        }
    }
}
Lazauya commented 3 months ago

Sorry, the link you've posted returns 404 for me.

ARGH!!!! I updated it last night but I checked and it still was 404'ing. Hopefully NOW it's publicly visible. That is so frustrating.