Skip to content

resource leak maybe exist in websocket #3359

Open
@zylthinking

Description

@zylthinking

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions