Skip to content

resource leak maybe exist in websocket #3359

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

Open
zylthinking opened this issue May 24, 2025 · 0 comments
Open

resource leak maybe exist in websocket #3359

zylthinking opened this issue May 24, 2025 · 0 comments

Comments

@zylthinking
Copy link

zylthinking commented May 24, 2025

I found that: after I drop the websocket (I even close it manully to make sure), the system socket may still exist with state ESTABLISHED;

I have logs to ensure the socket has been closed at application level. Like below:

async fn handle_socket(mut socket: WebSocket, pool: pool::Pool) {
    use tokio::time::{self, *};

    let mut link = links::Link::new();
    let nr = links::ONLINE.fetch_add(1, Ordering::Relaxed);
    info!("connection +1, total: {}", nr + 1);

    let mut n1 = 0;
    let mut n2 = 0;
    let mut intv = time::interval_at(Instant::now(), Duration::from_secs(10));
    loop {
        tokio::select! {
            r = socket.recv() => {
                let Some(msg) = r else {
                    info!("connecion will break because of: {r:?}");
                    _ = socket.close().await.map_err(|e| error!("socket close failed {e}"));
                    break
                };
                n2 = 0;

                match msg {
                    Ok(Message::Ping(data)) => {
                        _ = socket.send(Message::Pong(data)).await;
                    }
                    Ok(Message::Binary(bin)) => {
                        if let Some(resp) = link.handle_pb_req(&pool, bin).await {
                            _ = socket.send(Message::Binary(resp.m2b())).await;
                        }
                    }
                    _ => {}
                }
            }

            bin = &mut link => {
                _ = socket.send(Message::Binary(bin)).await;
            }

            _ = intv.tick() => {
                link.tick(n1).await;
                n1 += 1;
                n2 += 1;
                if n2 == 6 {
                    warn!("connection will break because of heart beat");
                    _ = socket.close().await.map_err(|e|
                        error!("socket close failed {e}")
                    );
                    break;
                }
            }
        }
    }
    link.tick(-1).await;

    let nr = links::ONLINE.fetch_sub(1, Ordering::Relaxed);
    info!("connection -1, total: {}", nr - 1);
}

After the logs says no connection left, netstat still shows there are established connections.

I also noticed there are 2 system socket for one websocket, is this necessary?

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

1 participant